瀏覽代碼

添加分页,上传提示列表排序等处理模块分类加载问题

yangg 10 月之前
父節點
當前提交
467b51417b

File diff suppressed because it is too large
+ 0 - 0
dist/index.html


+ 0 - 0
dist/static/css/chunk-08eaa8e2.e30e9787.css → dist/static/css/chunk-227fce26.e30e9787.css


+ 0 - 1
dist/static/css/chunk-36721b8a.b27c668a.css

@@ -1 +0,0 @@
-.project-search{padding:30px;font-size:12px}

+ 0 - 1
dist/static/css/chunk-78f219c8.7131743c.css

@@ -1 +0,0 @@
-.data-search{padding:20px 10px 0 10px}.data-list .btns,.data-list .page-info{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row}.data-list .page-info{margin-top:10px}.data-list .page-info .opt{width:50%;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row;-webkit-box-pack:start;-ms-flex-pack:start;justify-content:flex-start;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.data-list .page-info .opt .pick{width:100px}.data-list .page-info .opt .section{margin-left:10px}.data-list .page-info .page-data{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between;-webkit-box-align:center;-ms-flex-align:center;align-items:center;width:100%}.data-list .page-info .page-data .page-item{width:100%}.data-list .page-info .page-data .page-opt{width:100%;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:end;-ms-flex-pack:end;justify-content:flex-end}.project-search{padding:30px;font-size:12px}

File diff suppressed because it is too large
+ 0 - 0
dist/static/css/chunk-96aac5cc.e3c3364c.css


+ 1 - 0
dist/static/css/chunk-bf1dc724.8d28e945.css

@@ -0,0 +1 @@
+.data-search{padding:20px 10px 0 10px}.custom-upload .el-upload,.custom-upload .el-upload .el-upload-dragger{width:100%}.data-list .btns,.data-list .page-info{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row}.data-list .page-info{margin-top:10px}.data-list .page-info .opt{width:50%;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row;-webkit-box-pack:start;-ms-flex-pack:start;justify-content:flex-start;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.data-list .page-info .opt .pick{width:100px}.data-list .page-info .opt .section{margin-left:10px}.data-list .page-info .page-data{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between;-webkit-box-align:center;-ms-flex-align:center;align-items:center;width:100%}.data-list .page-info .page-data .page-item{width:100%}.data-list .page-info .page-data .page-opt{width:100%;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:end;-ms-flex-pack:end;justify-content:flex-end}.project-search{padding:30px;font-size:12px}

+ 1 - 0
dist/static/css/chunk-cd1f0158.162e8a99.css

@@ -0,0 +1 @@
+.project-search[data-v-0116246d]{display:-webkit-box;display:-ms-flexbox;display:flex;padding:10px;font-size:12px}

+ 0 - 0
dist/static/css/chunk-4487d514.6044f932.css → dist/static/css/chunk-db653464.e30e9787.css


File diff suppressed because it is too large
+ 0 - 0
dist/static/js/app.563fe5c4.js


File diff suppressed because it is too large
+ 0 - 0
dist/static/js/chunk-08eaa8e2.925a0455.js


File diff suppressed because it is too large
+ 0 - 0
dist/static/js/chunk-227fce26.2ecbc8e4.js


File diff suppressed because it is too large
+ 0 - 0
dist/static/js/chunk-36721b8a.284f6e13.js


File diff suppressed because it is too large
+ 0 - 0
dist/static/js/chunk-5de18842.e2a35709.js


File diff suppressed because it is too large
+ 0 - 0
dist/static/js/chunk-6fca2da6.6c43b6bc.js


File diff suppressed because it is too large
+ 0 - 0
dist/static/js/chunk-78f219c8.e4546ce5.js


File diff suppressed because it is too large
+ 0 - 0
dist/static/js/chunk-96aac5cc.ae0a98bd.js


File diff suppressed because it is too large
+ 0 - 0
dist/static/js/chunk-bf1dc724.b68d6fcd.js


File diff suppressed because it is too large
+ 0 - 0
dist/static/js/chunk-cd1f0158.78f25a6b.js


File diff suppressed because it is too large
+ 0 - 0
dist/static/js/chunk-db653464.e37e0185.js


+ 9 - 0
src/api/knowledge.js

@@ -91,4 +91,13 @@ export function searchTaskInfo(data) {
     method: 'post',
     data
   })
+}
+
+/* /kbm/batchAnalysis  批量解析 */
+export function batchAnalysis(data) {
+  return request({
+    url: '/kbm/batchAnalysis',
+    method: 'post',
+    data
+  })
 }

+ 86 - 26
src/views/document/create.vue

@@ -116,7 +116,7 @@
                 </el-collapse-item>
               </el-collapse>
             </div>
-            <div v-if="showView == 1">
+            <div v-if="showView == 1" class="scrollable-container">
               <!-- <el-collapse
                 v-model="activeModel"
                 :accordion="true"
@@ -243,6 +243,47 @@
                               :name="greatGrandChild.id"
                               class="min-width-content"
                             >
+                              <el-collapse
+                                v-if="
+                                  greatGrandChild.children &&
+                                  greatGrandChild.children.length
+                                "
+                                v-model="greatGrandChild.activeChildren"
+                                @change="handlegreatGrandChildItemVal"
+                                v-show="greatGrandChild.children"
+                                class="borderless-collapse"
+                              >
+                                <el-collapse-item
+                                  v-for="(
+                                    fiveChild, fiveIndex
+                                  ) in greatGrandChild.children"
+                                  :key="fiveIndex"
+                                  :title="fiveChild.name"
+                                  :name="fiveChild.id"
+                                  class="min-width-content"
+                                >
+                                  <draggable
+                                    v-model="fiveChild.dataList"
+                                    :options="{
+                                      group: { name: 'itxst', pull: 'clone' },
+                                      sort: true,
+                                    }"
+                                    :disabled="type == 'module'"
+                                  >
+                                    <transition-group>
+                                      <div
+                                        class="sub-menus min-width-content"
+                                        v-for="(
+                                          fiveIts, fiveIndex
+                                        ) in fiveChild.dataList"
+                                        :key="fiveIndex"
+                                      >
+                                        <div>{{ fiveIts.name }}</div>
+                                      </div>
+                                    </transition-group>
+                                  </draggable>
+                                </el-collapse-item>
+                              </el-collapse>
                               <draggable
                                 v-model="greatGrandChild.dataList"
                                 :options="{
@@ -669,15 +710,25 @@ export default {
     }
     this.isAdmin = this.userInfo ? this.userInfo.roleInfo.is_admin : 2;
     this.initArticleCategoryList();
-    if (this.type == "document" && this.articleId!==undefined) {
-      document.title = this.docAttr.title+"-轻良实业";
+    if (this.type == "document" && this.articleId !== undefined) {
+      document.title = this.docAttr.title + "-轻良实业";
     }
     if (this.type !== "module" && this.type !== "document") {
       document.title = "新建模版-轻良实业";
     }
-    if (this.type !== "module" && this.type !== "document" &&this.articleId!==undefined) {
-      document.title = this.docAttr.title+"-轻良实业";
+    if (
+      this.type !== "module" &&
+      this.type !== "document" &&
+      this.articleId !== undefined
+    ) {
+      document.title = this.docAttr.title + "-轻良实业";
     }
+    this.$nextTick(() => {
+      const arrows = document.querySelectorAll('.el-collapse-item__arrow');
+      arrows.forEach(arrow => {
+        arrow.style.margin = '0';
+      });
+    });
   },
 
   methods: {
@@ -700,17 +751,16 @@ export default {
       }
     },
     handleGrandChildItemVal(value) {
-      this.$forceUpdate();
       this.loadChildren(value);
+      this.$forceUpdate();
     },
-    handleGreatGrandChildItemClick(greatGrandChild) {
-      if (!greatGrandChild.children) {
-        this.loadChildren(greatGrandChild);
-      }
+    handlegreatGrandChildItemVal(greatGrandChild) {
+      this.loadChildren(greatGrandChild);
+      this.$forceUpdate();
     },
     async loadChildren(category) {
       const category_id = category[category.length - 1];
-      console.log(this.categoryList);
+
       try {
         const res = await searchTemplateCategory({ parent_id: category_id });
         if (res.status != 200 || res.data.length == 0) return;
@@ -721,6 +771,7 @@ export default {
           );
         }
         this.insertChildrenById(this.categoryList, category_id, newChildren);
+        console.log(this.categoryList);
         this.$forceUpdate(); // Force Vue to re-render the component
       } catch (error) {
         console.error("Error fetching template categories:", error);
@@ -1860,21 +1911,6 @@ export default {
 
 <style lang="scss">
 @import "./create.scss";
-/* .borderless-collapse {
-  border: none;
-  ::v-deep.el-collapse-item .el-collapse-item__header{
-    border-bottom: none;
-  }
-  ::v-deep .el-collapse-item__wrap {
-    border-bottom: none;
-  }
-  ::v-deep .el-collapse-item .el-collapse-item__header {
-    border-bottom: none;
-  }
-} */
-.min-width-content {
-  min-width: 150px; /* Set your desired minimum width here */
-}
 
 .el-collapse,
 .el-collapse-item__wrap {
@@ -1883,6 +1919,10 @@ export default {
 .el-collapse,
 .el-collapse-item__header {
   border: none;
+  .el-collapse-item__arrow{
+    margin: 0;
+  }
+
 }
 .borderless-collapse {
   border: none;
@@ -1891,9 +1931,29 @@ export default {
   ::v-deep .el-collapse-item__content,
   ::v-deep .el-collapse-item {
     border: none;
+    
   }
+
   ::v-deep .el-collapse-item__wrap {
     border-bottom: none !important;
   }
 }
+.scrollable-container {
+  overflow-x: auto;
+  white-space: nowrap;
+  width: 350px;
+  padding-bottom: 10px;
+}
+
+.min-width-content {
+  /*   display: inline-block;
+  vertical-align: top; */
+  min-width: 150px;
+  white-space: normal;
+}
+
+/*.el-collapse-item {
+  display: inline-block;
+  vertical-align: top;
+} */
 </style>

+ 208 - 45
src/views/knowledgeMenu/category/components/dataList.vue

@@ -1,26 +1,41 @@
 <template>
   <div class="data-list" v-loading="loading" element-loading-text="加载中...">
+    <div class="batch-actions" style="margin: 10px 0">
+      <el-button
+        type="primary"
+        @click="batchAnalysis"
+        :disabled="!selectedRows.length"
+        >批量解析</el-button
+      >
+    </div>
     <el-table
+      ref="dataTable"
       :data="dataList"
       style="width: 100%"
       header-row-class-name="headerBg"
       empty-text="没有模板信息"
+      @selection-change="handleSelectionChange"
+      @sort-change="handleSortChange"
     >
+      <el-table-column type="selection" width="55"></el-table-column>
       <el-table-column prop="id" label="ID" align="center" width="80" />
-      <el-table-column prop="name" label="文件名称" align="center">
+      <el-table-column
+        prop="name"
+        label="文件名称"
+        align="center"
+        sortable="custom"
+      >
         <template #default="scope">
-          <span @click="getName(scope.row)">{{ scope.row.name }}</span>
+          <span>{{ scope.row.name }}</span>
         </template>
       </el-table-column>
       <el-table-column prop="chunk_num" label="分块数" align="center" />
-      <el-table-column prop="create_time" label="上传时间" align="center" />
-      <!-- <el-table-column prop="" label="解析方法" align="center" /> -->
-      <el-table-column prop="createTime" label="启用" align="center"
-        ><template #default="scope">
-          <div v-if="scope.row.status == 5">启用</div>
-          <div v-if="scope.row.status == 6">停用</div>
-        </template></el-table-column
-      >
+      <el-table-column
+        prop="create_time"
+        label="上传时间"
+        align="center"
+        sortable="custom"
+      />
       <el-table-column prop="run" label="解析状态" align="center">
         <template #default="scope">
           <div v-if="scope.row.run == 0">未解析</div>
@@ -30,49 +45,112 @@
           <div v-if="scope.row.run == 5">待处理</div>
         </template>
       </el-table-column>
-      <el-table-column label="操作" align="center" width="500"
-        ><!-- editWidth() -->
+      <el-table-column label="操作" align="center" width="330">
         <template #default="scope">
           <div class="btns">
-            <el-button
-              type="primary"
-              size="small"
-              v-if="allowEdit"
-              @click="analysis(scope.row)"
-              :loading="scope.row.analyzing"
-              :disabled="scope.row.run === 1"
+            <el-tooltip
+              class="item"
+              effect="dark"
+              content="预览"
+              placement="top"
             >
-              {{ scope.row.run === 1 ? "解析中" : "解析" }}</el-button
+              <el-button
+                type="text"
+                size="small"
+                circle
+                icon="el-icon-view"
+                v-if="allowEdit"
+                style="font-size: 20px"
+                @click="getName(scope.row)"
+              ></el-button
+            ></el-tooltip>
+            <el-tooltip
+              class="item"
+              effect="dark"
+              :content="scope.row.run === 1 ? '解析中' : '解析'"
+              placement="top"
             >
-            <el-button
-              type="primary"
-              size="small"
-              v-if="allowEdit"
-              @click="Analytical(scope.row)"
-              >解析方法</el-button
+              <el-button
+                type="text"
+                :icon="
+                  scope.row.run === 1
+                    ? 'el-icon-loading'
+                    : 'el-icon-caret-right'
+                "
+                circle
+                v-if="allowEdit"
+                @click="analysis(scope.row)"
+                :loading="scope.row.analyzing"
+                :disabled="scope.row.run === 1"
+                style="font-size: 20px"
+              >
+              </el-button>
+            </el-tooltip>
+            <el-tooltip
+              class="item"
+              effect="dark"
+              content="解析方法"
+              placement="top"
             >
-            <el-button
-              type="primary"
-              size="small"
-              v-if="allowEdit"
-              @click="btnEdit(scope.row)"
-              ><svg-icon icon-class="edit" />修改文件名</el-button
+              <el-button
+                type="text"
+                size="small"
+                circle
+                icon="el-icon-tickets"
+                v-if="allowEdit"
+                style="font-size: 20px"
+                @click="Analytical(scope.row)"
+              ></el-button
+            ></el-tooltip>
+            <el-tooltip
+              class="item"
+              effect="dark"
+              content="修改文件名"
+              placement="top"
             >
-            <el-button
-              type="primary"
-              size="small"
-              v-if="allowEdit"
-              @click="btnDown(scope.row)"
-              :loading="scope.row.downloading"
-              ><svg-icon icon-class="edit" />下载</el-button
+              <el-button
+                type="text"
+                size="small"
+                circle
+                icon="el-icon-edit"
+                v-if="allowEdit"
+                style="font-size: 20px"
+                @click="btnEdit(scope.row)"
+              ></el-button
+            ></el-tooltip>
+            <el-tooltip
+              class="item"
+              effect="dark"
+              content="下载"
+              placement="top"
             >
-            <el-button
-              type="danger"
-              size="small"
-              v-if="allowDelete"
-              @click="btnDelete(scope.row.id)"
-              ><svg-icon icon-class="delete" />删除</el-button
+              <el-button
+                type="text"
+                size="small"
+                circle
+                icon="el-icon-download"
+                v-if="allowEdit"
+                @click="btnDown(scope.row)"
+                :loading="scope.row.downloading"
+                style="font-size: 20px"
+              ></el-button
+            ></el-tooltip>
+            <el-tooltip
+              class="item"
+              effect="dark"
+              content="删除"
+              placement="top"
             >
+              <el-button
+                type="text"
+                size="small"
+                circle
+                icon="el-icon-delete"
+                v-if="allowDelete"
+                @click="btnDelete(scope.row.id)"
+                style="font-size: 20px"
+              ></el-button
+            ></el-tooltip>
           </div>
         </template>
       </el-table-column>
@@ -158,6 +236,7 @@ import {
   nameGetUrl,
   renameFile,
   analysis,
+  batchAnalysis,
 } from "@/api/knowledge";
 export default {
   props: {
@@ -229,12 +308,95 @@ export default {
         token_num: 0,
       },
       analRules: {},
+      selectedRows: [],
+      sortColumn: "",
+      sortOrder: "",
     };
   },
   mounted() {
     this.search();
   },
   methods: {
+    /* 排序 */
+    handleSortChange({ prop, order }) {
+      this.sortColumn = prop;
+      this.sortOrder = order;
+      this.sortData();
+    },
+
+    sortData() {
+      const { sortColumn, sortOrder } = this;
+      if (!sortColumn || !sortOrder) {
+        this.search(); // Reset to original order
+        return;
+      }
+
+      this.dataList.sort((a, b) => {
+        let comparison = 0;
+        if (sortColumn === "name") {
+          comparison = a.name.localeCompare(b.name, "zh-CN");
+        } else if (sortColumn === "create_time") {
+          comparison = new Date(a.create_time) - new Date(b.create_time);
+        }
+        return sortOrder === "ascending" ? comparison : -comparison;
+      });
+    },
+    /* 批量解析 */
+    handleSelectionChange(val) {
+      this.selectedRows = val;
+    },
+
+    batchAnalysis() {
+      const selectedIds = this.selectedRows.map((row) => row.id);
+      if (selectedIds.length === 0) {
+        this.$message.warning("请选择要解析的文件");
+        return;
+      }
+
+      this.$confirm("确定要批量解析选中的文件吗?", "提示", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning",
+      })
+        .then(() => {
+          this.loading = true;
+          batchAnalysis({ ids: JSON.stringify(selectedIds) })
+            .then((res) => {
+              if (res.status === 200) {
+                this.$message.success("批量解析任务已提交");
+                this.updateAnalysisStatus(selectedIds);
+                this.clearSelection();
+              } else {
+                this.$message.error("批量解析请求失败");
+              }
+            })
+            .catch((error) => {
+              console.error("批量解析错误:", error);
+              this.$message.error("批量解析过程中出现错误");
+            })
+            .finally(() => {
+              this.loading = false;
+            });
+        })
+        .catch(() => {
+          // 取消操作
+        });
+    },
+
+    updateAnalysisStatus(ids) {
+      this.dataList.forEach((row) => {
+        if (ids.includes(row.id)) {
+          row.run = 1; // 设置状态为"解析中"
+          this.checkAnalysisStatus(row);
+        }
+      });
+    },
+
+    clearSelection() {
+      this.$refs.dataTable.clearSelection();
+      this.selectedRows = [];
+    },
+
     /* 跳转页面 */
     getName(e) {
       this.$router.push({
@@ -444,6 +606,7 @@ export default {
             end_page: _this.analForm.end_page,
           }));
           _this.pageTotal = res.data.pagination.total_count;
+          _this.recordCount = res.data.pagination.total_count;
           _this.loading = false;
 
           // Initialize the analysis status for each row

+ 1 - 1
src/views/knowledgeMenu/category/components/dataSearch.scss

@@ -1,3 +1,3 @@
 .data-search{ 
   padding:20px 10px 0px 10px;
-}
+}

+ 86 - 36
src/views/knowledgeMenu/category/components/dataSearch.vue

@@ -8,17 +8,23 @@
         ></el-input>
       </el-form-item>
 
-      <!--  <el-form-item label="所属分类:">
-          <el-select v-model="queryForm.category_id" clearable class="m-2" placeholder="请选择分类" size="large">
-              <el-option
-                v-for="item in categoryList"
-                :key="item.id"
-                :label="item.name"
-                :value="item.id"
-              />
-            </el-select>
-        </el-form-item>
-        <el-form-item label="文档状态:">
+      <el-form-item label="解析状态:">
+        <el-select
+          v-model="queryForm.run"
+          clearable
+          class="m-2"
+          placeholder="请选择状态"
+          size="large"
+        >
+          <el-option
+            v-for="item in categoryList"
+            :key="item.value"
+            :label="item.label"
+            :value="item.value"
+          />
+        </el-select>
+      </el-form-item>
+      <!--<el-form-item label="文档状态:">
           <el-select v-model="queryForm.status" class="m-2" placeholder="请选择文档状态" size="large">
               <el-option
                 v-for="item in statusOptions"
@@ -30,13 +36,18 @@
         </el-form-item> -->
 
       <el-form-item>
-        <!-- <el-button type="primary" @click="onSubmit">
+        <el-button type="primary" @click="onSubmit">
           <svg-icon icon-class="search" /> 搜索</el-button
-        > -->
+        >
       </el-form-item>
       <el-form-item>
-        <el-popover placement="bottom" trigger="click">
-          <el-button @click="addDocument">本地文件</el-button>
+        <el-button
+          type="primary"
+          class="el-icon-circle-plus-outline"
+          @click="addDocument"
+          >新增文件</el-button
+        >
+        <!-- <el-popover placement="bottom" trigger="click">
           <el-button @click="newFile">新建空文件</el-button>
           <el-button
             type="primary"
@@ -45,7 +56,7 @@
           >
             新增文件</el-button
           >
-        </el-popover>
+        </el-popover> -->
       </el-form-item>
     </el-form>
     <el-dialog
@@ -76,22 +87,26 @@
       <el-form :model="uploadForm" ref="uploadRef" :rules="uploadRules">
         <el-form-item>
           <el-upload
-            class="upload-demo"
+            class="upload-demo custom-upload"
             drag
             :action="url + '/minio/post'"
-            :data="{ bucket_id: queryForm.bucket_id,user_id:queryForm.user_id }"
+            :data="{
+              bucket_id: queryForm.bucket_id,
+              user_id: queryForm.user_id,
+            }"
             multiple
             :on-change="handleFileChange"
             :file-list="fileList"
             :on-success="handleAvatarSuccess"
+            :on-error="handleUploadError"
           >
             <i class="el-icon-upload"></i>
             <div class="el-upload__text">
               将文件拖到此处,或<em>点击上传</em>
             </div>
-            <div class="el-upload__tip" slot="tip">
+            <!-- <div class="el-upload__tip" slot="tip">
               只能上传jpg/png文件,且不超过500kb
-            </div>
+            </div> -->
           </el-upload>
         </el-form-item>
       </el-form>
@@ -114,7 +129,7 @@ export default {
           page: 1,
           pageSize: 10,
           bucket_id: "",
-          user_id:''
+          user_id: "",
         };
       },
     },
@@ -149,14 +164,36 @@ export default {
         },
       ],
       dialogVisible: false,
-      categoryList: [],
+      categoryList: [
+        {
+          value: "0",
+          label: "未解析",
+        },
+        {
+          value: "1",
+          label: "解析中",
+        },
+
+        {
+          value: "3",
+          label: "成功",
+        },
+        {
+          value: "4",
+          label: "失败",
+        },
+        {
+          value: "5",
+          label: "待处理",
+        },
+      ],
       creatForm: {
         bucket_name: "",
       }, //知识库名称
       creatRules: {
         bucket_name: [
           { required: true, message: "请输入知识库名称", trigger: "blur" },
-         /*  { validator: validateBucketName, trigger: "blur" }, */
+          /*  { validator: validateBucketName, trigger: "blur" }, */
         ],
       },
       uploadVisible: false,
@@ -169,7 +206,7 @@ export default {
   mounted() {
     this.url = process.env.VUE_APP_BASE_API;
     this.queryForm.bucket_id = this.$route.query.id;
-   this.queryForm.user_id=this.$store.state.user.id
+    this.queryForm.user_id = this.$store.state.user.id;
   },
   methods: {
     onCreate(e) {
@@ -217,25 +254,30 @@ export default {
     handleRemove(file, fileList) {
       this.fileList = fileList;
     },
-    handleAvatarSuccess(res, file) {
-      this.$emit("bindSetQuery", this.$props.queryForm);
-      this.$message.success('添加成功!')
-      this.uploadVisible=false
+    handleAvatarSuccess(response, res, file) {
+      if (response.status == 200) {
+        this.$emit("bindSetQuery", this.$props.queryForm);
+        this.$message.success("添加成功!");
+        this.uploadVisible = false;
+      } else {
+        this.$message.warning(response.message);
+        this.removeFile(file);
+      }
+    },
+    handleUploadError(err, file, fileList) {
+      this.$message.error("上传失败: " + err.message);
+      this.removeFile(file);
     },
 
-    submitUpload() {
-      // Here you can implement the logic to upload the files
-      console.log("Files to upload:", this.fileList);
-      // After successful upload, you may want to close the dialog and clear the file list
-      this.uploadVisible = false;
-      this.fileList = [];
+    removeFile(file) {
+      this.$refs.upload.handleRemove(file);
     },
 
     handleUploadClose() {
       this.uploadVisible = false;
       this.fileList = [];
     },
-    submitUpload() {
+    /* submitUpload() {
       this.fileList.map((el) => {
         postUpload({ bucket_name: this.queryForm.bucket_name, file: el }).then(
           (res) => {
@@ -243,11 +285,19 @@ export default {
           }
         );
       });
-    },
+    }, */
   },
 };
 </script>
 
 <style lang="scss">
 @import "./dataSearch.scss";
+.custom-upload {
+  .el-upload {
+    width: 100%;
+    .el-upload-dragger {
+      width: 100%;
+    }
+  }
+}
 </style>

+ 15 - 8
src/views/knowledgeMenu/category/infoList.vue

@@ -1,10 +1,16 @@
 <template>
   <div class="project-search">
-    <div>
-      <iframe :src="documentUrl" width="100%" height="780px"></iframe>
+    <div style="width: 50%" v-if="dataList.length!==0">
+      <div v-for="item in dataList" :key="item.id">
+        <div>{{ !item }}</div>
+        <div v-html="item.content"></div>
+      </div>
+    </div>
+    <div v-else style="width: 50%;font-size: 25px;margin: 300px auto; color: #909399;text-align: center;">
+      暂无解析数据
     </div>
-    <div v-for="item in dataList" :key="item.id">
-      <div v-html="item.content"></div>
+    <div style="width: 50%">
+      <iframe :src="documentUrl" width="100%" height="780px"></iframe>
     </div>
   </div>
 </template>
@@ -25,7 +31,7 @@ export default {
       },
       dataList: [],
       conten: "",
-      documentUrl:''
+      documentUrl: "",
     };
   },
   mounted() {
@@ -47,16 +53,17 @@ export default {
       searchTaskInfo(this.queryForm).then((res) => {
         console.log(res);
         this.dataList = res.data.tasks;
-        this.documentUrl=res.data.documentUrl
+        this.documentUrl = res.data.documentUrl;
       });
     },
   },
 };
 </script>
     
-    <style lang="scss">
+    <style lang="scss" scoped>
 .project-search {
-  padding: 30px;
+  display: flex;
+  padding: 10px;
   font-size: 12px;
 }
 </style>

+ 60 - 18
src/views/template/category/components/dataList.vue

@@ -1,6 +1,12 @@
 <template>
-  <div class="data-list">
+  <div
+    class="data-list"
+    v-loading="tableLoading"
+    element-loading-text="加载中..."
+    element-loading-spinner="el-icon-loading"
+  >
     <el-table
+      ref="dataTable"
       :data="dataList"
       stripe
       lazy
@@ -49,7 +55,7 @@
 
     <div class="page-info">
       <el-pagination
-        v-model:currentPage="queryForm.page"
+        :currentPage="queryForm.page"
         :page-size="queryForm.pageSize"
         :total="recordCount"
         :page-count="pageTotal"
@@ -149,6 +155,7 @@ import {
 } from "@/api/template";
 import dataInfo from "./dataInfo.vue";
 import elDragDialog from "@/directive/el-drag-dialog";
+import Vue from "vue";
 export default {
   components: {
     dataInfo,
@@ -187,6 +194,7 @@ export default {
       currentData: {},
       activeName: "base",
       currentCategory: [],
+      tableLoading: false,
       dataForm: {
         id: 0,
         name: "",
@@ -210,6 +218,7 @@ export default {
         },
       ],
       SubclassVisible: false,
+      expandedRows: new Set(),
     };
   },
   mounted() {
@@ -242,22 +251,37 @@ export default {
       if (_this.dataForm.id > 0) {
         updateTemplateCategory(_this.dataForm).then((res) => {
           if (res.status != 200) return;
-          _this.$alert("模板类别信息更新成功");
+          _this.$message.success("模板类别信息更新成功");
           _this.SubclassVisible = false;
           _this.search();
+          _this.refreshAndExpandParent();
         });
       } else {
         createTemplateCategory(_this.dataForm).then((res) => {
           if (res.status != 200) return;
-          _this.$alert("模板类别信息创建成功");
+          _this.$message.success("模板类别信息创建成功");
           _this.SubclassVisible = false;
-         if(_this.dataForm.child_count>0){
-          
-         }
           _this.search();
+          _this.refreshAndExpandParent();
         });
       }
     },
+    refreshAndExpandParent() {
+      const parentId = this.dataForm.parent_id;
+      this.expandedRows.add(parentId);
+      this.search(); // 这里已经重新加载了数据
+      this.$nextTick(() => {
+        // 使用 $refs 来访问 el-table 组件
+        const table = this.$refs.dataTable;
+        if (table) {
+          // 找到父行并展开
+          const parentRow = this.dataList.find((row) => row.id === parentId);
+          if (parentRow) {
+            table.toggleRowExpansion(parentRow, true);
+          }
+        }
+      });
+    },
 
     //产品详情
     getInfo(id) {
@@ -323,6 +347,7 @@ export default {
             }
           });
           resolve(res.data);
+          this.expandedRows.add(row.id);
         });
 
         /*    resolve(row.children); */
@@ -372,19 +397,36 @@ export default {
     //搜索
     search() {
       let _this = this;
-      searchTemplateCategory(_this.queryForm).then((res) => {
-        if (!res) return;
-        res.data.dataList.map((el) => {
-          if (el.child_count > 0) {
-            el.hasChildren = true;
-          } else {
-            el.hasChildren = false;
+      _this.dataList = [];
+      _this.tableLoading = true;
+      searchTemplateCategory(_this.queryForm)
+        .then((res) => {
+          if (!res) {
+            _this.tableLoading = false;
+            return;
           }
+          const newDataList = res.data.dataList.map((el) => {
+            if (el.child_count > 0) {
+              el.hasChildren = true;
+            } else {
+              el.hasChildren = false;
+            }
+          });
+          _this.dataList = res.data.dataList;
+          _this.recordCount = res.data.totalRecord;
+          _this.pageTotal = res.data.totalPage;
+          _this.$forceUpdate();
+
+          // 使用 nextTick 确保 DOM 已更新
+          _this.$nextTick(() => {
+            // 这里可以添加任何需要在 DOM 更新后执行的操作
+            console.log("View updated");
+            _this.tableLoading = false;
+          });
+        })
+        .catch(() => {
+          _this.tableLoading = false;
         });
-        _this.dataList = res.data.dataList;
-        _this.recordCount = res.data.totalRecord;
-        _this.pageTotal = res.data.totalPage;
-      });
     },
     //修改分页
     ChangePage(e) {

Some files were not shown because too many files changed in this diff