From d498cdcf61fd8e2ec341cad3e7c21829ecef1672 Mon Sep 17 00:00:00 2001
From: sd <shidong@jhsoft.cc>
Date: 星期二, 26 八月 2025 17:44:18 +0800
Subject: [PATCH] 摄像机配置、数据推送和文搜万物 bug和样式修复; 知识库卡片样式调整参照大模型平台知识库样式。

---
 src/pages/Knowledge/components/KnowledgeView copy.vue       |  458 ++++++
 src/pages/datapush/index/RightEvent copy 2.vue              |  950 +++++++++++++
 src/pages/datapush/index/RightEvent.vue                     |    5 
 src/components/rightPagination.vue                          |    4 
 src/api/AiRetrievalView.ts                                  |   26 
 src/pages/Knowledge/components/KnowLedgeFilesView.vue       | 1060 +++++++++++++++
 src/pages/Knowledge/components/KnowledgeView copy 2.vue     |  612 ++++++++
 src/pages/cameraAccess/components/SceneRule.vue             |   39 
 src/pages/cameraAccess/components/ruleSelect/ruleSelect.vue |    2 
 src/pages/Knowledge/index/main.ts                           |   30 
 src/pages/searchNew/components/AiRetrievalView.vue          |   31 
 src/pages/searchNew/components/SurveyView.vue               |   67 
 src/pages/Knowledge/components/KnowledgeView.vue            |  644 +++++++++
 src/pages/Knowledge/index/mixins.ts                         |   25 
 src/pages/Knowledge/index/App.vue                           |  131 +
 public/config.json                                          |    5 
 src/Pool/VideoManageData.ts                                 |   27 
 src/api/KnowledgeView.ts                                    |   66 
 18 files changed, 4,106 insertions(+), 76 deletions(-)

diff --git a/public/config.json b/public/config.json
index fdad481..692425c 100644
--- a/public/config.json
+++ b/public/config.json
@@ -1,3 +1,6 @@
 {
-  "serverUrl": "http://192.168.1.173:8088/v1"
+  "iframeUrl": "http://127.0.0.1:7009",
+  "chatUrl": "http://127.0.0.1:8870",
+  "docUrl":"http://127.0.0.1:7010",
+  "severUrl":"http://127.0.0.1:8088"
 }
\ No newline at end of file
diff --git a/src/Pool/VideoManageData.ts b/src/Pool/VideoManageData.ts
index f16c827..6c95ac3 100644
--- a/src/Pool/VideoManageData.ts
+++ b/src/Pool/VideoManageData.ts
@@ -57,14 +57,25 @@
       }
     );
     if (rspk && rspk.status === 200) {
-      this.knowsList = rspk.data.map(k => ({
-        id: Number(k.knowledgeId),
-        title: k.title,
-        files: k.files.map(f => ({
-          id: Number(f.id),
-          title: f.title
-        }))
-      }))
+      for(let i = 0; i < rspk.data.length; i++){
+        if(rspk.data[i].files){
+          this.knowsList.push(
+            {
+              id: Number(rspk.data[i].id),
+              title: rspk.data[i].title,
+            }
+          )
+        }
+
+      }
+      // this.knowsList = rspk.data.map(k => ({
+      //   id: Number(k.knowledgeId),
+      //   title: k.title,
+      //   files: k.files.map(f => ({
+      //     id: Number(f.id),
+      //     title: f.title
+      //   }))
+      // }))
     }
     console.info("rspk:"+JSON.stringify(this.knowsList))
   }
diff --git a/src/api/AiRetrievalView.ts b/src/api/AiRetrievalView.ts
index 368a7d0..1d98692 100644
--- a/src/api/AiRetrievalView.ts
+++ b/src/api/AiRetrievalView.ts
@@ -15,11 +15,23 @@
       params
     })
   },
-  getChatDetail(params) {//瀵硅瘽妫�绱�
-    return request({
-      url: '/api-v1/v1/record/chat',
-      method: 'post',
-      params
-    })
-  },
+  // getChatDetail(data) {//瀵硅瘽妫�绱�
+  //   return request({
+  //     url: '/api-v1/v1/record/chat',
+  //     method: 'post',
+  //     data,
+  //     headers: {
+  //       "Content-Type": "application/json",
+  //       "Accept":"text/event-stream",
+  //       "Cache-Control": "no-cache"
+  //     },
+  //   })
+  // },
+  getChatDetail(data) {
+    return fetch("/api-v1/v1/record/chat", { // 浣跨敤浠g悊璺緞
+      method: "POST",
+      headers: { "Content-Type": "application/json" },
+      body: JSON.stringify(data)
+    }); // 鐩存帴杩斿洖 fetch 鐨� Promise
+  }
 }
\ No newline at end of file
diff --git a/src/api/KnowledgeView.ts b/src/api/KnowledgeView.ts
new file mode 100644
index 0000000..f4e0ba1
--- /dev/null
+++ b/src/api/KnowledgeView.ts
@@ -0,0 +1,66 @@
+import request from "@/scripts/httpRequest";
+export default {
+  getKnowledges(params) {
+    // return service.get('/checkContent/all', { params })
+    return request({
+      url: '/api-v1/v1/knowledge/all',
+      method: 'get',
+      params
+    })
+  },
+  createKnowledge(data) {
+    // return service.post('/checkContent/add', data)
+    return request({
+      url: '/api-v1/v1/knowledge/add',
+      method: 'post',
+      data
+    })
+  },
+  updateKnowledge(data) {
+    // return service.put(`/checkContent/update`, data)
+    return request({
+      url: '/api-v1/v1/knowledge/update',
+      method: 'put',
+      data
+    })
+  },
+  deleteKnowledgee(params) {
+    // return service.delete(`/checkContent/delete`,{ params })
+    return request({
+      url: '/api-v1/v1/knowledge/delete',
+      method: 'delete',
+      params
+    })
+  },
+
+  getDocumentList(params) {
+    // return service.get('/checkContent/all', { params })
+    return request({
+      url: '/api-v1/v1/knowledge/documentList',
+      method: 'get',
+      params
+    })
+  },
+  uploadFiles(data){
+    return request({
+      url: '/api-v1/v1/knowledge/uploadDocument',
+      method: 'post',
+      data
+    })
+  },
+  downloadFiles(params){
+    return request({
+      url: '/api-v1/v1/knowledge/download',
+      method: 'get',
+      params
+    })
+  },
+  deleteDocument(params) {
+    // return service.delete(`/checkContent/delete`,{ params })
+    return request({
+      url: '/api-v1/v1/knowledge/delDocument',
+      method: 'delete',
+      params
+    })
+  },
+}
\ No newline at end of file
diff --git a/src/components/rightPagination.vue b/src/components/rightPagination.vue
index 1e2fa6c..f00b44d 100644
--- a/src/components/rightPagination.vue
+++ b/src/components/rightPagination.vue
@@ -90,8 +90,8 @@
   margin-top: 20px;
   padding: 15px 0;
   text-align: right;
-  background: #fff;
-  border-top: 1px solid #ebeef5;
+  /* background: #fff;
+  border-top: 1px solid #ebeef5; */
 }
 /* 鍝嶅簲寮忛�傞厤 */
 @media screen and (max-width: 768px) {
diff --git a/src/pages/Knowledge/components/KnowLedgeFilesView.vue b/src/pages/Knowledge/components/KnowLedgeFilesView.vue
new file mode 100644
index 0000000..414eb89
--- /dev/null
+++ b/src/pages/Knowledge/components/KnowLedgeFilesView.vue
@@ -0,0 +1,1060 @@
+<template>
+
+  <div class="task-container">
+    <!-- 鍙充笂瑙掑叧闂寜閽� -->
+    <div class="close-container">
+      <el-button type="text" icon="el-icon-back" @click="handleClose" class="close-btn">
+      </el-button>
+    </div>
+
+    <!-- 鏂板鏂囦欢寮圭獥 -->
+    <el-dialog :title="dialogType === 'create' ? '涓婁紶鏂囦欢鎴栨枃浠跺す' : ''" :visible.sync="dialogVisible" width="800px"
+      custom-class="task-dialog" @closed="handleDialogClose" :close-on-click-modal="false"
+      :close-on-press-escape="false">
+      <!-- 鏂板鏂囦欢鏃舵樉绀轰笂浼犲尯鍩� -->
+      <div v-if="dialogType === 'create'" class="upload-area">
+        <!-- 鏂囦欢閫夋嫨鍖哄煙 - 宸查噸鏋勪负鏀寔鎷栨嫿 -->
+        <div class="upload-container">
+          <!-- 鏂囦欢鎷栨嫿鍖哄煙 -->
+          <div class="upload-wrapper drag-area" @dragover.prevent="handleDragOver" @dragleave="handleDragLeave"
+            @drop.prevent="handleDrop" :class="{ 'drag-over': isDragOver }">
+            <div class="drag-content">
+              <i class="el-icon-upload"></i>
+              <div class="el-upload__text">鎷栨嫿鏂囦欢鎴栨枃浠跺す鍒版澶勪笂浼�</div>
+              <div class="upload-tip">鎴�</div>
+              <div class="action-buttons">
+                <el-button type="primary" size="small" @click.stop="triggerFileInput">閫夋嫨鏂囦欢</el-button>
+                <el-button type="primary" size="small" @click.stop="triggerFolderInput">閫夋嫨鏂囦欢澶�</el-button>
+              </div>
+            </div>
+            <input type="file" ref="fileInput" multiple style="display: none" @change="handleFileChange">
+            <input type="file" ref="folderInput" webkitdirectory style="display: none" @change="handleFolderChange">
+          </div>
+        </div>
+
+        <!-- 涓婁紶鏂囦欢鍒楄〃 -->
+        <div class="file-list">
+          <div class="list-header">
+            <!-- <div>鍥炬爣</div> -->
+            <div>绫诲瀷</div>
+            <div>鍚嶇О</div>
+            <div>鎿嶄綔</div>
+          </div>
+          <div class="list-items">
+            <div v-for="(item, index) in uploadList" :key="index" class="file-item">
+              <!-- <div class="item-icon">
+                <i :class="item.type === 'folder' ? 'el-icon-folder' : 'el-icon-document'"></i>
+              </div> -->
+              <div class="item-type">{{ item.type === 'folder' ? '鏂囦欢澶�' : item.fileType || '鏂囦欢' }}</div>
+              <div class="item-name">{{ item.name }}</div>
+              <div class="item-action">
+                <i class="el-icon-delete" @click="removeFileItem(index)"></i>
+              </div>
+            </div>
+            <div v-if="uploadList.length === 0" class="empty-tip">
+              鏆傛棤鏂囦欢
+            </div>
+          </div>
+        </div>
+      </div>
+
+      <span slot="footer">
+        <el-button @click="dialogVisible = false">鍙栨秷</el-button>
+        <el-button type="primary" @click="submitTask" :loading="isUploading" :disabled="isUploading">
+          <span v-if="isUploading">涓婁紶涓�...</span>
+          <span v-else>淇濆瓨</span>
+        </el-button>
+      </span>
+    </el-dialog>
+
+    <!-- 鎼滅储鍜屾搷浣滄爮 -->
+    <div class="search-bar">
+      <el-input v-model="searchKey" placeholder="璇疯緭鍏ュ悕绉�" clearable class="search-input"></el-input>
+      <el-button type="primary" @click="handleSearch">鏌ヨ</el-button>
+      <el-button @click="handleReset">閲嶇疆</el-button>
+      <el-button type="primary" class="new-btn" @click="handleCreate()"><i class="el-icon-plus"></i> 鏂板鏂囦欢</el-button>
+    </div>
+
+    <!-- 鍦ㄨ〃鏍煎尯鍩熶笂鏂规坊鍔犲叏灞�鍔犺浇鐘舵�� -->
+    <div class="global-loading" v-if="isUploading">
+      <div class="loading-content">
+        <i class="el-icon-loading"></i>
+        <p>鏂囦欢涓婁紶涓紝璇风◢鍊�...</p>
+      </div>
+    </div>
+    <!-- 浠诲姟琛ㄦ牸锛堢簿纭垪瀹介厤缃級 -->
+    <el-table :data="tableData" style="width: 100%" class="data-table" :header-cell-style="{
+      background: '#f5f7fa',
+      color: '#606266'
+    }">
+      <!-- 閫夋嫨鍒� -->
+      <!-- <el-table-column type="selection"  width="auto" min-width="5%"></el-table-column> -->
+
+
+      <!-- 鏂囦欢ID -->
+      <el-table-column prop="id" label="鏂囦欢ID" v-if="false">
+        <template #default="{ row }">
+          <span class="text-ellipsis">{{ row.id }}</span>
+        </template>
+      </el-table-column>
+      <!-- 鏂囦欢URl -->
+      <el-table-column prop="fileUrl" label="鏂囦欢URl" v-if="false">
+        <template #default="{ row }">
+          <span class="text-ellipsis">{{ row.fileUrl }}</span>
+        </template>
+      </el-table-column>
+      <!-- 鍚嶇О -->
+      <el-table-column prop="fileName" label="鍚嶇О" width="auto" min-width="180px">
+        <template #default="{ row }">
+          <span class="text-ellipsis">{{ row.fileName }}</span>
+        </template>
+      </el-table-column>
+      <!-- 鍒嗗潡鏁� -->
+      <el-table-column prop="totalChunks" label="鍒嗗潡鏁�" width="auto" min-width="80px">
+        <template #default="{ row }">
+          <!-- <el-tag class="text-ellipsis">{{ row.modelName }}</el-tag> -->
+          {{ row.totalChunks }}
+        </template>
+      </el-table-column>
+
+      <!-- 涓婁紶鏃堕棿 -->
+      <el-table-column prop="createTime" label="涓婁紶鏃堕棿" width="auto" min-width="80px">
+        <template #default="{ row }">
+          <!-- <span class="level level-1 text-ellipsis">{{ row.createTime }}</span> -->
+          <!-- {{ row.createTime }} -->
+          {{ formatDateTime(row.createTime) }}
+        </template>
+      </el-table-column>
+      <!-- 瑙f瀽鏂规硶 -->
+      <el-table-column prop="parserType" label="瑙f瀽鏂规硶" width="auto" min-width="180px">
+        <template #default="{ row }">
+          <div class="multi-tags">
+            {{ row.parserType }}
+          </div>
+        </template>
+      </el-table-column>
+
+      <!-- 鎿嶄綔 -->
+      <el-table-column label="鎿嶄綔" width="auto" min-width="80px">
+        <template #default="{ row }">
+          <div style="display: flex; gap: 8px">
+            <el-button type="text" icon="el-icon-delete" @click="handleDelete(row)"></el-button>
+            <el-button type="text" icon="el-icon-download" @click="handleDownload(row)"></el-button>
+          </div>
+        </template>
+      </el-table-column>
+    </el-table>
+
+    <!-- 鍒嗛〉 -->
+    <div class="pagination">
+      <el-pagination @current-change="handleCurrentChange" :page-size="10" layout="prev, pager, next"
+        :total="this.pagination.total"></el-pagination>
+    </div>
+  </div>
+</template>
+
+<script>
+import Inspection from "@/api/KnowledgeView"
+export default {
+  props: {
+    knowledgeId: {
+      type: [Number, String],
+      required: true
+    }
+  },
+  data() {
+    return {
+      isUploading: false,
+      uploadList: [], // 涓婁紶鏂囦欢鍒楄〃
+      isDragOver: false, // 鎷栨嫿鐘舵��
+      // 鏂板鎼滅储鍙傛暟
+      searchParams: {
+        searchKey: '',
+      },
+      // 鏂板鍒嗛〉鍙傛暟
+      pagination: {
+        page: 1,
+        pageSize: 10,
+        total: 100,
+        totalPage: 1
+      },
+      // 鏂板鐘舵�佺鐞�
+      dialogType: 'create',
+      dialogVisible: false,
+      taskForm: {
+        id: null,
+        fileName: '',
+        taskDescription: "",
+        modelId: '',
+        totalChunks: '',
+        createTime: '',
+        eventLevelName: '',
+        videoIds: [],
+        videoCamera: [],
+        workingTimes: [],
+        checkContents: [],
+        warningRules: []
+      },
+      searchKey: '',
+      currentPage: 1,
+      tableData: []
+    }
+  },
+  mounted() {
+
+    this.handleReset()
+    this.fetchTableData() // 鍒濆鍖栧姞杞芥暟鎹�
+  },
+  methods: {
+    // 娣诲姞涓嬭浇鏂规硶
+    async handleDownload(row) {
+      window.location.href="/api/v1/knowledge/download?id="+row.id
+      // try {
+      //   const response = await Inspection.downloadFiles({
+      //     id: row.id
+      //   }, {
+      //     responseType: 'blob' // 鍏抽敭锛氬0鏄庡搷搴旂被鍨嬩负浜岃繘鍒舵暟鎹�
+      //   });
+
+      //   // 鍒涘缓Blob瀵硅薄
+      //   const blob = new Blob([response.data]);
+
+      //   // 鍒涘缓涓嬭浇閾炬帴
+      //   const url = URL.createObjectURL(blob);
+      //   const link = document.createElement('a');
+      //   link.href = url;
+
+      //   // 璁剧疆鏂囦欢鍚嶏紙浠庡搷搴斿ご鎻愬彇鎴栦娇鐢╮ow.fileName锛�
+      //   const fileName = row.fileName || `file_${row.id}`;
+      //   link.download = fileName;
+
+      //   // 瑙﹀彂涓嬭浇
+      //   document.body.appendChild(link);
+      //   link.click();
+
+      //   // 娓呯悊璧勬簮
+      //   setTimeout(() => {
+      //     document.body.removeChild(link);
+      //     URL.revokeObjectURL(url);
+      //   }, 100);
+
+      // } catch (error) {
+      //   console.error('涓嬭浇澶辫触:', error);
+      //   this.$message.error('涓嬭浇澶辫触');
+      // }
+    },
+    // 澶勭悊鏂囦欢鎷栨嫿杩涘叆鍖哄煙
+    handleDragOver(e) {
+      e.preventDefault();
+      this.isDragOver = true;
+    },
+
+    // 澶勭悊鏂囦欢鎷栨嫿绂诲紑鍖哄煙
+    handleDragLeave() {
+      this.isDragOver = false;
+    },
+
+    // 澶勭悊鏂囦欢鏀句笅锛堟嫋鎷戒笂浼狅級
+    handleDrop(e) {
+      this.isDragOver = false;
+      const items = e.dataTransfer.items;
+
+      if (items) {
+        // 澶勭悊鏂囦欢澶规嫋鎷�
+        for (let i = 0; i < items.length; i++) {
+          const entry = items[i].webkitGetAsEntry();
+          if (entry) {
+            this.traverseEntry(entry);
+          }
+        }
+      } else {
+        // 澶勭悊鏂囦欢鎷栨嫿
+        const files = e.dataTransfer.files;
+        this.processFiles(Array.from(files));
+      }
+    },
+
+    // 閬嶅巻鏂囦欢绯荤粺鏉$洰锛堢敤浜庢枃浠跺す鎷栨嫿锛�
+    async traverseEntry(entry, path = '') {
+      if (entry.isFile) {
+        const file = await this.getFileFromEntry(entry);
+        this.addFileToList(file);
+      } else if (entry.isDirectory) {
+        const directoryReader = entry.createReader();
+        const entries = await this.readDirectoryEntries(directoryReader);
+
+        // 娣诲姞鏂囦欢澶瑰埌鍒楄〃
+        // this.uploadList.push({
+        //   type: 'folder',
+        //   name: entry.name,
+        //   fileCount: entries.length,
+        //   files: [] // 瀹為檯鏂囦欢涓垜浠彧灞曠ず鏂囦欢澶瑰悕
+        // });
+
+        for (let i = 0; i < entries.length; i++) {
+          await this.traverseEntry(entries[i], `${path}/${entry.name}`);
+        }
+      }
+    },
+
+    // 浠庢枃浠剁郴缁熸潯鐩幏鍙栨枃浠�
+    getFileFromEntry(entry) {
+      return new Promise((resolve) => {
+        entry.file(file => {
+          resolve(file);
+        });
+      });
+    },
+
+    // 璇诲彇鏂囦欢澶规潯鐩�
+    readDirectoryEntries(directoryReader) {
+      return new Promise((resolve) => {
+        directoryReader.readEntries(entries => {
+          resolve(entries);
+        });
+      });
+    },
+
+    // 澶勭悊閫夋嫨鐨勬枃浠�
+    processFiles(files) {
+      if (!files.length) return;
+
+      files.forEach(file => {
+        // 璺宠繃绌烘枃浠跺拰鏂囦欢澶�
+        if (file.size > 0 || file.type !== '') {
+          this.addFileToList(file);
+        }
+      });
+    },
+
+    // 娣诲姞鏂囦欢鍒颁笂浼犲垪琛�
+    addFileToList(file) {
+      const fileType = this.getFileType(file.name);
+      this.uploadList.push({
+        type: 'file',
+        name: file.name,
+        fileType,
+        size: file.size,
+        file
+      });
+    },
+    // 瑙﹀彂鏂囦欢閫夋嫨
+    triggerFileInput() {
+      this.$refs.fileInput.click();
+    },
+
+    // 瑙﹀彂鏂囦欢澶归�夋嫨
+    triggerFolderInput() {
+      this.$refs.folderInput.click();
+    },
+
+    // 澶勭悊鏂囦欢閫夋嫨
+    handleFileChange(e) {
+      const files = Array.from(e.target.files);
+      if (files.length === 0) return;
+
+      files.forEach(file => {
+        const fileType = this.getFileType(file.name);
+        this.uploadList.push({
+          type: 'file',
+          name: file.name,
+          fileType,
+          size: file.size,
+          file
+        });
+      });
+      e.target.value = '';
+    },
+
+    // 澶勭悊鏂囦欢澶归�夋嫨
+    handleFolderChange(e) {
+      const files = Array.from(e.target.files);
+      if (files.length === 0) return;
+
+      // 鑾峰彇鏂囦欢澶瑰悕绉�
+      const folderName = this.extractFolderName(files);
+
+      // this.uploadList.push({
+      //   type: 'folder',
+      //   name: folderName,
+      //   fileCount: files.length,
+      //   files
+      // });
+      e.target.value = '';
+    },
+
+    // 浠庢枃浠跺垪琛ㄤ腑鎻愬彇鏂囦欢澶瑰悕
+    extractFolderName(files) {
+      if (files.length === 0) return '鏈懡鍚嶆枃浠跺す';
+      const path = files[0].webkitRelativePath;
+      const parts = path.split('/');
+      return parts.length > 1 ? parts[0] : '鏈懡鍚嶆枃浠跺す';
+    },
+
+    // 鑾峰彇鏂囦欢绫诲瀷锛堟牴鎹墿灞曞悕锛�
+    getFileType(fileName) {
+      const ext = fileName.split('.').pop().toLowerCase();
+      const types = {
+        jpg: '鍥剧墖',
+        jpeg: '鍥剧墖',
+        png: '鍥剧墖',
+        gif: '鍥剧墖',
+        pdf: 'PDF',
+        doc: 'Word',
+        docx: 'Word',
+        xls: 'Excel',
+        xlsx: 'Excel',
+        ppt: 'PPT',
+        pptx: 'PPT',
+        txt: '鏂囨湰',
+        zip: '鍘嬬缉鍖�',
+        rar: '鍘嬬缉鍖�',
+        mp4: '瑙嗛',
+        mov: '瑙嗛',
+        avi: '瑙嗛'
+      };
+      return types[ext] || '鏂囦欢';
+    },
+
+    // 绉婚櫎鏂囦欢椤�
+    removeFileItem(index) {
+      this.uploadList.splice(index, 1);
+    },
+
+    // 鏂板鎼滅储澶勭悊鏂规硶
+    handleSearch() {
+      this.pagination.page = 1; // 鎼滅储鏃堕噸缃埌绗竴椤�
+      this.fetchTableData();
+    },
+    // 鏂板閲嶇疆澶勭悊鏂规硶
+    handleReset() {
+      this.searchKey = '';
+    },
+    // 鍒嗛〉澶勭悊
+    handleCurrentChange(page) {
+      this.pagination.page = page
+      this.fetchTableData()
+      // console.info(this.pagination)
+    },
+    // 鏂板鎿嶄綔
+    handleCreate() {
+      this.dialogType = 'create'
+      this.dialogVisible = true
+      this.uploadList = []
+      this.taskForm = {
+        id: 0,
+        fileName: '',
+        taskDescription: "",
+        modelId: 1,
+        totalChunks: '',
+        createTime: 1,
+        eventLevelName: '',
+        videoIds: [],
+        videoCamera: [],
+        workingTimes: [],
+        checkContents: [],
+        warningRules: []
+      }
+    },
+
+    // 鍒犻櫎鎿嶄綔
+    async handleDelete(row) {
+      this.$confirm('纭鍒犻櫎璇ユ枃浠跺悧锛�', '鎻愮ず', {
+        type: 'warning'
+      }).then(async () => {
+        // this.tableData = this.tableData.filter(item => item.taskName !== row.taskName)
+        try {
+          await Inspection.deleteDocument({
+            id: row.id
+          }).then(async (rsp) => {
+            if (rsp && rsp.status === 200) {
+              // 鍒犻櫎鎴愬姛鍚庤嚜鍔ㄤ慨姝i〉鐮�
+              if (this.files.length === 1 && this.pagination.page > 1) {
+                this.pagination.page -= 1
+              }
+              await this.handleReset()
+              await this.fetchTableData()
+              this.$message({
+                type: "success",
+                message: "鍒犻櫎鎴愬姛"
+              })
+            } else {
+              this.$message({
+                type: "error",
+                message: rsp.msg
+              })
+            }
+          })
+
+        } catch (error) {
+          this.$message.error('鍒犻櫎澶辫触')
+          console.error('API Error:', error)
+        }
+      }).catch(() => {
+
+      })
+    },
+    // 寮圭獥鎵撳紑鏃剁殑澶勭悊
+    handleDialogOpen() {
+      this.$nextTick(() => {
+        this.$refs.taskForm.clearValidate()
+      })
+    },
+    // 寮圭獥鍏抽棴鏃剁殑澶勭悊
+    handleDialogClose() {
+      this.$refs.taskForm.resetFields()
+    },
+    // 鏂板鏁版嵁鑾峰彇鏂规硶
+    async fetchTableData() {
+      console.info("knowledgeId :" + this.knowledgeId)
+      try {
+        // 妯℃嫙鎺ュ彛璇锋眰
+        const res = await Inspection.getDocumentList({
+          page: this.pagination.page,
+          pageSize: this.pagination.pageSize,
+          knowId: this.knowledgeId,
+          searchName: this.searchKey // 娣诲姞鎼滅储鍙傛暟
+        })
+        // 鏇存柊鍒嗛〉鏁版嵁鍓嶅厛鏍¢獙褰撳墠椤电爜
+        const totalPage = res.data.pagination.totalPage
+        const currentPage = this.pagination.page > totalPage
+          ? totalPage
+          : res.data.pagination.page
+        this.pagination = {
+          ...this.pagination,
+          page: currentPage,
+          total: res.data.pagination.total,
+          totalPage: totalPage
+        }
+        this.pagination.total = res.data.pagination.total
+        this.pagination.totalPage = res.data.pagination.totalPage
+        this.tableData = res.data.list
+        // this.tableData = [{
+        //   id: 1,
+        //   fileName: '瀹夊叏鐢熶骇浠诲姟111111111111111111111111',
+        //   fileUrl: "D:/鏂板缓鏂囦欢澶�/瑙e喅ide缂栬瘧鎶ラ敊/璇存槑.jpg",
+        //   totalChunks: '鍒嗘暟鍧�',
+        //   createTime: '涓婁紶鏃堕棿',
+        //   parserType: "瑙f瀽鏂规硶"
+        // }]
+      } catch (error) {
+        this.$message.error('鏁版嵁鍔犺浇澶辫触' + error.message)
+      }
+    },
+
+    // 鎻愪氦鏂规硶
+    async submitTask() {
+      if (this.dialogType === 'create') {
+        // 澶勭悊涓婁紶閫昏緫
+        if (this.uploadList.length === 0) {
+          this.$message.warning('璇疯嚦灏戜笂浼犱竴涓枃浠舵垨鏂囦欢澶�');
+          return;
+        }
+        // 璁剧疆涓婁紶鐘舵��
+        this.isUploading = true;
+        try {
+          // 1. 鍒涘缓FormData鐢ㄤ簬鏂囦欢涓婁紶
+          let formData = new FormData();
+
+          // 2. 娣诲姞瀹為檯鏂囦欢鍐呭鍒癋ormData
+          this.uploadList.forEach(item => {
+            if (item.file) {
+              // 娣诲姞鏂囦欢鏃舵寚瀹氭纭殑鏂囦欢瀛楁鍚嶏紙鏍规嵁API瑕佹眰锛�
+              formData.append('file', item.file);
+            }
+          });
+          // formData.append('file', this.uploadList[0].file);//鍚庣鏆傛椂鍙敮鎸佸崟鏂囦欢
+          // 3. 娣诲姞鍏朵粬蹇呰鍙傛暟锛堝鐭ヨ瘑搴揑D锛�
+          const knowledgeId = this.knowledgeId;
+          if (knowledgeId) {
+            formData.append('knowId', knowledgeId);
+          }
+
+          for (var pair of formData.entries()) {
+            console.log(pair[0] + ', ' + pair[1]);
+          }
+          // 4. 璋冪敤瀹為檯鐨勪笂浼燗PI
+          const response = await Inspection.uploadFiles(formData);
+          if (response.status == 200) {
+            this.$message.success('鏂囦欢涓婁紶鎴愬姛');
+            this.dialogVisible = false;
+            this.uploadList = [];
+          } else {
+            this.$message.error(response.msg);
+          }
+        } catch (error) {
+          this.$message.error('鏂囦欢涓婁紶澶辫触: ' + error.message);
+          console.error('Upload error:', error);
+        } finally {
+          // 鏃犺鎴愬姛澶辫触锛岄兘缁撴潫鍔犺浇鐘舵��
+          this.isUploading = false;
+        }
+      } else {
+        // 鍘熸湁鐨勭紪杈戜换鍔¢�昏緫
+        // ...锛堜繚鐣欏師鏈夌紪杈戜换鍔$殑鎻愪氦閫昏緫锛�...
+      }
+      // 鍒锋柊鍒楄〃
+      await this.handleReset()
+      await this.fetchTableData()
+    },
+    //鍏抽棴缁勪欢鏂规硶
+    handleClose() {
+      // this.$router.push({
+      //   name: 'knowledge' // 杩斿洖鍒扮煡璇嗗簱鍒楄〃璺敱
+      // })
+      this.$emit('back') // 瑙﹀彂杩斿洖浜嬩欢
+    },
+    // 鏍煎紡鍖栧紑濮嬫椂闂�
+    formatDateTime(dateTimeStr) {
+      if (!dateTimeStr) return '';
+
+      try {
+        // 澶勭悊UTC鏍煎紡鏃ユ湡瀛楃涓�
+        const dateObj = new Date(dateTimeStr);
+
+        // 鏍煎紡鍖栦负骞存湀鏃� 鏃跺垎绉掞紙琛ラ浂锛�
+        return dateObj.toLocaleString('zh-CN', {
+          year: 'numeric',
+          month: '2-digit',
+          day: '2-digit',
+          hour: '2-digit',
+          minute: '2-digit',
+          second: '2-digit',
+          hour12: false
+        }).replace(/\//g, '-');
+      } catch (e) {
+        console.error('鏃ユ湡鏍煎紡杞崲閿欒:', e);
+        // 鍥為��澶勭悊锛氬彧鎻愬彇骞存湀鏃ユ椂鍒嗙閮ㄥ垎
+        return dateTimeStr.slice(0, 19);
+      }
+    },
+  },
+
+}
+</script>
+
+<style lang="scss" scoped>
+.task-container {
+  padding: 20px;
+  background: #fff;
+
+
+  .close-container {
+    position: absolute;
+    top: 15px;
+    left: 20px;
+
+    .close-btn {
+      font-size: 26px;
+      color: #606266;
+      // background: #f5f7fa;
+      // padding: 8px 15px;
+      // border-radius: 4px;
+      // box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
+
+
+    }
+  }
+
+  .search-bar {
+    float: right;
+    display: flex;
+    gap: 10px;
+    margin-bottom: 20px;
+
+    .search-input {
+      width: 300px;
+    }
+
+    .new-btn {
+      // margin-left: auto;
+    }
+  }
+
+  .data-table {
+    ::v-deep {
+
+      .el-table__header,
+      .el-table__body {
+
+        th,
+        td {
+          border-right: 1px solid #ebeef5;
+
+          &:last-child {
+            border-right: none;
+          }
+        }
+      }
+
+      .el-table__row td {
+        padding: 12px 0;
+      }
+
+      .cell {
+        overflow: visible !important;
+      }
+    }
+
+    .text-ellipsis {
+      display: inline-block;
+      max-width: 100%;
+      overflow: hidden;
+      text-overflow: ellipsis;
+      white-space: nowrap;
+      vertical-align: middle;
+    }
+
+    .level {
+      display: inline-block;
+      padding: 4px 12px;
+      border-radius: 4px;
+      font-size: 12px;
+
+      &-1 {
+        background: #fef0f0;
+        color: #f56c6c;
+      }
+    }
+
+    .check-tag {
+      margin: 2px;
+    }
+
+    .kb-btn {
+      padding: 5px 10px;
+    }
+
+    .multi-tags {
+      display: flex;
+      flex-wrap: nowrap;
+      overflow: hidden;
+      gap: 4px;
+
+      .tag-item {
+        flex-shrink: 1;
+        max-width: 100px;
+        margin: 2px;
+      }
+    }
+
+    .check-items {
+      display: flex;
+      flex-wrap: wrap;
+      max-height: 36px;
+      overflow: hidden;
+      gap: 4px;
+
+      .check-tag {
+        max-width: 120px;
+        flex-shrink: 1;
+      }
+    }
+
+    .kb-buttons {
+      display: flex;
+      flex-wrap: nowrap;
+      overflow: hidden;
+      gap: 4px;
+
+      .kb-btn {
+        max-width: 100px;
+        overflow: hidden;
+        text-overflow: ellipsis;
+        padding: 5px 8px;
+
+        span {
+          display: block;
+          overflow: hidden;
+          text-overflow: ellipsis;
+        }
+      }
+    }
+  }
+
+  .pagination {
+    display: flex;
+    justify-content: flex-end;
+    margin-top: 20px;
+  }
+}
+
+.task-dialog {
+  .el-dialog__header {
+    border-bottom: 1px solid #ebeef5;
+    padding: 15px 20px;
+  }
+
+  .el-dialog__title {
+    font-size: 16px;
+    color: #303133;
+  }
+
+  .el-form-item {
+    margin-bottom: 18px;
+
+    .el-input__inner,
+    .el-textarea__inner {
+      border-radius: 4px;
+    }
+  }
+
+  .el-select {
+    width: 100%;
+  }
+
+  .el-button--primary {
+    padding: 10px 20px;
+  }
+}
+
+/* 鏌ョ湅璇︽儏寮圭獥鏍峰紡 */
+.view-dialog {
+  .el-dialog__header {
+    border-bottom: 1px solid #ebeef5;
+    padding: 15px 20px;
+  }
+
+  .el-dialog__title {
+    font-size: 16px;
+    color: #303133;
+  }
+
+  .el-form-item {
+    margin-bottom: 18px;
+
+    .el-input__inner,
+    .el-textarea__inner {
+      border-radius: 4px;
+    }
+  }
+
+  .el-select {
+    width: 100%;
+  }
+
+  .el-button--primary {
+    padding: 10px 20px;
+  }
+}
+
+.time-dialog {
+  .el-dialog__body {
+    padding: 20px;
+  }
+
+  .time-period-component {
+    margin: 15px 0;
+  }
+}
+
+.time-setting-btn {
+  margin-left: 10px;
+}
+
+//涓婁紶鏂囦欢鏍峰紡
+.upload-area {
+  padding: 15px 0;
+}
+
+.upload-container {
+
+  //鎷栨嫿鍖哄煙鏍峰紡
+  .drag-area {
+    border: 2px dashed #c0c4cc;
+    border-radius: 6px;
+    padding: 30px;
+    text-align: center;
+    transition: all 0.3s;
+    cursor: pointer;
+    position: relative;
+
+    &.drag-over {
+      border-color: #409eff;
+      background-color: rgba(64, 158, 255, 0.05);
+
+      i,
+      .el-upload__text {
+        color: #409eff;
+      }
+    }
+
+    .drag-content {
+      i {
+        font-size: 50px;
+        color: #c0c4cc;
+        margin-bottom: 15px;
+        display: block;
+      }
+
+      .el-upload__text {
+        font-size: 16px;
+        font-weight: 500;
+        color: #606266;
+      }
+
+      .upload-tip {
+        color: #909399;
+        margin: 10px 0;
+      }
+
+      .action-buttons {
+        margin-top: 15px;
+
+        .el-button {
+          margin: 0 5px;
+        }
+      }
+    }
+  }
+
+  //鐐瑰嚮閫夋嫨鍖哄煙鏍峰紡
+  display: flex;
+  gap: 20px;
+  margin-bottom: 20px;
+
+  .upload-wrapper {
+    flex: 1;
+    border: 1px dashed #dcdfe6;
+    border-radius: 4px;
+    padding: 40px 0;
+    text-align: center;
+    cursor: pointer;
+    transition: border-color 0.3s;
+
+    &:hover {
+      border-color: #409eff;
+
+      i,
+      .el-upload__text {
+        color: #409eff;
+      }
+    }
+
+    i {
+      font-size: 50px;
+      color: #8c939d;
+      margin-bottom: 15px;
+    }
+
+    .el-upload__text {
+      font-size: 14px;
+      color: #606266;
+    }
+
+    &.folder {
+      background-color: #f8faff;
+    }
+  }
+}
+
+.file-list {
+  border: 1px solid #ebeef5;
+  border-radius: 4px;
+  overflow: hidden;
+
+  .list-header {
+    display: grid;
+    grid-template-columns: 50px 1fr 80px;
+    background-color: #f5f7fa;
+    padding: 10px 15px;
+    font-weight: bold;
+    color: #606266;
+  }
+
+  .list-items {
+    max-height: 300px;
+    overflow-y: auto;
+  }
+
+  .file-item {
+    display: grid;
+    grid-template-columns: 50px 1fr 80px;
+    align-items: center;
+    padding: 10px 15px;
+    border-bottom: 1px solid #ebeef5;
+
+    &:hover {
+      background-color: #f8fafc;
+    }
+
+    .item-icon {
+      i {
+        font-size: 24px;
+
+        &.el-icon-folder {
+          color: #e6a23c;
+        }
+
+        &.el-icon-document {
+          color: #409eff;
+        }
+      }
+    }
+
+    .item-type {
+      color: #606266;
+    }
+
+    .item-name {
+      overflow: hidden;
+      text-overflow: ellipsis;
+      white-space: nowrap;
+      padding-right: 10px;
+    }
+
+    .item-action {
+      i {
+        font-size: 18px;
+        color: #f56c6c;
+        cursor: pointer;
+
+        &:hover {
+          color: #e53935;
+        }
+      }
+    }
+  }
+
+  .empty-tip {
+    text-align: center;
+    padding: 20px;
+    color: #909399;
+    font-size: 14px;
+  }
+}
+
+/* 鏂板鍏ㄥ眬鍔犺浇鏍峰紡 */
+.global-loading {
+  position: fixed;
+  top: 0;
+  left: 0;
+  right: 0;
+  bottom: 0;
+  background-color: rgba(0, 0, 0, 0.8);
+  z-index: 9999;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  
+  .loading-content {
+    text-align: center;
+    // background: white;
+    // padding: 30px 50px;
+    // border-radius: 8px;
+    // box-shadow: 0 2px 12px rgba(0, 0, 0, 0.15);
+    
+    .el-icon-loading {
+      font-size: 40px;
+      color: #409eff;
+      margin-bottom: 15px;
+    }
+    
+    p {
+      margin: 0;
+      font-size: 16px;
+      color: #606266;
+    }
+  }
+}
+</style>
\ No newline at end of file
diff --git a/src/pages/Knowledge/components/KnowledgeView copy 2.vue b/src/pages/Knowledge/components/KnowledgeView copy 2.vue
new file mode 100644
index 0000000..fd237b2
--- /dev/null
+++ b/src/pages/Knowledge/components/KnowledgeView copy 2.vue
@@ -0,0 +1,612 @@
+<template>
+  <div>
+    <div v-if="currentView === 'list'">
+      <!-- 椤堕儴鎿嶄綔鏍� -->
+      <div class="header-container">
+        <div class="search-container">
+          <el-input 
+            style="width: 200px;" 
+            v-model="TreeDataPool.searchInput" 
+            placeholder="鎼滅储" 
+            clearable 
+            @input="querySearchAsync('camera')"
+          >
+            <i class="el-icon-search el-input__icon" style="color: #dcdfe6" slot="prefix" @click="searchAreaData"></i>
+          </el-input>
+        </div>
+        <div class="button-container">
+          <el-button type="primary" @click="openDialog('create')">
+            <i class="el-icon-plus"></i> 鍒涘缓鐭ヨ瘑搴�
+          </el-button>
+        </div>
+      </div>
+
+      <!-- 閫氱敤寮圭獥缁勪欢 -->
+      <el-dialog :title="dialogTitle" :visible.sync="dialogVisible" width="600px" custom-class="custom-dialog"
+        @open="handleDialogOpen" @closed="handleDialogClose">
+        <el-form label-width="100px" :disabled="isViewMode" ref="form" :rules="formRules" :model="currentFile">
+          <el-form-item label="鍚嶇О" prop="title">
+            <el-input v-model="currentFile.title" placeholder="璇疯緭鍏ョ煡璇嗗簱鍚嶇О" />
+          </el-form-item>
+
+          <el-form-item label="鎻忚堪" prop="content">
+            <el-input type="textarea" :rows="6" v-model="currentFile.content" resize="none">
+            </el-input>
+          </el-form-item>
+        </el-form>
+
+        <span slot="footer" class="dialog-footer">
+          <el-button @click="dialogVisible = false">鍙� 娑�</el-button>
+          <el-button type="primary" @click="handleConfirm" v-if="!isViewMode">
+            纭� 瀹�
+          </el-button>
+        </span>
+      </el-dialog>
+
+      <div class="file-manager-container">
+        <div class="file-grid" v-if="files.length > 0">
+          <div v-for="(file, index) in files" :key="file.checkId" class="file-item">
+            <!-- 淇敼杩欓噷锛氫慨澶嶇偣鍑讳簨浠� -->
+            <div class="card-container" @click="handleCardClick(file, $event)">
+              <!-- 鍗$墖澶撮儴 -->
+              <div class="card-top">
+                <div class="card-top-left">
+                  <div class="card-icon"><i class="el-icon-folder"></i></div>
+                  <div class="card-name">{{ file.title }}</div>
+                </div>
+                
+                <!-- 淇敼鍚庣殑涓嬫媺鑿滃崟 - 榧犳爣绉诲叆瑙﹀彂 -->
+                <div class="card-settings" @mouseenter="showDropdown(index)" @mouseleave="hideDropdown(index)">
+                  <i class="el-icon-more"></i>
+                  <div class="dropdown-menu" v-show="activeDropdown === index">
+                    <ul>
+                      <li @click.stop="openDialog('edit', file)">
+                        <i class="el-icon-edit"></i> 缂栬緫
+                      </li>
+                      <li @click.stop="handleView(file)">
+                        <i class="el-icon-view"></i> 鏌ョ湅
+                      </li>
+                      <li @click.stop="handleDelete(file)">
+                        <i class="el-icon-delete"></i> 鍒犻櫎
+                      </li>
+                    </ul>
+                  </div>
+                </div>
+              </div>
+              
+              <!-- 鍗$墖鏍囩鍖哄煙 -->
+              <div class="card-label"></div>
+              
+              <!-- 鍗$墖鎻忚堪鍖哄煙 -->
+              <div class="card-des"></div>
+              
+              <!-- 鍗$墖搴曢儴淇℃伅 -->
+              <div class="card-bottom">
+                <div class="bottom-left">
+                  <div>{{ file.documentCount || 0 }} 鏂囨。</div>
+                  <div>{{ file.updateTime || '鏃犳洿鏂�' }}</div>
+                </div>
+                <div class="bottom-right"></div>
+              </div>
+            </div>
+          </div>
+        </div>
+
+        <!-- 鏂板绌虹姸鎬佹樉绀� -->
+        <el-empty v-else description="鏆傛棤鏁版嵁"></el-empty>
+      </div>
+      <div class="footer-container">
+        <el-pagination @current-change="handleCurrentChange" :page-size="16" layout="prev, pager, next"
+          :total="pagination.total">
+        </el-pagination>
+      </div>
+    </div>
+    <!-- 鐭ヨ瘑搴撹鎯呰鍥� -->
+    <KnowLedgeFilesView v-if="currentView === 'detail'" :knowledge-id="currentKnowledgeId" @back="handleBackToList" />
+  </div>
+</template>
+
+<script>
+import FileAPI from '@/api/KnowledgeView.ts'
+import KnowLedgeFilesView from './KnowLedgeFilesView.vue' // 寮曞叆缁勪欢
+
+export default {
+  components: {
+    KnowLedgeFilesView
+  },
+  data() {
+    return {
+      currentView: 'list', // 'list' 鎴� 'detail'
+      currentKnowledgeId: null,
+      formRules: {},
+      pagination: {
+        page: 1,
+        pageSize: 16,
+        total: 0,
+        totalPage: 1
+      },
+      dialogVisible: false,
+      dialogType: 'create',
+      currentFile: this.initFile(),
+      form: {
+        fileName: '',
+        checkContent: '',
+        rangeValue: 0
+      },
+      files: [],
+      userName: 'user', // 鐢ㄦ埛鍚嶏紝瀹為檯搴旂敤涓簲浠庣敤鎴蜂俊鎭幏鍙�
+      TreeDataPool: {
+        searchInput: ''
+      },
+      activeDropdown: -1 // 褰撳墠鏄剧ず涓嬫媺鑿滃崟鐨勫崱鐗囩储寮�
+    }
+  },
+  mounted() {
+    this.fetchFiles()
+  },
+  computed: {
+    dialogTitle() {
+      return {
+        create: '鍒涘缓鐭ヨ瘑搴�',
+        edit: '缂栬緫鐭ヨ瘑搴�',
+        view: '鐭ヨ瘑搴撹鎯�'
+      }[this.dialogType]
+    },
+    isViewMode() {
+      return this.dialogType === 'view'
+    }
+  },
+  methods: {
+    // 澶勭悊鍗$墖鐐瑰嚮浜嬩欢
+    handleCardClick(file, event) {
+      // 妫�鏌ョ偣鍑绘槸鍚﹀彂鐢熷湪璁剧疆鍥炬爣涓�
+      const isSettingsClick = event.target.closest('.card-settings');
+      
+      if (!isSettingsClick) {
+        this.handleView(file);
+      }
+    },
+    
+    // 鏄剧ず涓嬫媺鑿滃崟
+    showDropdown(index) {
+      this.activeDropdown = index;
+    },
+    
+    // 闅愯棌涓嬫媺鑿滃崟
+    hideDropdown(index) {
+      if (this.activeDropdown === index) {
+        this.activeDropdown = -1;
+      }
+    },
+    
+    handleDialogOpen() {
+      this.$nextTick(() => {
+        this.$refs.form.clearValidate()
+      })
+    },
+    handleDialogClose() {
+      this.$refs.form.resetFields()
+      this.formRules = {}
+    },
+    async fetchFiles() {
+      try {
+        const res = await FileAPI.getKnowledges({
+          page: this.pagination.page,
+          pageSize: this.pagination.pageSize
+        })
+        const totalPage = res.data.pagination.totalPage
+        const currentPage = this.pagination.page > totalPage
+          ? totalPage
+          : res.data.pagination.page
+        this.pagination = {
+          ...this.pagination,
+          page: currentPage,
+          total: res.data.pagination.total,
+          totalPage: totalPage
+        }
+        
+        // 娣诲姞妯℃嫙鏁版嵁瀛楁
+        this.files = res.data.list.map(file => {
+          return {
+            ...file,
+            documentCount: Math.floor(Math.random() * 100), // 妯℃嫙鏂囨。鏁伴噺
+            updateTime: this.formatDate(new Date()) // 妯℃嫙鏇存柊鏃堕棿
+          }
+        })
+        
+        this.pagination.total = res.data.pagination.total
+        this.pagination.totalPage = res.data.pagination.totalPage
+      } catch (error) {
+        this.$message.error('鑾峰彇鍒楄〃澶辫触')
+        console.error('API Error:', error)
+      }
+    },
+    formatDate(date) {
+      // 鏍煎紡鍖栨棩鏈熶负 YYYY-MM-DD HH:mm:ss
+      const year = date.getFullYear()
+      const month = String(date.getMonth() + 1).padStart(2, '0')
+      const day = String(date.getDate()).padStart(2, '0')
+      const hours = String(date.getHours()).padStart(2, '0')
+      const minutes = String(date.getMinutes()).padStart(2, '0')
+      const seconds = String(date.getSeconds()).padStart(2, '0')
+      return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`
+    },
+    initFile() {
+      return {
+        id: null,
+        title: '',
+        content: ''
+      }
+    },
+    openDialog(type, file = null) {
+      if (type != 'view') {
+        this.formRules = {
+          title: [
+            { required: true, message: '鏂囦欢鍚嶇О涓嶈兘涓虹┖', trigger: 'blur' }
+          ],
+          content: [
+            { required: true, message: '妫�娴嬪唴瀹逛笉鑳戒负绌�', trigger: 'blur' }
+          ]
+        }
+      }
+      this.dialogType = type
+      this.currentFile = file ? { ...file } : this.initFile()
+      this.dialogVisible = true
+    },
+    handleConfirm() {
+      this.$refs.form.validate(valid => {
+        if (valid) {
+          const operation = {
+            create: this.createFile,
+            edit: this.updateFile
+          }[this.dialogType]
+
+          operation && operation(this.currentFile)
+          this.dialogVisible = false
+        }
+      })
+    },
+    async createFile(file) {
+      try {
+        await FileAPI.createKnowledge({
+          title: file.title,
+          content: file.content
+        })
+        this.$message.success('娣诲姞鎴愬姛')
+        this.fetchFiles()
+      } catch (error) {
+        this.$message.error('娣诲姞澶辫触')
+        console.error('API Error:', error)
+      }
+    },
+    async updateFile(file) {
+      try {
+        await FileAPI.updateKnowledge({
+          id: file.id,
+          title: file.title,
+          content: file.content
+        })
+        this.$message.success('缂栬緫鎴愬姛')
+        this.fetchFiles()
+      } catch (error) {
+        this.$message.error('缂栬緫澶辫触')
+        console.error('API Error:', error)
+      }
+    },
+    handleCurrentChange(page) {
+      this.pagination.page = page
+      this.fetchFiles()
+    },
+    async handleDelete(file) {
+      this.$confirm('鍗冲皢鍒犻櫎璇ョ煡璇嗗簱鍙婂叾鎵�鏈夋枃浠讹紝鎵�鏈夊唴瀹瑰皢鏃犳硶鎵惧洖, 鏄惁缁х画?', '鎻愮ず', {
+        confirmButtonText: '纭畾',
+        cancelButtonText: '鍙栨秷',
+        type: 'warning'
+      }).then(async () => {
+        try {
+          await FileAPI.deleteKnowledgee({
+            id: file.id
+          }).then((rsp) => {
+            if (rsp && rsp.status === 200) {
+              // 鍒犻櫎鎴愬姛鍚庤嚜鍔ㄤ慨姝i〉鐮�
+              if (this.files.length === 1 && this.pagination.page > 1) {
+                this.pagination.page -= 1
+              }
+              this.fetchFiles()
+
+              this.$message({
+                type: "success",
+                message: "鍒犻櫎鎴愬姛"
+              })
+            } else {
+              this.$message({
+                type: "error",
+                message: rsp.msg
+              })
+            }
+          })
+        } catch (error) {
+          this.$message.error('鍒犻櫎澶辫触')
+          console.error('API Error:', error)
+        }
+      }).catch(() => {
+        // this.$message({
+        //   type: 'info',
+        //   message: '宸插彇娑堝垹闄�'
+        // });
+      });
+    },
+    // 澶勭悊鏌ョ湅鐭ヨ瘑搴撹鎯�
+    handleView(file) {
+      this.currentKnowledgeId = file.id
+      this.currentView = 'detail'
+    },
+    // 杩斿洖鍒楄〃鏂规硶
+    handleBackToList() {
+      this.currentView = 'list'
+    },
+    // 鎼滅储鏂规硶锛堟ā鎷燂級
+    querySearchAsync(type) {
+      console.log('Searching for:', this.TreeDataPool.searchInput)
+    },
+    searchAreaData() {
+      console.log('Search button clicked')
+    }
+  }
+}
+</script>
+<style lang="scss" scoped>
+/* 椤堕儴鎿嶄綔鏍忔牱寮� */
+.header-container {
+  display: flex;
+  justify-content: flex-end;
+  margin: 20px;
+}
+
+.search-container {
+  flex: 1;
+  max-width: 300px;
+}
+
+.button-container {
+  margin-left: 20px;
+}
+
+/* 鏂囦欢缃戞牸甯冨眬 */
+.file-grid {
+  display: grid;
+  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
+  gap: 20px;
+  padding: 0 20px;
+}
+
+/* 鍗$墖瀹瑰櫒鏍峰紡 */
+.card-container {
+  margin: 5px;
+  background: #ffffff;
+  border-radius: 8px;
+  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
+  padding: 20px;
+  height: 220px;
+  display: flex;
+  flex-direction: column;
+  transition: all 0.3s ease;
+  position: relative;
+  cursor: pointer; /* 娣诲姞鎸囬拡鏍峰紡琛ㄦ槑鍙偣鍑� */
+  
+  // &:hover {
+  //   transform: translateY(-5px);
+  //   box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
+  // }
+}
+
+/* 鍗$墖椤堕儴鍖哄煙 */
+.card-top {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  margin-bottom: 15px;
+}
+
+.card-top-left {
+  display: flex;
+  align-items: center;
+}
+
+.card-icon {
+  width: 44px;
+  height: 44px;
+  // background-color: #e6f7ff;
+  border-radius: 6px;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  margin-right: 12px;
+  
+  i {
+    font-size: 20px;
+    color: #1890ff;
+  }
+}
+
+.card-name {
+  font-size: 16px;
+  font-weight: 600;
+  color: #333;
+}
+
+/* 璁剧疆鍥炬爣 */
+.card-settings {
+  cursor: pointer;
+  padding: 5px;
+  border-radius: 4px;
+  transition: background 0.2s;
+  position: relative;
+  z-index: 2; /* 纭繚涓嬫媺鑿滃崟鍦ㄥ崱鐗囦笂鏂� */
+  
+  &:hover {
+    background: #f5f7fa;
+  }
+  
+  i {
+    font-size: 20px;
+    color: #666;
+  }
+}
+
+/* 鍗$墖鏍囩 */
+.card-label {
+  font-size: 14px;
+  // color: #1890ff;
+  // background-color: #e6f7ff;
+  padding: 4px 10px;
+  border-radius: 4px;
+  display: inline-flex;
+  align-items: center;
+  margin-bottom: 15px;
+  width: fit-content;
+}
+
+/* 鍗$墖鎻忚堪 */
+.card-des {
+  flex: 1;
+  font-size: 14px;
+  color: #666;
+  line-height: 1.5;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  display: -webkit-box;
+  -webkit-line-clamp: 3;
+  -webkit-box-orient: vertical;
+  margin-bottom: 15px;
+}
+
+/* 鍗$墖搴曢儴 */
+.card-bottom {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  margin-top: auto;
+  padding-top: 15px;
+  border-top: 1px solid #eee;
+  color: #999;
+  font-size: 13px;
+}
+
+.bottom-left {
+  display: flex;
+  gap: 15px;
+}
+
+/* 涓嬫媺鑿滃崟鏍峰紡 */
+.dropdown-menu {
+  position: absolute;
+  top: 100%;
+  right: 0;
+  z-index: 1000;
+  min-width: 100px;
+  background: #fff;
+  border-radius: 4px;
+  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.15);
+  padding: 5px 0;
+  
+  ul {
+    list-style: none;
+    padding: 0;
+    margin: 0;
+    
+    li {
+      padding: 8px 16px;
+      font-size: 14px;
+      color: #333;
+      cursor: pointer;
+      display: flex;
+      align-items: center;
+      
+      i {
+        margin-right: 8px;
+        font-size: 14px;
+      }
+      
+      &:hover {
+        background-color: #f5f7fa;
+        color: #409EFF;
+      }
+    }
+  }
+}
+
+.footer-container {
+  margin-top: 30px;
+  padding: 0 20px;
+  text-align: center;
+}
+
+/* 寮圭獥鏍峰紡 */
+:deep(.custom-dialog) {
+  border-radius: 8px;
+  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
+
+  .el-dialog__header {
+    border-bottom: 1px solid #ebeef5;
+    padding: 16px 20px;
+
+    .el-dialog__title {
+      font-size: 16px;
+      color: #303133;
+    }
+  }
+
+  .el-dialog__body {
+    padding: 20px 30px;
+  }
+
+  .dialog-input {
+    width: 80%;
+
+    .el-input__inner {
+      border-color: #dcdfe6;
+    }
+  }
+
+  .dialog-textarea {
+    .el-textarea__inner {
+      font-family: 'Microsoft YaHei', sans-serif;
+      line-height: 1.6;
+      color: #606266;
+      border-color: #dcdfe6;
+    }
+  }
+
+  .dialog-slider {
+    width: 70%;
+    margin-right: 20px;
+    flex: 1; // 婊戝潡鑷�傚簲瀹藉害
+  }
+
+  .score-value {
+    color: rgb(4, 8, 12);
+    font-weight: bold;
+    margin-right: 15px;
+  }
+
+  .dialog-footer {
+    .el-button {
+      padding: 10px 20px;
+
+      &--primary {
+        background: #409EFF;
+        border-color: #409EFF;
+      }
+    }
+  }
+}
+
+.content-pre {
+  white-space: pre-wrap;
+  word-break: break-word;
+  margin: 0;
+  font-size: 13px;
+  line-height: 1.6;
+}
+</style>
\ No newline at end of file
diff --git a/src/pages/Knowledge/components/KnowledgeView copy.vue b/src/pages/Knowledge/components/KnowledgeView copy.vue
new file mode 100644
index 0000000..67f8ae6
--- /dev/null
+++ b/src/pages/Knowledge/components/KnowledgeView copy.vue
@@ -0,0 +1,458 @@
+<template>
+  <div>
+    <div v-if="currentView === 'list'">
+      <!-- 鍒涘缓鐭ヨ瘑搴撴寜閽� -->
+      <div class="header-container">
+        <el-input style="width: 200px;margin-right: 50px;" v-model="TreeDataPool.searchInput" placeholder="鎼滅储" clearable @input="querySearchAsync('camera')">
+          <i class="el-icon-search el-input__icon" style="color: #dcdfe6" slot="prefix" @click="searchAreaData"></i>
+        </el-input>
+        <el-button type="primary" @click="openDialog('create')">
+          <i class="el-icon-plus"></i> 鍒涘缓鐭ヨ瘑搴�
+        </el-button>
+      </div>
+
+      <!-- 閫氱敤寮圭獥缁勪欢 -->
+      <el-dialog :title="dialogTitle" :visible.sync="dialogVisible" width="600px" custom-class="custom-dialog"
+        @open="handleDialogOpen" @closed="handleDialogClose">
+        <el-form label-width="100px" :disabled="isViewMode" ref="form" :rules="formRules" :model="currentFile">
+          <el-form-item label="鍚嶇О" prop="title">
+            <el-input v-model="currentFile.title" placeholder="璇疯緭鍏ョ煡璇嗗簱鍚嶇О" />
+          </el-form-item>
+
+          <el-form-item label="鎻忚堪" prop="content">
+            <el-input type="textarea" :rows="6" v-model="currentFile.content" resize="none">
+            </el-input>
+          </el-form-item>
+        </el-form>
+
+        <span slot="footer" class="dialog-footer">
+          <el-button @click="dialogVisible = false">鍙� 娑�</el-button>
+          <el-button type="primary" @click="handleConfirm" v-if="!isViewMode">
+            纭� 瀹�
+          </el-button>
+        </span>
+      </el-dialog>
+
+      <div class="file-manager-container">
+
+        <el-row v-if="files.length > 0" :gutter="20">
+          <el-col v-for="(file, index) in files" :key="file.checkId" :span="5" class="file-col">
+            <el-card class="file-card" @click.native="handleView(file)">
+              <!-- 鏂囦欢鏍囬閮ㄥ垎 -->
+              <div class="file-header">
+                <span class="file-index" hidden>{{ index + 1 }}</span>
+                <i class="el-icon-document file-icon"></i>
+                <div class="file-title">{{ file.title }}</div>
+              </div>
+
+              <!-- 鏂囦欢鎻忚堪 -->
+              <div class="file-desc">
+                <!-- {{ file.content }} -->
+              </div>
+
+              <!-- 鎿嶄綔鎸夐挳缁� -->
+              <div class="file-actions">
+                <el-button type="text" @click.stop="openDialog('edit', file)">
+                  <i class="el-icon-edit"></i> 缂栬緫
+                </el-button>|
+                <el-button type="text" @click.stop="handleView(file)"> <!-- 淇敼鏌ョ湅鎸夐挳浜嬩欢 -->
+                  <i class="el-icon-view"></i> 鏌ョ湅
+                </el-button>|
+                <el-button type="text" @click.stop="handleDelete(file)">
+                  <i class="el-icon-delete"></i> 鍒犻櫎
+                </el-button>
+              </div>
+            </el-card>
+          </el-col>
+        </el-row>
+
+        <!-- 鏂板绌虹姸鎬佹樉绀� -->
+        <el-empty v-else description="鏆傛棤鏁版嵁"></el-empty>
+
+      </div>
+      <div class="footer-container">
+        <el-pagination @current-change="handleCurrentChange" :page-size="16" layout="prev, pager, next"
+          :total="this.pagination.total">
+        </el-pagination>
+      </div>
+    </div>
+    <!-- 鐭ヨ瘑搴撹鎯呰鍥� -->
+    <KnowLedgeFilesView v-if="currentView === 'detail'" :knowledge-id="currentKnowledgeId" @back="handleBackToList" />
+  </div>
+</template>
+
+<script>
+import FileAPI from '@/api/KnowledgeView.ts'
+import KnowLedgeFilesView from './KnowLedgeFilesView.vue' // 寮曞叆缁勪欢
+
+export default {
+  components: {
+    KnowLedgeFilesView
+  },
+  data() {
+    return {
+      currentView: 'list', // 'list' 鎴� 'detail'
+      currentKnowledgeId: null,
+      formRules: {},
+      pagination: {
+        page: 1,
+        pageSize: 16,
+        total: 0,
+        totalPage: 1
+      },
+      dialogVisible: false,
+      dialogType: 'create',
+      currentFile: this.initFile(),
+      form: {
+        fileName: '',
+        checkContent: '',
+        rangeValue: 0
+      },
+      files: []
+    }
+  },
+  mounted() {
+    this.fetchFiles()
+  },
+  computed: {
+    dialogTitle() {
+      return {
+        create: '鍒涘缓鐭ヨ瘑搴�',
+        edit: '缂栬緫鐭ヨ瘑搴�',
+        view: '鐭ヨ瘑搴撹鎯�'
+      }[this.dialogType]
+    },
+    isViewMode() {
+      return this.dialogType === 'view'
+    }
+  },
+  methods: {
+    handleDialogOpen() {
+      this.$nextTick(() => {
+        this.$refs.form.clearValidate()
+      })
+    },
+    handleDialogClose() {
+      this.$refs.form.resetFields()
+      this.formRules = {}
+    },
+    async fetchFiles() {
+      try {
+        const res = await FileAPI.getKnowledges({
+          page: this.pagination.page,
+          pageSize: this.pagination.pageSize
+        })
+        const totalPage = res.data.pagination.totalPage
+        const currentPage = this.pagination.page > totalPage
+          ? totalPage
+          : res.data.pagination.page
+        this.pagination = {
+          ...this.pagination,
+          page: currentPage,
+          total: res.data.pagination.total,
+          totalPage: totalPage
+        }
+        this.files = res.data.list
+        this.pagination.total = res.data.pagination.total
+        this.pagination.totalPage = res.data.pagination.totalPage
+      } catch (error) {
+        this.$message.error('鑾峰彇鍒楄〃澶辫触')
+        console.error('API Error:', error)
+      }
+    },
+    initFile() {
+      return {
+        id: null,
+        title: '',
+        content: ''
+      }
+    },
+    openDialog(type, file = null) {
+      if (type != 'view') {
+        this.formRules = {
+          title: [
+            { required: true, message: '鏂囦欢鍚嶇О涓嶈兘涓虹┖', trigger: 'blur' }
+          ],
+          content: [
+            { required: true, message: '妫�娴嬪唴瀹逛笉鑳戒负绌�', trigger: 'blur' }
+          ]
+        }
+      }
+      this.dialogType = type
+      this.currentFile = file ? { ...file } : this.initFile()
+      this.dialogVisible = true
+    },
+    handleConfirm() {
+      this.$refs.form.validate(valid => {
+        if (valid) {
+          const operation = {
+            create: this.createFile,
+            edit: this.updateFile
+          }[this.dialogType]
+
+          operation && operation(this.currentFile)
+          this.dialogVisible = false
+        }
+      })
+    },
+    async createFile(file) {
+      try {
+        await FileAPI.createKnowledge({
+          title: file.title,
+          content: file.content
+        })
+        this.$message.success('娣诲姞鎴愬姛')
+        this.fetchFiles()
+      } catch (error) {
+        this.$message.error('娣诲姞澶辫触')
+        console.error('API Error:', error)
+      }
+    },
+    async updateFile(file) {
+      try {
+        await FileAPI.updateKnowledge({
+          id: file.id,
+          title: file.title,
+          content: file.content
+        })
+        this.$message.success('缂栬緫鎴愬姛')
+        this.fetchFiles()
+      } catch (error) {
+        this.$message.error('缂栬緫澶辫触')
+        console.error('API Error:', error)
+      }
+    },
+    handleCurrentChange(page) {
+      this.pagination.page = page
+      this.fetchFiles()
+    },
+    async handleDelete(file) {
+      this.$confirm('鍗冲皢鍒犻櫎璇ョ煡璇嗗簱鍙婂叾鎵�鏈夋枃浠讹紝鎵�鏈夊唴瀹瑰皢鏃犳硶鎵惧洖, 鏄惁缁х画?', '鎻愮ず', {
+        confirmButtonText: '纭畾',
+        cancelButtonText: '鍙栨秷',
+        type: 'warning'
+      }).then(async () => {
+        try {
+          await FileAPI.deleteKnowledgee({
+            id: file.id
+          }).then((rsp) => {
+            if (rsp && rsp.status === 200) {
+              // 鍒犻櫎鎴愬姛鍚庤嚜鍔ㄤ慨姝i〉鐮�
+              if (this.files.length === 1 && this.pagination.page > 1) {
+                this.pagination.page -= 1
+              }
+              this.fetchFiles()
+
+              this.$message({
+                type: "success",
+                message: "鍒犻櫎鎴愬姛"
+              })
+            } else {
+              this.$message({
+                type: "error",
+                message: rsp.msg
+              })
+            }
+          })
+        } catch (error) {
+          this.$message.error('鍒犻櫎澶辫触')
+          console.error('API Error:', error)
+        }
+      }).catch(() => {
+        // this.$message({
+        //   type: 'info',
+        //   message: '宸插彇娑堝垹闄�'
+        // });
+      });
+    },
+    // 鏂板锛氬鐞嗘煡鐪嬬煡璇嗗簱璇︽儏
+    handleView(file) {
+      this.currentKnowledgeId = file.id
+      this.currentView = 'detail'
+      // this.$router.push({
+      //   name: 'KnowledgeFiles',
+      //   params: { id: file.id }
+      // })
+    },
+    // 杩斿洖鍒楄〃鏂规硶
+    handleBackToList() {
+      this.currentView = 'list'
+    },
+  }
+}
+</script>
+<style lang="scss" scoped>
+/* 鏂板鎸夐挳瀹瑰櫒鏍峰紡 */
+.header-container {
+  display: flex;
+  justify-content: flex-end;
+  margin-top: 10px;
+  margin-right: 20px;
+
+
+}
+
+.footer-container {}
+
+.file-manager-container {
+  min-height: 750px;
+  padding: 20px;
+  background: #fff;
+  position: relative;
+  /* 鏂板瀹氫綅鍩哄噯 */
+
+  .new-task-btn {
+    /* 绉婚櫎缁濆瀹氫綅 */
+    position: absolute;
+    right: 30px;
+    top: 20px;
+  }
+
+  .file-col {
+    margin-bottom: 20px;
+    width: 300px;
+  }
+
+  .file-card {
+    cursor: pointer;
+    transition: all 0.3s;
+    border: 2px solid transparent;
+
+    // &.selected {
+    //   border-color: #409EFF;
+    // }
+
+    .file-header {
+      display: flex;
+      align-items: center;
+      margin-bottom: 12px;
+
+      .file-index {
+        width: 24px;
+        height: 24px;
+        background: #409EFF;
+        color: white;
+        border-radius: 50%;
+        text-align: center;
+        line-height: 24px;
+        margin-right: 8px;
+      }
+
+      .file-icon {
+        color: #409EFF;
+        font-size: 24px;
+        margin-right: 8px;
+      }
+
+      .file-title {
+        font-weight: bold;
+        overflow: hidden;
+        text-overflow: ellipsis;
+        white-space: nowrap;
+      }
+    }
+
+    .file-desc {
+      color: #666;
+      font-size: 12px;
+      line-height: 1.5; // 鏍规嵁瀹為檯瀛椾綋澶у皬璋冩暣
+      height: 3em; // 2琛� x 1.5琛岄珮 = 3em锛堟帹鑽愪娇鐢ㄧ浉瀵瑰崟浣嶏級
+      overflow: hidden;
+      text-overflow: ellipsis;
+      display: -webkit-box;
+      -webkit-line-clamp: 2;
+      -webkit-box-orient: vertical;
+      margin-bottom: 12px;
+      text-align: left;
+      // 鏂板浠ヤ笅涓よ
+      word-wrap: break-word;
+      white-space: normal; // 鎴栦娇鐢� pre-line
+
+    }
+
+    .file-actions {
+      width: 250px;
+      border-top: 1px solid #eee;
+      padding-top: 12px;
+      // text-align: right;
+
+      .el-button {
+        padding: 0 8px;
+        color: #666;
+
+        i {
+          margin-right: 4px;
+        }
+      }
+    }
+  }
+}
+
+/* 寮圭獥鏍峰紡 */
+:deep(.custom-dialog) {
+  border-radius: 8px;
+  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
+
+  .el-dialog__header {
+    border-bottom: 1px solid #ebeef5;
+    padding: 16px 20px;
+
+    .el-dialog__title {
+      font-size: 16px;
+      color: #303133;
+    }
+  }
+
+  .el-dialog__body {
+    padding: 20px 30px;
+  }
+
+  .dialog-input {
+    width: 80%;
+
+    .el-input__inner {
+      border-color: #dcdfe6;
+    }
+  }
+
+  .dialog-textarea {
+    .el-textarea__inner {
+      font-family: 'Microsoft YaHei', sans-serif;
+      line-height: 1.6;
+      color: #606266;
+      border-color: #dcdfe6;
+    }
+  }
+
+  .dialog-slider {
+    width: 70%;
+    margin-right: 20px;
+    flex: 1; // 婊戝潡鑷�傚簲瀹藉害
+  }
+
+  .score-value {
+    color: rgb(4, 8, 12);
+    font-weight: bold;
+    margin-right: 15px;
+  }
+
+  .dialog-footer {
+    .el-button {
+      padding: 10px 20px;
+
+      &--primary {
+        background: #409EFF;
+        border-color: #409EFF;
+      }
+    }
+  }
+}
+
+.content-pre {
+  white-space: pre-wrap;
+  word-break: break-word;
+  margin: 0;
+  font-size: 13px;
+  line-height: 1.6;
+}
+</style>
\ No newline at end of file
diff --git a/src/pages/Knowledge/components/KnowledgeView.vue b/src/pages/Knowledge/components/KnowledgeView.vue
new file mode 100644
index 0000000..c411a77
--- /dev/null
+++ b/src/pages/Knowledge/components/KnowledgeView.vue
@@ -0,0 +1,644 @@
+<template>
+  <div>
+    <div class="file-manager-container" v-if="currentView === 'list'">
+      <!-- 椤堕儴鎿嶄綔鏍� -->
+      <div class="header-container">
+        <div class="search-container">
+          <el-input style="width: 300px;" v-model="TreeDataPool.searchInput" placeholder="鎼滅储" clearable
+            @change="querySearchAsync()" @clear="clearList()">
+            <i class="el-icon-search el-input__icon" style="color: #dcdfe6" slot="prefix" @click="searchAreaData"></i>
+          </el-input>
+        </div>
+        <div class="button-container">
+          <el-button type="primary" @click="openDialog('create')">
+            <i class="el-icon-plus"></i> 鍒涘缓鐭ヨ瘑搴�
+          </el-button>
+        </div>
+      </div>
+
+      <!-- 閫氱敤寮圭獥缁勪欢 -->
+      <el-dialog :title="dialogTitle" :visible.sync="dialogVisible" width="600px" custom-class="custom-dialog"
+        @open="handleDialogOpen" @closed="handleDialogClose">
+        <el-form label-width="100px" :disabled="isViewMode" ref="form" :rules="formRules" :model="currentFile">
+          <el-form-item label="鍚嶇О" prop="title">
+            <el-input v-model="currentFile.title" placeholder="璇疯緭鍏ョ煡璇嗗簱鍚嶇О" />
+          </el-form-item>
+
+          <el-form-item label="鎻忚堪" prop="content">
+            <el-input type="textarea" :rows="6" v-model="currentFile.content" resize="none">
+            </el-input>
+          </el-form-item>
+        </el-form>
+
+        <span slot="footer" class="dialog-footer">
+          <el-button @click="dialogVisible = false">鍙� 娑�</el-button>
+          <el-button type="primary" @click="handleConfirm" v-if="!isViewMode">
+            纭� 瀹�
+          </el-button>
+        </span>
+      </el-dialog>
+
+      <div>
+        <div v-if="this.files.length" class="file-grid-container">
+          <div class="file-grid" v-if="files.length > 0">
+            <div v-for="(file, index) in files" :key="file.checkId" class="file-item">
+              <div class="card-container" @click="handleCardClick(file, $event)">
+                <!-- 鍗$墖澶撮儴 -->
+                <div class="card-top">
+                  <div class="card-top-left">
+                    <div class="card-icon"><i class="el-icon-folder"></i></div>
+                    <div class="card-name">{{ file.title }}</div>
+                  </div>
+
+                  <!-- 涓嬫媺鑿滃崟 -->
+                  <div class="card-settings" @mouseenter="showDropdown(index)" @mouseleave="hideDropdown(index)">
+                    <i class="el-icon-more"></i>
+                    <div class="dropdown-menu" v-show="activeDropdown === index">
+                      <ul>
+                        <li @click.stop="openDialog('edit', file)">
+                          <i class="el-icon-edit"></i> 缂栬緫
+                        </li>
+                        <!-- <li @click.stop="handleView(file)">
+                          <i class="el-icon-view"></i> 鏌ョ湅
+                        </li> -->
+                        <li @click.stop="handleDelete(file)">
+                          <i class="el-icon-delete"></i> 鍒犻櫎
+                        </li>
+                      </ul>
+                    </div>
+                  </div>
+                </div>
+
+                <!-- 鍗$墖鏍囩鍖哄煙 -->
+                <div class="card-label"></div>
+
+                <!-- 鍗$墖鎻忚堪鍖哄煙 -->
+                <div class="card-des"></div>
+
+                <!-- 鍗$墖搴曢儴淇℃伅 -->
+                <div class="card-bottom">
+                  <div class="bottom-left">
+                    <span>{{ file.documentNum || 0 }} 鏂囨。</span>&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;
+                    <span>{{ file.createTime || '鏃犳洿鏂�' }}</span>
+                  </div>
+                  <div class="bottom-right"></div>
+                </div>
+              </div>
+            </div>
+          </div>
+        </div>
+
+        <!-- 鏂板绌虹姸鎬佹樉绀� -->
+        <el-empty v-else description="鏆傛棤鏁版嵁"></el-empty>
+      </div>
+      <Pagination :total="pagination.total" :current-page.sync="pagination.page" :page-size.sync="pagination.pageSize"
+        @pagination-change="paginationChange" />
+      <!-- <div class="footer-container">
+        <el-pagination @current-change="handleCurrentChange" :page-size="16" layout="prev, pager, next"
+          :total="pagination.total">
+        </el-pagination>
+      </div> -->
+    </div>
+    <!-- 鐭ヨ瘑搴撹鎯呰鍥� -->
+    <KnowLedgeFilesView v-if="currentView === 'detail'" :knowledge-id="currentKnowledgeId" @back="handleBackToList" />
+  </div>
+</template>
+
+<script>
+import FileAPI from '@/api/KnowledgeView.ts'
+import KnowLedgeFilesView from './KnowLedgeFilesView.vue' // 寮曞叆缁勪欢
+import Pagination from '@/components/rightPagination';
+
+export default {
+  components: {
+    KnowLedgeFilesView,
+    Pagination
+  },
+  data() {
+    return {
+      currentView: 'list', // 'list' 鎴� 'detail'
+      currentKnowledgeId: null,
+      formRules: {},
+      pagination: {
+        page: 1,
+        pageSize: 20,
+        total: 0,
+        totalPage: 1
+      },
+      dialogVisible: false,
+      dialogType: 'create',
+      currentFile: this.initFile(),
+      form: {
+        fileName: '',
+        checkContent: '',
+        rangeValue: 0
+      },
+      files: [],
+      userName: 'user', // 鐢ㄦ埛鍚嶏紝瀹為檯搴旂敤涓簲浠庣敤鎴蜂俊鎭幏鍙�
+      TreeDataPool: {
+        searchInput: ''
+      },
+      activeDropdown: -1 // 褰撳墠鏄剧ず涓嬫媺鑿滃崟鐨勫崱鐗囩储寮�
+    }
+  },
+  mounted() {
+    this.fetchFiles()
+  },
+  computed: {
+    dialogTitle() {
+      return {
+        create: '鍒涘缓鐭ヨ瘑搴�',
+        edit: '缂栬緫鐭ヨ瘑搴�',
+        view: '鐭ヨ瘑搴撹鎯�'
+      }[this.dialogType]
+    },
+    isViewMode() {
+      return this.dialogType === 'view'
+    }
+  },
+  methods: {
+    // 澶勭悊鍗$墖鐐瑰嚮浜嬩欢
+    handleCardClick(file, event) {
+      // 妫�鏌ョ偣鍑绘槸鍚﹀彂鐢熷湪璁剧疆鍥炬爣涓�
+      const isSettingsClick = event.target.closest('.card-settings');
+
+      if (!isSettingsClick) {
+        this.handleView(file);
+      }
+    },
+
+    // 鏄剧ず涓嬫媺鑿滃崟
+    showDropdown(index) {
+      this.activeDropdown = index;
+    },
+
+    // 闅愯棌涓嬫媺鑿滃崟
+    hideDropdown(index) {
+      if (this.activeDropdown === index) {
+        this.activeDropdown = -1;
+      }
+    },
+
+    handleDialogOpen() {
+      this.$nextTick(() => {
+        this.$refs.form.clearValidate()
+      })
+    },
+    handleDialogClose() {
+      this.$refs.form.resetFields()
+      this.formRules = {}
+    },
+    async fetchFiles() {
+      try {
+        const res = await FileAPI.getKnowledges({
+          searchName: this.TreeDataPool.searchInput,
+          page: this.pagination.page,
+          pageSize: this.pagination.pageSize
+        })
+        const totalPage = res.data.pagination.totalPage
+        const currentPage = this.pagination.page > totalPage
+          ? totalPage
+          : res.data.pagination.page
+        this.pagination = {
+          ...this.pagination,
+          page: currentPage,
+          total: res.data.pagination.total,
+          totalPage: totalPage
+        }
+
+        // 娣诲姞妯℃嫙鏁版嵁瀛楁
+        if (res.data.list) {
+          this.files = res.data.list.map(file => {
+            return {
+              ...file,
+              // documentCount: Math.floor(Math.random() * 100), // 妯℃嫙鏂囨。鏁伴噺
+              // updateTime: this.formatDate(new Date()) // 妯℃嫙鏇存柊鏃堕棿
+              createTime: file.createTime ? this.formatDate(new Date(file.createTime)) : "" // 鏇存柊鏃堕棿
+            }
+          })
+        }else{
+          this.files=[]
+        }
+        this.pagination.total = res.data.pagination.total
+        this.pagination.totalPage = res.data.pagination.totalPage
+      } catch (error) {
+        this.$message.error('鑾峰彇鍒楄〃澶辫触')
+        console.error('API Error:', error)
+      }
+    },
+    formatDate(date) {
+      // 鏍煎紡鍖栨棩鏈熶负 YYYY-MM-DD HH:mm:ss
+      // console.log(date)
+      // console.log(new Date())
+      const year = date.getFullYear()
+      const month = String(date.getMonth() + 1).padStart(2, '0')
+      const day = String(date.getDate()).padStart(2, '0')
+      const hours = String(date.getHours()).padStart(2, '0')
+      const minutes = String(date.getMinutes()).padStart(2, '0')
+      const seconds = String(date.getSeconds()).padStart(2, '0')
+      return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`
+    },
+    initFile() {
+      return {
+        id: null,
+        title: '',
+        content: ''
+      }
+    },
+    openDialog(type, file = null) {
+      if (type != 'view') {
+        this.formRules = {
+          title: [
+            { required: true, message: '鏂囦欢鍚嶇О涓嶈兘涓虹┖', trigger: 'blur' }
+          ],
+          content: [
+            { required: true, message: '妫�娴嬪唴瀹逛笉鑳戒负绌�', trigger: 'blur' }
+          ]
+        }
+      }
+      this.dialogType = type
+      this.currentFile = file ? { ...file } : this.initFile()
+      this.dialogVisible = true
+    },
+    handleConfirm() {
+      this.$refs.form.validate(valid => {
+        if (valid) {
+          const operation = {
+            create: this.createFile,
+            edit: this.updateFile
+          }[this.dialogType]
+
+          operation && operation(this.currentFile)
+          this.dialogVisible = false
+        }
+      })
+    },
+    async createFile(file) {
+      try {
+        await FileAPI.createKnowledge({
+          title: file.title,
+          content: file.content
+        })
+        this.$message.success('娣诲姞鎴愬姛')
+        this.fetchFiles()
+      } catch (error) {
+        this.$message.error('娣诲姞澶辫触')
+        console.error('API Error:', error)
+      }
+    },
+    async updateFile(file) {
+      try {
+        await FileAPI.updateKnowledge({
+          id: file.id,
+          title: file.title,
+          content: file.content
+        })
+        this.$message.success('缂栬緫鎴愬姛')
+        this.fetchFiles()
+      } catch (error) {
+        this.$message.error('缂栬緫澶辫触')
+        console.error('API Error:', error)
+      }
+    },
+
+    async paginationChange(params) {
+      this.currentPage = params.page
+      this.pageSize = params.pageSize
+      await this.fetchFiles()
+    },
+    handleCurrentChange(page) {//鏃у垎椤�
+      this.pagination.page = page
+      this.fetchFiles()
+    },
+    async handleDelete(file) {
+      this.$confirm('鍗冲皢鍒犻櫎璇ョ煡璇嗗簱鍙婂叾鎵�鏈夋枃浠讹紝鎵�鏈夊唴瀹瑰皢鏃犳硶鎵惧洖, 鏄惁缁х画?', '鎻愮ず', {
+        confirmButtonText: '纭畾',
+        cancelButtonText: '鍙栨秷',
+        type: 'warning'
+      }).then(async () => {
+        try {
+          await FileAPI.deleteKnowledgee({
+            id: file.id
+          }).then((rsp) => {
+            if (rsp && rsp.status === 200) {
+              // 鍒犻櫎鎴愬姛鍚庤嚜鍔ㄤ慨姝i〉鐮�
+              if (this.files.length === 1 && this.pagination.page > 1) {
+                this.pagination.page -= 1
+              }
+              this.fetchFiles()
+
+              this.$message({
+                type: "success",
+                message: "鍒犻櫎鎴愬姛"
+              })
+            } else {
+              this.$message({
+                type: "error",
+                message: rsp.msg
+              })
+            }
+          })
+        } catch (error) {
+          this.$message.error('鍒犻櫎澶辫触')
+          console.error('API Error:', error)
+        }
+      }).catch(() => {
+        // this.$message({
+        //   type: 'info',
+        //   message: '宸插彇娑堝垹闄�'
+        // });
+      });
+    },
+    // 澶勭悊鏌ョ湅鐭ヨ瘑搴撹鎯�
+    handleView(file) {
+      this.currentKnowledgeId = file.id
+      this.currentView = 'detail'
+    },
+    // 杩斿洖鍒楄〃鏂规硶
+    handleBackToList() {
+      this.currentView = 'list'
+    },
+    // 鎼滅储鏂规硶锛堟ā鎷燂級
+    querySearchAsync() {
+      // console.log('Searching for:', this.TreeDataPool.searchInput)
+      this.fetchFiles()
+    },
+    clearList(){
+      this.fetchFiles()
+    },
+    searchAreaData() {
+      console.log('Search button clicked')
+    }
+  }
+}
+</script>
+<style lang="scss" scoped>
+/* 椤堕儴鎿嶄綔鏍忔牱寮� */
+.header-container {
+  display: flex;
+  justify-content: flex-end;
+  margin: 20px;
+}
+
+.search-container {
+  flex: 1;
+  max-width: 300px;
+}
+
+.button-container {
+  margin-left: 20px;
+}
+
+/* 鏂囦欢绠$悊瀹瑰櫒 - 娣诲姞妯悜婊氬姩 */
+.file-manager-container {
+  overflow-x: auto;
+  padding-bottom: 100px;
+  /* 涓烘粴鍔ㄦ潯鐣欏嚭绌洪棿 */
+}
+
+/* 鏂囦欢缃戞牸瀹瑰櫒 - 璁剧疆鏈�灏忓搴� */
+.file-grid-container {
+  min-width: 1480px;
+  /* 5 * 280px + 4 * 20px = 1400 + 80 = 1480px */
+  padding: 0 20px;
+}
+
+/* 鏂囦欢缃戞牸甯冨眬 */
+.file-grid {
+  display: grid;
+  grid-template-columns: repeat(5, minmax(280px, 1fr));
+  /* 鍥哄畾5鍒楋紝鏈�灏忓搴�280px */
+  gap: 20px;
+  width: 100%;
+}
+
+/* 鍗$墖瀹瑰櫒鏍峰紡 */
+.card-container {
+  background: #ffffff;
+  border-radius: 8px;
+  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
+  padding: 20px;
+  height: 180px;
+  display: flex;
+  flex-direction: column;
+  transition: all 0.3s ease;
+  position: relative;
+  cursor: pointer;
+
+  &:hover {
+    // transform: translateY(-5px);
+    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
+  }
+}
+
+/* 鍗$墖椤堕儴鍖哄煙 */
+.card-top {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  margin-bottom: 15px;
+}
+
+.card-top-left {
+  display: flex;
+  align-items: center;
+}
+
+.card-icon {
+  width: 44px;
+  height: 44px;
+  // background-color: #e6f7ff;
+  border-radius: 6px;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  margin-right: 12px;
+
+  i {
+    font-size: 20px;
+    color: #1890ff;
+  }
+}
+
+.card-name {
+  font-size: 16px;
+  font-weight: 600;
+  color: #333;
+}
+
+/* 璁剧疆鍥炬爣 */
+.card-settings {
+  cursor: pointer;
+  padding: 5px;
+  border-radius: 4px;
+  transition: background 0.2s;
+  position: relative;
+  z-index: 10;
+  /* 纭繚涓嬫媺鑿滃崟鍦ㄥ崱鐗囦笂鏂� */
+
+  &:hover {
+    background: #f5f7fa;
+  }
+
+  i {
+    font-size: 20px;
+    color: #666;
+  }
+}
+
+/* 鍗$墖鏍囩 */
+.card-label {
+  font-size: 14px;
+  // color: #1890ff;
+  // background-color: #e6f7ff;
+  padding: 4px 10px;
+  border-radius: 4px;
+  display: inline-flex;
+  align-items: center;
+  margin-bottom: 15px;
+  width: fit-content;
+}
+
+/* 鍗$墖鎻忚堪 */
+.card-des {
+  flex: 1;
+  font-size: 14px;
+  color: #666;
+  line-height: 1.5;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  display: -webkit-box;
+  -webkit-line-clamp: 3;
+  -webkit-box-orient: vertical;
+  margin-bottom: 15px;
+}
+
+/* 鍗$墖搴曢儴 */
+.card-bottom {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  margin-top: auto;
+  padding-top: 15px;
+  border-top: 1px solid #eee;
+  color: #999;
+  font-size: 13px;
+}
+
+.bottom-left {
+  // display: flex;
+  // gap: 15px;
+}
+
+/* 涓嬫媺鑿滃崟鏍峰紡 */
+.dropdown-menu {
+  position: absolute;
+  top: 100%;
+  right: 0;
+  z-index: 1000;
+  min-width: 100px;
+  background: #fff;
+  border-radius: 4px;
+  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.15);
+  padding: 5px 0;
+
+  ul {
+    list-style: none;
+    padding: 0;
+    margin: 0;
+
+    li {
+      padding: 8px 16px;
+      font-size: 14px;
+      color: #333;
+      cursor: pointer;
+      display: flex;
+      align-items: center;
+
+      i {
+        margin-right: 8px;
+        font-size: 14px;
+      }
+
+      &:hover {
+        background-color: #f5f7fa;
+        color: #409EFF;
+      }
+    }
+  }
+}
+
+.footer-container {
+  margin-top: 30px;
+  padding: 0 20px;
+  text-align: center;
+}
+
+/* 寮圭獥鏍峰紡 */
+:deep(.custom-dialog) {
+  border-radius: 8px;
+  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
+
+  .el-dialog__header {
+    border-bottom: 1px solid #ebeef5;
+    padding: 16px 20px;
+
+    .el-dialog__title {
+      font-size: 16px;
+      color: #303133;
+    }
+  }
+
+  .el-dialog__body {
+    padding: 20px 30px;
+  }
+
+  .dialog-input {
+    width: 80%;
+
+    .el-input__inner {
+      border-color: #dcdfe6;
+    }
+  }
+
+  .dialog-textarea {
+    .el-textarea__inner {
+      font-family: 'Microsoft YaHei', sans-serif;
+      line-height: 1.6;
+      color: #606266;
+      border-color: #dcdfe6;
+    }
+  }
+
+  .dialog-slider {
+    width: 70%;
+    margin-right: 20px;
+    flex: 1; // 婊戝潡鑷�傚簲瀹藉害
+  }
+
+  .score-value {
+    color: rgb(4, 8, 12);
+    font-weight: bold;
+    margin-right: 15px;
+  }
+
+  .dialog-footer {
+    .el-button {
+      padding: 10px 20px;
+
+      &--primary {
+        background: #409EFF;
+        border-color: #409EFF;
+      }
+    }
+  }
+}
+
+.content-pre {
+  white-space: pre-wrap;
+  word-break: break-word;
+  margin: 0;
+  font-size: 13px;
+  line-height: 1.6;
+}
+</style>
\ No newline at end of file
diff --git a/src/pages/Knowledge/index/App.vue b/src/pages/Knowledge/index/App.vue
new file mode 100644
index 0000000..049d2c2
--- /dev/null
+++ b/src/pages/Knowledge/index/App.vue
@@ -0,0 +1,131 @@
+<template>
+  <div class="column">
+    <div class="column-right">
+       <know-view ref="cardlist"/>
+    </div>
+  </div>
+</template>
+
+<script>
+import { getUrlKey } from "@/api/utils";
+import KnowView from "../components/KnowledgeView";
+
+export default {
+  name: "VideoManage",
+  components: {
+    KnowView
+  },
+  computed: {
+    app() {
+      return getUrlKey("dataStack") !== null ? "DataStack" : "Camera";
+    },
+  },
+  data() {
+    return {
+      leftWith: 0,
+      screenHeight: 0,
+    };
+  },
+  mounted() {
+    this.screenHeight = document.documentElement.clientHeight;
+    window.onresize = () => {
+      return (() => {
+        this.screenHeight = document.documentElement.clientHeight;
+      })();
+    };
+
+    this.leftWith = this.$refs["left"].offsetWidth;
+    this.TreeDataPool.readonly = false;
+    this.TreeDataPool.gbReadonly = false;
+    this.DataStackPool.readonly = false;
+  },
+  methods: {
+    changeTrainId(trainId){
+      if (this.$refs.cardlist) {
+        this.$refs.cardlist.changeTrainId(trainId);
+      }
+    }
+  },
+};
+</script>
+
+<style lang="scss" scoped>
+.column {
+  overflow: hidden;
+  //min-width: 1399px;
+  // min-width: 1920px;
+  height: 100%;
+}
+.column-right {
+  padding: 5px;
+  height: 100vh;
+  background-color: #eee;
+  box-sizing: border-box;
+  overflow: scroll;
+}
+.heigher-index {
+  position: absolute;
+  top: 0;
+  z-index: 10;
+  width: 100%;
+  height: 100%;
+}
+.resize-save {
+  position: absolute;
+  top: 0;
+  right: 5px;
+  bottom: 0;
+  left: 0;
+  padding: 16px;
+  padding-top: 8px;
+  overflow-x: hidden;
+  overflow-y: auto;
+}
+.resize-bar {
+  width: 338px;
+  height: inherit;
+  resize: horizontal;
+  cursor: ew-resize;
+  opacity: 0;
+  overflow: scroll;
+  max-width: 500px; //璁惧畾鏈�澶ф媺浼搁暱搴�
+  min-width: 33px; //璁惧畾鏈�灏忓搴�
+}
+/* 鎷栨嫿绾� */
+.resize-line {
+  position: absolute;
+  right: 0;
+  top: 0;
+  bottom: 0;
+  border-right: 2px solid #efefef;
+  border-left: 1px solid #e0e0e0;
+  pointer-events: none;
+}
+.resize-bar:hover ~ .resize-line,
+.resize-bar:active ~ .resize-line {
+  border-left: 1px dashed skyblue;
+}
+.resize-bar::-webkit-scrollbar {
+  width: 200px;
+  height: inherit;
+}
+
+/* Firefox鍙湁涓嬮潰涓�灏忓潡鍖哄煙鍙互鎷変几 */
+@supports (-moz-user-select: none) {
+  .resize-bar:hover ~ .resize-line,
+  .resize-bar:active ~ .resize-line {
+    border-left: 1px solid #bbb;
+  }
+  .resize-bar:hover ~ .resize-line::after,
+  .resize-bar:active ~ .resize-line::after {
+    content: "";
+    position: absolute;
+    width: 16px;
+    height: 16px;
+    bottom: 0;
+    right: -8px;
+    // background: url(./resize.svg);
+    background-size: 100% 100%;
+  }
+}
+</style>
diff --git a/src/pages/Knowledge/index/main.ts b/src/pages/Knowledge/index/main.ts
new file mode 100644
index 0000000..aa3df71
--- /dev/null
+++ b/src/pages/Knowledge/index/main.ts
@@ -0,0 +1,30 @@
+import Vue from "vue";
+import App from './App.vue';
+
+import ElementUI from 'element-ui';
+import 'element-ui/lib/theme-chalk/index.css';
+// import "@/assets/css/element-variables.scss";
+
+import ToggleButton from 'vue-js-toggle-button';
+import VueAwesomeSwiper from "vue-awesome-swiper";
+import "swiper/dist/css/swiper.css";
+import * as VueWindow from "@hscmap/vue-window";
+import moment from 'moment';
+import Mixin from "./mixins";
+
+Vue.prototype.$moment = moment;
+Vue.use(ElementUI);
+Vue.use(ToggleButton);
+Vue.use(VueAwesomeSwiper as any);
+Vue.use(VueWindow);
+Vue.filter('moment', function (value, formatString) {
+  formatString = formatString || 'YYYY-MM-DD HH:mm:ss';
+  return moment(value).format(formatString);
+
+});
+Vue.mixin(Mixin);
+
+new Vue({
+  el: '#app',
+  render: h => h(App)
+})
diff --git a/src/pages/Knowledge/index/mixins.ts b/src/pages/Knowledge/index/mixins.ts
new file mode 100644
index 0000000..52fb92b
--- /dev/null
+++ b/src/pages/Knowledge/index/mixins.ts
@@ -0,0 +1,25 @@
+import TreeDataPool from "@/Pool/TreeData";
+import DataStackPool from "@/Pool/dataStack"
+import DataPool from "@/Pool/PollData"
+import VideoManageData from "@/Pool/VideoManageData";
+import TaskMange from '@/Pool/TaskMange'
+
+/* eslint-disable */
+const onlyTreeDataPool = new TreeDataPool
+const onlyDataStack = new DataStackPool
+const onlyDataPool = new DataPool
+const onlyVideoManageData = new VideoManageData
+const onlyTaskMange = new TaskMange
+
+const mixin = {
+  data() {
+    return {
+      TreeDataPool: onlyTreeDataPool,
+      DataStackPool: onlyDataStack,
+      VideoManageData: onlyVideoManageData,
+      TaskMange: onlyTaskMange,
+      PollData: onlyDataPool
+    };
+  },
+};
+export default mixin;
\ No newline at end of file
diff --git a/src/pages/cameraAccess/components/SceneRule.vue b/src/pages/cameraAccess/components/SceneRule.vue
index fba6762..9cea7d0 100644
--- a/src/pages/cameraAccess/components/SceneRule.vue
+++ b/src/pages/cameraAccess/components/SceneRule.vue
@@ -12,8 +12,7 @@
           <el-form-item label="鍥炬爣">
             <!-- 鍥剧墖棰勮 -->
             <div class="icon-preview-container">
-              <el-image v-if="sceneForm.iconUrl"
-                :src="sceneForm.iconUrl + '?t=' + timestamp"></el-image>
+              <el-image v-if="sceneForm.iconUrl" :src="sceneForm.iconUrl + '?t=' + timestamp"></el-image>
               <!-- <el-image :src="sceneForm.iconUrl?'http://192.168.1.235:7009'+sceneForm.iconUrl + '?t=' + timestamp:'http://192.168.1.235:7009/opt/smart/icon/task_icon.png'" fit="cover" /> -->
               <img v-else src="@/assets/img/绌虹櫧.png" fit="cover" />
               <!-- <img style="width: 60px;" v-else src="@/assets/img/瀹瑰櫒@1x.png" /> -->
@@ -63,9 +62,13 @@
               @rule-selected="handleRuleSelect" @rule-created="handleRuleCreate" />
           </el-form-item>
           <!-- 鐭ヨ瘑搴� -->
-          <el-form-item label="鍏宠仈鐭ヨ瘑搴�" size="mini">
-            <el-cascader v-model="sceneForm.knowsList" :options="VideoManageData.knowsList" :props="knowledgeProps"
-              clearable filterable placeholder="璇烽�夋嫨" class="knowledge-cascader" :show-all-levels="false"></el-cascader>
+          <el-form-item label="鍏宠仈鐭ヨ瘑搴�">
+            <!-- <el-cascader size="mini" v-model="sceneForm.knowsList" :options="VideoManageData.knowsList" :props="knowledgeProps"
+              clearable filterable placeholder="璇烽�夋嫨" class="knowledge-cascader" :show-all-levels="false"></el-cascader> -->
+            <el-select v-model="sceneForm.knowsList" placeholder="璇烽�夋嫨" size="mini" style="width: 250px" multiple>
+              <el-option v-for="item in VideoManageData.knowsList" :key="item.id" :label="item.title" :value="item.id">
+              </el-option>
+            </el-select>
           </el-form-item>
           <el-form-item label="澶囨敞">
             <el-input v-model="sceneForm.desc" type="textarea" size="mini"></el-input>
@@ -162,7 +165,8 @@
           </el-table-column>
           <el-table-column label="鍏宠仈鐭ヨ瘑搴�" prop="knowledge" align="center">
             <template slot-scope="scope">
-              {{(scope.row.knowledge || []).map(r => r.fileName).join(' / ') || ''}}
+              <!-- {{(scope.row.knowledge || []).map(r => r.fileName).join(' / ') || ''}} -->
+              {{(scope.row.knowledge || []).map(r => r.title).join(' / ') || ''}}
             </template>
           </el-table-column>
           <el-table-column label="澶囨敞" prop="desc" align="center" min-width="120"></el-table-column>
@@ -552,16 +556,16 @@
       //     labelName: timeOption ? timeOption.name : ''
       //   }
       // })
-      let fileIds = []
-      if (this.sceneForm.knowsList) {
-        fileIds = this.sceneForm.knowsList.map(
-          path => {
-            // 鎻愬彇鏈�鍚庝竴绾х殑鏂囦欢ID骞惰浆鎹负鏁板瓧
-            const id = path[path.length - 1];
-            return Number(id); // 鎴栬�呬娇鐢� parseInt(id) 鎴� +id
-          }
-        )
-      }
+      // let fileIds = []
+      // if (this.sceneForm.knowsList) {
+      //   fileIds = this.sceneForm.knowsList.map(
+      //     path => {
+      //       // 鎻愬彇鏈�鍚庝竴绾х殑鏂囦欢ID骞惰浆鎹负鏁板瓧
+      //       const id = path[path.length - 1];
+      //       return Number(id); // 鎴栬�呬娇鐢� parseInt(id) 鎴� +id
+      //     }
+      //   )
+      // }
       this.sceneForm.taskName = this.sceneForm.scene_name
       this.sceneForm.eventLevel = this.sceneForm.alarm_level
       // this.sceneForm.checks = this.sceneForm.checkContents
@@ -569,7 +573,8 @@
       this.sceneForm.rules = this.sceneForm.warningRules
       // this.sceneForm.workTimes = workTimes
       this.sceneForm.taskDescription = this.sceneForm.desc
-      this.sceneForm.knows = fileIds,
+      // this.sceneForm.knows = fileIds,
+      this.sceneForm.knows = this.sceneForm.knowsList,
         this.sceneForm.createUser = this.userInfo.id
       this.sceneForm.type = this.isGb28182 ? 1 : 0
       // console.info(this.sceneForm)
diff --git a/src/pages/cameraAccess/components/ruleSelect/ruleSelect.vue b/src/pages/cameraAccess/components/ruleSelect/ruleSelect.vue
index 7ef2101..6c3d5cf 100644
--- a/src/pages/cameraAccess/components/ruleSelect/ruleSelect.vue
+++ b/src/pages/cameraAccess/components/ruleSelect/ruleSelect.vue
@@ -1,6 +1,6 @@
 <template>
   <div class="rule-selector">
-    <el-autocomplete v-model="inputValue" :fetch-suggestions="querySearch" placeholder="涓�鍙ヨ瘽鐢熸垚绠楁硶"
+    <el-autocomplete size="mini" v-model="inputValue" :fetch-suggestions="querySearch" placeholder="涓�鍙ヨ瘽鐢熸垚绠楁硶"
       :trigger-on-focus="true" value-key="fileName" @select="handleSelect" @blur="handleBlur" clearable
       @clear="handleClear"
       class="rule-input">
diff --git a/src/pages/datapush/index/RightEvent copy 2.vue b/src/pages/datapush/index/RightEvent copy 2.vue
new file mode 100644
index 0000000..f816a59
--- /dev/null
+++ b/src/pages/datapush/index/RightEvent copy 2.vue
@@ -0,0 +1,950 @@
+<template>
+  <div class="s-event-push-right">
+    <div class="s-right-config">
+      <el-form>
+        <el-form-item label="鍚嶇О">
+          <el-input v-model="taskEditData.name" placeholder="璇疯緭鍏ュ悕绉�" size="small" style="width: 400px"></el-input>
+        </el-form-item>
+
+        <el-form-item label="鏃堕棿">
+          <el-date-picker v-model="taskEditData.time" format="yyyy-MM-dd HH:mm:ss" value-format="yyyy-MM-dd HH:mm:ss"
+            type="datetimerange" range-separator="鑷�" start-placeholder="寮�濮嬫棩鏈�" end-placeholder="缁撴潫鏃ユ湡"
+            size="small"></el-date-picker>
+        </el-form-item>
+
+
+        <div>
+          <span style="line-height: 38px;margin-right: 20px;">鎺ㄩ�佹柟寮�</span>
+          <el-radio v-model="taskEditData.pushType" label="1">UDP</el-radio>
+          <el-radio v-model="taskEditData.pushType" label="2">HTTP</el-radio>
+          <el-radio disabled v-model="taskEditData.pushType" label="3">MQTT</el-radio>
+        </div>
+        <span style="line-height: 38px">鎺ㄩ�佹湇鍔″櫒</span>
+        <div class="icon-btn" v-if="urls.length < 1" @click="addUrl()">
+          <i class="el-icon-circle-plus-outline"></i>
+          <span>&nbsp;娣诲姞鎺ュ彛鍦板潃</span>
+        </div>
+        <div v-for="(item, index) in urls" :key="item.hash" class="flex-box server-url">
+          <div>
+            <el-checkbox v-model="item.enable"></el-checkbox>
+            <span v-if="taskEditData.pushType === '1'" class="ml20">{{ "鏈嶅姟鍣�&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;" }}</span>
+            <span v-else class="ml20">{{ "URL&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;" }}</span>
+            <el-input v-if="taskEditData.pushType === '1'" v-model="item.server_ip"
+              style="width: 180px; margin-left: 0px;margin-right: 30px" size="small"
+              placeholder="192.168.1.100"></el-input>
+            <span v-if="taskEditData.pushType === '1'">绔彛</span>
+            <el-input v-if="taskEditData.pushType === '1'" v-model="item.port" style="width: 70px; margin-left: 10px"
+              size="small" placeholder="8030"></el-input>
+            <el-input v-if="taskEditData.pushType === '2'" v-model="item.url" style="width: 360px; margin-left: 0px"
+              size="small" placeholder="http://10.10.10.10:8000/dataApi"></el-input>
+            <!-- <el-input v-if="taskEditData.pushType === '3'" v-model="item.url" style="width: 360px; margin-left: 0px" size="small"
+              placeholder="MQTT"></el-input> -->
+          </div>
+          <div class="server-add">
+            <i class="el-icon-remove-outline" @click="delUrl(index)" style="color: red; margin-right: 10px" />
+            <i class="el-icon-circle-plus-outline" @click="addUrl()"></i>
+          </div>
+        </div>
+
+        <el-form-item label="鑱斿姩鏂瑰紡" style="margin-top: 20px; width: 100">
+          <el-select v-model="taskEditData.lineWay" placeholder="璇烽�夋嫨" size="small">
+            <el-option label="璇烽�夋嫨" value=""></el-option>
+            <el-option v-for="item in taskEditData.lineOptions" :key="item.value" :label="item.label"
+              :value="item.value"></el-option>
+          </el-select>
+        </el-form-item>
+
+        <el-form-item label="鏍囩">
+          <el-radio v-model="taskEditData.radioValue" label="1">婊¤冻鍏ㄩ儴</el-radio>
+          <el-radio v-model="taskEditData.radioValue" label="2">婊¤冻浠绘剰涓�涓�</el-radio>
+        </el-form-item>
+      </el-form>
+    </div>
+    <div class="s-right-mid"></div>
+    <div class="s-right-rule">
+      <div class="rule-title">
+        <b style="margin-right: 20px">浠诲姟閰嶇疆</b>
+        <div class="icon-btn" v-if="dataList.length === 0" @click="createSet">
+          <i class="el-icon-circle-plus-outline"></i>
+          <span>&nbsp;鏂板</span>
+        </div>
+        <div class="icon-btn" v-if="dataList.length > 0" @click="cleanSet">
+          <i class="el-icon-remove-outline"></i>
+          <span>&nbsp;娓呯┖</span>
+        </div>
+      </div>
+
+      <div v-for="(rule, index) in dataList" :key="index" style="margin-top: 10px">
+        <el-row :gutter="20">
+          <!-- 涓婚 -->
+          <el-col :span="4">
+            <el-select v-model="rule.topic_type" placeholder="璇烽�夋嫨" @change="selectTopic(rule, true)" size="small">
+              <el-option v-for="item in rule.topicTypeOptions" :key="item.id" :label="item.name"
+                :value="item.value"></el-option>
+            </el-select>
+          </el-col>
+
+          <!-- 杩囨护鍊� -->
+          <el-col :span="4">
+            <el-select v-model="rule.topic_arg" placeholder="璇烽�夋嫨" @change="selectArg(rule, true)" size="small">
+              <el-option v-for="item in rule.topicArgOptions" :key="item.id" :label="item.name"
+                :value="item.value"></el-option>
+            </el-select>
+          </el-col>
+
+          <!-- 鎿嶄綔绗� -->
+          <el-col :span="4">
+            <el-select v-model="rule.operator" placeholder="璇烽�夋嫨" size="small">
+              <el-option label="==" value="="></el-option>
+            </el-select>
+          </el-col>
+
+          <!-- 鍊肩被鍨� -->
+          <el-col :span="4">
+            <el-select v-model="rule.operator_type" placeholder="璇烽�夋嫨" @change="selectOperator(rule, true)" size="small">
+              <el-option v-for="item in rule.operatorTypeOpionts" :key="item.id" :label="item.name"
+                :value="item.value"></el-option>
+            </el-select>
+          </el-col>
+
+          <!-- 杩囨护鍊� -->
+          <el-col :span="4">
+            <div v-if="rule.operator_type === 'custom'">
+              <el-input v-model="rule.rule_value" placeholder="璇疯緭鍏ュ唴瀹�" size="small"></el-input>
+            </div>
+            <div v-else>
+              <el-select v-model="rule.rule_values" multiple collapse-tags placeholder="璇烽�夋嫨" size="small"
+                @change="selectValue(rule, $event)">
+                <el-option v-for="item in rule.ruleValueOptions" :key="item.id" :label="item.name"
+                  :disabled="item.disabled" :value="item.value"></el-option>
+              </el-select>
+            </div>
+          </el-col>
+          <el-col :span="4">
+            <div class="rule-edit-btn">
+              <i v-show="dataList.length > 1" class="el-icon-remove-outline" @click="delRule(index)"
+                style="color: red; margin-right: 10px" />
+              <i v-show="index === dataList.length - 1" class="el-icon-circle-plus-outline" @click="addRule()"
+                style="color: #3d68e1"></i>
+            </div>
+          </el-col>
+        </el-row>
+        <el-row></el-row>
+      </div>
+
+      <div class="rule-title2">
+        <b>瑙勫垯</b>
+        <div class="div-border" v-html="taskEditData.eventTxt"></div>
+      </div>
+      <div class="config-item">
+        <b>鎺ㄩ�佸瓧娈�</b>
+        <el-button v-if="taskEditData.pushType === '1'" type="primary" size="mini"
+          @click="openPushImsDialog">鏌ョ湅</el-button>
+        <el-button v-else type="primary" size="mini" @click="openPushSetDialog">璁剧疆</el-button>
+      </div>
+      <div class="save-btn">
+        <el-button type="info" size="small" @click="onCancle" style="color: #222">鍙栨秷</el-button>
+        <el-button type="primary" @click="eventPushsSave" size="small">淇濆瓨</el-button>
+      </div>
+    </div>
+    <el-dialog :visible="pushImageDialog" :append-to-body="false" :close-on-click-modal="false"
+      class="dialog-push-field" @close="pushImageDialog = false">
+      <!-- <el-image fit="fill" src="https://fuss10.elemecdn.com/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg"></el-image> -->
+      <img src="@/assets/img/UDP閰嶇疆.png" style="width: 100%;">
+    </el-dialog>
+    <el-dialog :visible="pushFieldDialog" :append-to-body="false" :close-on-click-modal="false"
+      class="dialog-push-field" @close="pushFieldDialog = false">
+      <div slot="title" class="slot-title">
+        <p>璇烽�夋嫨鎯宠鎺ㄩ�佺殑瀛楁</p>
+        <div class="right">
+          <el-checkbox v-model="allFieldChecked" @change="allCheckChange"></el-checkbox>
+        </div>
+      </div>
+      <div class="check-area" v-for="configObj in tempPushSet" :key="configObj.id">
+        <div class="header">
+          <div class="title">{{ configObj.name }}</div>
+          <div class="right">
+            <el-checkbox v-model="configObj.checked" @change="toggleConfigCheck(configObj)">鍏ㄩ��</el-checkbox>
+          </div>
+        </div>
+        <div class="flex-box flex-wrap">
+          <div class="param flex-box" v-for="param in configObj.children" :key="param.id">
+            <el-checkbox v-model="param.checked" @change="checkChildren"></el-checkbox>
+            <span class="param-name">{{ param.name }}</span>
+            <el-input v-model="param.alias" size="mini" :ref="`input_${param.id}`" @input="varifyField(param)" :style="{
+              color: param.error ? 'red' : '',
+              borderColor: param.error ? 'red' : '',
+            }"></el-input>
+          </div>
+        </div>
+      </div>
+      <div slot="footer" class="text-center">
+        <el-button size="small" @click="canclePushFieldSet">鍙栨秷</el-button>
+        <el-button size="small" type="primary" :disabled="disabledPushFieldSet"
+          @click="submitPushFieldSet">淇濆瓨</el-button>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+<script>
+import { eventPushsSave, findByEventTopic, getPushSet } from "@/api/event";
+import { findDictionaryByType, findDictionaryByID } from "@/api/dictionary";
+import { getTaskList } from "@/api/search";
+
+export default {
+  name: "rightEvent",
+  props: {
+    eventObject: {
+      type: Object,
+      default: () => {
+        return {};
+      },
+    },
+  },
+  computed: {
+    urls() {
+      return this.taskEditData.urls;
+    },
+  },
+  data() {
+    return {
+      taskEditData: {},
+      dataList: [],
+      dictionary: [],
+      cameras: [],
+      tasks: [],
+      tables: [],
+      baseRule: {
+        event_push_id: "",
+        id: "",
+        operator: "==",
+        operator_type: "",
+        rule_value: "",
+        rule_values: [],
+        topic_arg: "",
+        topic_type: "",
+        topicTypeOptions: {},
+        topicArgOptions: {},
+        operatorOptions: {},
+        operatorTypeOpionts: {},
+        ruleValueOptions: [],
+      },
+      pushFieldDialog: false,
+      pushImageDialog: false,
+      tempPushSet: [],
+      pushFields: [],
+      allFieldChecked: false,
+      disabledPushFieldSet: true,
+    };
+  },
+  watch: {
+    eventObject: {
+      handler(newVal, oldVal) {
+        this.taskEditData.enable = this.eventObject.enable;
+        if (newVal !== oldVal) {
+          if (this.taskEditData.id !== newVal.id) {
+            this.dataList = [];
+
+            this.taskEditData.id = newVal.id;
+            this.taskEditData.name = newVal.name;
+            this.taskEditData.time = [
+              this.eventObject.time_start,
+              this.eventObject.time_end,
+            ];
+            this.taskEditData.serverIp = newVal.ip_ports;
+            this.taskEditData.urls = newVal.urls;
+            this.taskEditData.lineWay = newVal.link_type;
+            this.taskEditData.eventTxt = newVal.rule_text;
+            this.taskEditData.radioValue = newVal.is_satisfy_all ? "1" : "2";
+            this.taskEditData.pushType = newVal.push_type + ""
+
+            if (!this.taskEditData.urls) {
+              this.$set(this.taskEditData, "urls", []);
+            }
+            //this.taskEditData.push_set = this.eventObject.push_set;
+            if (!this.eventObject.push_set.length) {
+              this.$set(this.taskEditData, "push_set", this.pushFields);
+            } else {
+              this.$set(
+                this.taskEditData,
+                "push_set",
+                this.eventObject.push_set
+              );
+            }
+            if (newVal.rules) {
+              newVal.rules.forEach((element) => {
+                let newRule = Object.assign(
+                  JSON.parse(JSON.stringify(this.baseRule)),
+                  element
+                );
+                this.dataList.push(newRule);
+                this.selectTopic(newRule);
+                this.selectOperator(newRule);
+              });
+            }
+          }
+        }
+      },
+      deep: true,
+    },
+    tempPushSet: {
+      handler(n, o) {
+        let _this = this;
+        let flag = false;
+        n.forEach((configObj) => {
+          let notChecked = configObj.children.find((param) => !param.checked);
+          if (!notChecked) {
+            configObj.checked = true;
+          } else {
+            configObj.checked = false;
+          }
+          let someoneChecked = configObj.children.find(
+            (param) => param.checked
+          );
+          if (someoneChecked) {
+            flag = true;
+          }
+        });
+        if (flag) {
+          this.disabledPushFieldSet = false;
+        } else {
+          this.disabledPushFieldSet = true;
+        }
+      },
+      deep: true,
+    },
+  },
+  created() {
+    this.reAdd();
+  },
+  mounted() {
+    // 鍔犺浇瀛楀吀
+    this.findByType();
+    this.getCameras();
+    this.getTasks();
+    this.getPushFields();
+  },
+  methods: {
+    openPushSetDialog() {
+      this.pushFieldDialog = true;
+      this.tempPushSet = JSON.parse(JSON.stringify(this.taskEditData.push_set));
+      this.checkFlag();
+    },
+    openPushImsDialog() {
+      this.pushImageDialog = true;
+    },
+    checkFlag() {
+      // debugger
+      let flag = true;
+      this.tempPushSet.forEach((item) => {
+        if (item.checked == false) {
+          flag = false;
+        }
+      });
+      this.allFieldChecked = flag;
+    },
+    checkChildren(val) {
+      console.log(val, 12121);
+      if (val == false) {
+        this.allFieldChecked = false;
+      } else if (val == true && this.allFieldChecked == false) {
+        this.$nextTick(() => {
+          this.checkFlag();
+        });
+      }
+    },
+    varifyField(param) {
+      var reg = /^[A-Za-z]+[0-9-_]?$/;
+      if (!reg.test(param.alias)) {
+        this.$message("璇疯緭鍏ュ悎娉曞瓧娈靛悕");
+        param.error = true;
+      } else {
+        param.error = false;
+      }
+      // this.pushFields.forEach(configObj => {
+      //   configObj.children.find(param => param.error)
+      // })
+    },
+    canclePushFieldSet() {
+      this.pushFieldDialog = false;
+    },
+    allCheckChange(val) {
+      this.tempPushSet.forEach(function (item) {
+        item.checked = val;
+        item.children.forEach(function (child) {
+          child.checked = val;
+        });
+      });
+    },
+    submitPushFieldSet() {
+      let flag = false;
+      //this.pushFields.forEach(configObj => {
+      this.tempPushSet.forEach((configObj) => {
+        let errorOne = configObj.children.find(
+          (param) => param.checked && param.error
+        );
+        if (errorOne) {
+          this.$notify({
+            type: "error",
+            message: "璇峰皢閫変腑瀛楁杈撳叆鍚堟硶瀛楁鍚�",
+          });
+          flag = true;
+        }
+      });
+      if (flag) {
+        //NO SUBMIT
+        return;
+      }
+
+      this.taskEditData.push_set = this.tempPushSet;
+      this.pushFieldDialog = false;
+
+      // 淇濆瓨瑙勫垯
+      this.eventPushsSave();
+    },
+    toggleConfigCheck(configObj) {
+      configObj.children.forEach((child) => {
+        child.checked = configObj.checked;
+      });
+      this.checkFlag();
+    },
+    getPushFields() {
+      let _this = this;
+      getPushSet().then((res) => {
+        _this.pushFields = res.data;
+      });
+      // this.pushFields = [
+      //   {          id: 'sxjxx', name: '鎽勫儚鏈轰俊鎭�', checked: false, alias: '',
+      //     children: [
+      //       { name: '鎽勫儚鏈篒D', checked: false, alias: 'cameraID', id: 'cameraID', children: null },
+      //       { name: '鎽勫儚鏈哄悕绉�', checked: false, alias: 'cameraName', id: 'cameraName', children: null },
+      //       { name: '鎽勫儚鏈哄湴鍧�', checked: false, alias: 'cameraAddr', id: 'cameraAddr', children: null },
+      //       { name: '鎽勫儚鏈哄潃', checked: false, alias: 'cameraAdr', id: 'cameraAdr', children: null }
+      //     ]        },
+      //   {          id: 'cjxx', name: '鍦烘櫙淇℃伅', checked: false, alias: '',
+      //     children: [{ name: '鍦烘櫙ID', checked: false, alias: 'taskId', id: 'tskId', children: null }]        },
+      // ];
+    },
+    addUrl() {
+      this.taskEditData.urls.push({
+        checked: true,
+        hash: Math.random().toString(36).substr(2),
+        url: "",
+        server_ip: "",
+        port: ""
+      });
+    },
+    delUrl(index) {
+      this.$set(this.taskEditData.urls, index, this.baseRule);
+      this.taskEditData.urls.splice(index, 1);
+    },
+    // 淇濆瓨
+    async eventPushsSave() {
+      // console.log(this.taskEditData.urls)
+      if (this.taskEditData.name.length < 1) {
+        this.$notify({
+          type: "warning",
+          message: "璇峰~鍐欐帹閫佷换鍔″悕绉�",
+        });
+        return;
+      }
+      // 鍒ゆ柇淇濆瓨鐨刬p鏄惁绗﹀悎鏍煎紡瑕佹眰
+      if (this.taskEditData.urls.length < 1) {
+        this.$notify({
+          type: "warning",
+          message: "璇烽厤缃嚦灏戜竴鍙版帹閫佹湇鍔″櫒",
+        });
+        return;
+      }
+      for (let i = 0; i < this.taskEditData.urls.length; i++) {
+        if (this.taskEditData.urls[i].url.length < 1 && this.taskEditData.urls[i].server_ip.length < 1) {
+          this.$notify({
+            type: "warning",
+            message: "鎺ュ彛URL鍦板潃涓嶅厑璁镐负绌�",
+          });
+          return;
+        }
+      }
+      if (this.dataList.length < 1) {
+        this.$notify({
+          type: "warning",
+          message: "璇峰湪浠诲姟閰嶇疆涓淮鎶よ鍒欙紒",
+        });
+        return;
+      }
+      // 鎷兼帴瀛楃涓�
+      let ruleDesc = [];
+      this.dataList.forEach((i) => {
+        let str = "";
+        if (i.topic_type) {
+          str += this.getNameByValue(i.topicTypeOptions, i.topic_type);
+        }
+        if (i.topic_arg) {
+          str += this.getNameByValue(i.topicArgOptions, i.topic_arg);
+        }
+        if (i.operator === "==") {
+          str += " = ";
+        }
+
+        if (i.rule_value === "all*all") {
+          str += "鍏ㄩ儴";
+        } else if (i.rule_value === "null*null") {
+          str += "绌�";
+        } else {
+          str += i.rule_value;
+        }
+
+        if (str.length > 0) {
+          ruleDesc.push(str);
+        }
+      });
+      console.log(this.dataList, "dataList")
+      // 澶勭悊瑙勫垯鍒楄〃鏁版嵁缁撴瀯
+      let ruleList = this.dataList.map((i) => {
+        return {
+          topic_type: i.topic_type,
+          topic_arg: i.topic_arg,
+          operator: i.operator,
+          operator_type: i.operator_type,
+          rule_value: i.rule_value,
+        };
+      });
+
+      let json = {
+        enable: this.taskEditData.enable,
+        id: this.taskEditData.id,
+        ip_ports: this.taskEditData.serverIp,
+        name: this.taskEditData.name,
+        rule_text: ruleDesc.join("<br/>"),
+        rules: ruleList,
+        time_start: this.taskEditData.time[0],
+        time_end: this.taskEditData.time[1],
+        urls: this.taskEditData.urls.map(item => {
+          return {
+            ...item,
+            port: item.port ? Number(item.port) : 0
+          }
+        }),
+        is_satisfy_all: this.taskEditData.radioValue === "1",
+        link_type: this.taskEditData.lineWay,
+        push_set: this.taskEditData.push_set,
+        push_type: Number(this.taskEditData.pushType)
+      };
+      let res = await eventPushsSave(json);
+      if (res && res.success) {
+        this.taskEditData.eventTxt = ruleDesc.join("<br/>");
+        this.$emit("updateList", res.data.id);
+        this.$notify({
+          type: "success",
+          message: "淇濆瓨鎴愬姛",
+        });
+      }
+    },
+    // 鏌ユ壘瀛楀吀
+    async findByType() {
+      let res = await findDictionaryByType();
+      if (res && res.success) {
+        this.dictionary = Object.assign(this.dictionary, res.data);
+        this.baseRule.topicTypeOptions = this.dictionary.EVENTRULETOPIC;
+        this.baseRule.operatorTypeOpionts = this.dictionary.EVENTTYPECOMPUTE;
+        this.dictionary["alarmLevel"] = this.dictionary.ALARMLEVEL.map((el) => {
+          return {
+            name: el.name,
+            value: el.name,
+          };
+        });
+        this.dictionary["warning"] = this.dictionary.WARNING.map((el) => {
+          return {
+            name: el.name,
+            value: el.name,
+          };
+        });
+      }
+    },
+    async getCameras() {
+      let rsp = await findByEventTopic({ topic: "camera", type: "name" });
+      if (rsp && rsp.success) {
+        this.dictionary["camera"] = rsp.data;
+      }
+
+      rsp = await findByEventTopic({ topic: "dbtable" });
+      if (rsp && rsp.success) {
+        this.dictionary["dbtable"] = rsp.data.map((el) => {
+          return {
+            name: el.name,
+            value: el.name,
+          };
+        });
+      }
+    },
+    async getTasks() {
+      this.dictionary["task"] = [];
+      let rsp = await getTaskList();
+      if (rsp && rsp.success) {
+        let hash = {};
+        rsp.data.forEach((task) => {
+          if (!task.isDelete && !hash[task.name]) {
+            this.dictionary["task"].push({
+              value: task.name,
+              name: task.name,
+            });
+            hash[task.name] = true;
+          }
+        });
+      }
+    },
+    // 鏂板缓閰嶇疆
+    createSet() {
+      this.dataList.push(JSON.parse(JSON.stringify(this.baseRule)));
+      console.log(this.dataList, "dataList")
+    },
+    cleanSet() {
+      this.dataList.splice(0, this.dataList.length);
+      console.log(this.dataList, "dataList")
+    },
+    // 娣诲姞瀛愯鍒�
+    addRule() {
+      this.dataList.push(JSON.parse(JSON.stringify(this.baseRule)));
+      console.log(this.dataList, "dataList")
+    },
+    // 鍒犻櫎瀛愯鍒�
+    delRule(index) {
+      this.dataList.splice(index, 1);
+    },
+    // 瑙勫垯涓笅鎷夋鐨勯�夋嫨鍥炶皟
+    selectTopic(rule, resetNext = false) {
+      rule.topicTypeOptions.forEach((element) => {
+        if (element.value === rule.topic_type) {
+          rule.topicArgOptions = element.children;
+          if (resetNext) {
+            rule.topic_arg = rule.topicArgOptions[0].value;
+            this.selectArg(rule, resetNext);
+            this.setOptionsDisable(rule);
+          }
+        }
+      });
+    },
+    selectArg(rule, resetNext = false) {
+      let argInfo = rule.topicArgOptions.filter((arg) => {
+        return arg.value === rule.topic_arg;
+      });
+
+      if (argInfo.length > 0) {
+        let desc = argInfo[0].description.split(",");
+        if (desc.length > 0) {
+          rule.operatorTypeOpionts = this.dictionary.EVENTTYPECOMPUTE.filter(
+            (el) => {
+              return desc.indexOf(el.value) >= 0;
+            }
+          );
+        }
+      }
+
+      if (resetNext) {
+        rule.operator_type =
+          rule.operatorTypeOpionts[rule.operatorTypeOpionts.length - 1].value;
+        this.selectOperator(rule, resetNext);
+      }
+    },
+    selectOperator(rule, resetNext = false) {
+      if (rule.operator_type === "option") {
+        rule.ruleValueOptions = this.dictionary[rule.topic_type]
+          ? this.dictionary[rule.topic_type]
+          : [];
+
+        if (rule.rule_value != "") {
+          rule.rule_values = rule.rule_value.split(",");
+        }
+
+        // 澶勭悊 鍏ㄩ儴/绌�
+        for (let i = 0; i < rule.rule_values.length; i++) {
+          if (rule.rule_values[i] === "all*all") {
+            rule.rule_values[i] = "鍏ㄩ儴";
+          }
+
+          if (rule.rule_values[i] === "null*null") {
+            rule.rule_values[i] = "绌�";
+          }
+        }
+        console.log("-----------");
+        this.setOptionsDisable(rule);
+      }
+
+      if (resetNext) {
+        rule.rule_value = "";
+        rule.rule_values = [];
+      }
+    },
+    selectValue(rule, val) {
+      if (rule.operator_type === "option") {
+        this.setOptionsDisable(rule);
+
+        if (val.indexOf("鍏ㄩ儴") >= 0) {
+          rule.rule_value = "all*all";
+          return;
+        }
+
+        if (val.indexOf("绌�") >= 0) {
+          rule.rule_value = "null*null";
+          return;
+        }
+      }
+
+    },
+    setOptionsDisable(rule) {
+      console.log(rule, "rule")
+      let isAllSelect =
+        rule.rule_values.indexOf("鍏ㄩ儴") >= 0 ||
+        rule.rule_values.indexOf("all*all") >= 0;
+      let isNullSelect = rule.rule_values.indexOf("绌�") >= 0;
+
+      rule.ruleValueOptions.forEach((opt) => {
+        if (!rule.rule_values.length) {
+          opt.disabled = false;
+          return;
+        }
+
+        if (opt.name === "绌�") {
+          opt.disabled = !isNullSelect;
+          return;
+        }
+
+        opt.disabled = isAllSelect || isNullSelect;
+      });
+      let str = ""
+      if (!rule.rule_value && rule.rule_values) {
+        for(let i=0; i<rule.rule_values.length; i++){
+          str += rule.rule_values+","
+        }
+        rule.rule_value = str.substring(0,str.length-1)
+      }
+      console.log(1212);
+      // console.log(rule.ruleValueOptions);
+    },
+    // 鏍规嵁value杩斿洖瀵瑰簲鐨刵ame
+    getNameByValue(arr, value) {
+      let s = arr.find((item) => {
+        return item.value === value;
+      });
+
+      return s.name;
+    },
+    // 娓呯┖閲嶆柊鏂板
+    reAdd() {
+      this.taskEditData = {
+        id: "",
+        name: "",
+        time: [
+          this.$moment().format("YYYY-MM-DD 00:00:00"),
+          this.$moment().format("YYYY-MM-DD HH:mm:ss"),
+        ],
+        serverIp: [
+          {
+            enable: true,
+            server_ip: "",
+            port: 0,
+          },
+        ],
+        urls: [],
+        lineWay: "",
+        lineOptions: [
+          {
+            value: "001",
+            label: "IP骞挎挱",
+          },
+        ],
+        radioValue: "1",
+        eventTxt: "",
+        push_set: this.pushFields,
+        pushType: '1'
+      };
+      this.dataList = [];
+    },
+    onCancle() {
+      this.$emit("onCancle");
+    },
+  },
+};
+</script>
+<style lang="scss">
+.s-event-push-right {
+  text-align: left;
+  font-size: 14px;
+
+  i {
+    cursor: pointer;
+  }
+
+  .s-right-config {
+    padding: 10px 40px;
+  }
+
+  .el-form-item__label {
+    text-align: left;
+  }
+
+  .s-right-mid {
+    height: 10px;
+    background-color: #e9ebf2;
+    width: 100%;
+    //position: absolute;
+  }
+
+  .s-right-rule {
+    padding: 20px 40px;
+    margin-top: 17px;
+
+    .rule-title {
+      border-bottom: 1px solid #e0e0e0;
+    }
+
+    .rule-title2 {
+      margin-top: 20px;
+    }
+
+    .div-border {
+      width: 995px;
+      padding: 10px;
+      margin-top: 15px;
+      min-height: 80px;
+      background: #fafafa;
+      border: 1px solid #f2f2f2;
+    }
+
+    .rule-edit-btn {
+      font-size: 18px;
+      line-height: 38px;
+    }
+
+    .save-btn {
+      // float: right;
+      margin-top: 20px;
+      margin-left: 895px;
+    }
+  }
+
+  .config-item {
+    margin: 20px 0;
+
+    b {
+      margin-right: 10px;
+    }
+  }
+
+  .el-button--text {
+    text-decoration: unset;
+  }
+
+  .icon-btn {
+    i {
+      font-size: 18px;
+      position: relative;
+      top: 2px;
+    }
+
+    span {
+      font-size: 14px;
+    }
+
+    display: inline;
+    color: #3d68e1;
+    line-height: 38px;
+    margin-left: 10px;
+    cursor: pointer;
+  }
+
+  .server-url {
+    padding-top: 25px;
+  }
+
+  .server-add {
+    font-size: 18px;
+    margin-left: 8px;
+    color: #3d68e1;
+    line-height: 39px;
+  }
+
+  .dialog-push-field {
+
+    .el-button--primary.is-disabled,
+    .el-button--primary.is-disabled:hover {
+      background-color: #9eb4f0 !important;
+      border-color: #9eb4f0 !important;
+    }
+
+    .el-dialog {
+      width: 910px;
+      height: 700px;
+
+      .el-dialog__body {
+        padding-top: 14px;
+        height: 540px;
+        overflow-y: auto;
+      }
+    }
+
+    .text-center {
+      text-align: center;
+    }
+
+    .slot-title {
+      position: relative;
+
+      .right {
+        position: absolute;
+        top: 0;
+        right: 30px;
+      }
+    }
+
+    .check-area {
+      padding-bottom: 10px;
+
+      .header {
+        position: relative;
+        background: #efefef;
+        line-height: 30px;
+        margin-bottom: 14px;
+        font-weight: bold;
+
+        .title {
+          border-left: 3px solid #2481fa;
+          padding-left: 10px;
+        }
+
+        .right {
+          position: absolute;
+          top: 0;
+          right: 30px;
+        }
+      }
+
+      .flex-box.flex-wrap {
+        flex-wrap: wrap;
+      }
+
+      .param.flex-box {
+        word-break: keep-all;
+        align-items: center;
+        margin: 0 10px;
+        min-width: 260px;
+        margin-bottom: 10px;
+
+        .param-name {
+          margin: 0 5px;
+        }
+
+        .el-input {
+          border-color: #dcdfe6;
+          color: #606266;
+
+          .el-input__inner {
+            color: inherit;
+            border-color: inherit;
+          }
+        }
+      }
+    }
+  }
+}
+</style>
diff --git a/src/pages/datapush/index/RightEvent.vue b/src/pages/datapush/index/RightEvent.vue
index 2eb64b5..50849da 100644
--- a/src/pages/datapush/index/RightEvent.vue
+++ b/src/pages/datapush/index/RightEvent.vue
@@ -27,10 +27,12 @@
         <div v-for="(item, index) in urls" :key="item.hash" class="flex-box server-url">
           <div>
             <el-checkbox v-model="item.enable"></el-checkbox>
-            <span class="ml20">{{ "鏈嶅姟鍣�&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;" }}</span>
+            <span v-if="taskEditData.pushType === '1'" class="ml20">{{ "鏈嶅姟鍣�&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;" }}</span>
+            <span v-else class="ml20">{{ "URL&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;" }}</span>
             <el-input v-if="taskEditData.pushType === '1'" v-model="item.server_ip"
               style="width: 180px; margin-left: 0px;margin-right: 30px" size="small"
               placeholder="192.168.1.100"></el-input>
+              <span v-if="taskEditData.pushType === '1'">绔彛</span>
              <el-input v-if="taskEditData.pushType === '1'" v-model="item.port" style="width: 70px; margin-left: 10px"
               size="small" placeholder="8030"></el-input>
             <el-input v-if="taskEditData.pushType === '2'" v-model="item.url" style="width: 360px; margin-left: 0px"
@@ -686,6 +688,7 @@
         }
       }
 
+      rule.rule_value = val.join(",");
     },
     setOptionsDisable(rule) {
       console.log(rule);
diff --git a/src/pages/searchNew/components/AiRetrievalView.vue b/src/pages/searchNew/components/AiRetrievalView.vue
index e26d59b..e0c49cb 100644
--- a/src/pages/searchNew/components/AiRetrievalView.vue
+++ b/src/pages/searchNew/components/AiRetrievalView.vue
@@ -227,21 +227,21 @@
         let ids = [];
         let idsStr = "";
         //绛涢�夋渶缁堢粨鏋�
-        // const response = await AiRetrieval.getChatDetail(
-        //   {
-        //     message:userMessage
-        //   }
-        // );
-        const response = await fetch(this.severUrl +"/v1/record/chat", {
-          method: "POST",
-          headers: {
-            "Content-Type": "application/json",
-          },
-          body: JSON.stringify({
-            message: userMessage
-          }),
-        });
-
+        const response = await AiRetrieval.getChatDetail(
+          {
+            message:userMessage
+          }
+        );
+        // const response = await fetch("http://192.168.1.235:8088/v1/record/chat", {
+        //   method: "POST",
+        //   headers: {
+        //     "Content-Type": "application/json",
+        //   },
+        //   body: JSON.stringify({
+        //     message: userMessage
+        //   }),
+        // });
+          // console.log(response,"response鍙傛暟")
         if (!response.ok) throw new Error(`璇锋眰澶辫触: ${response.status}`);
 
         const reader = response.body.getReader();
@@ -768,6 +768,7 @@
   background: #cadcff;
   color: #2e2f31;
   border-radius: 12px 12px 0 12px;
+  max-width: 225px;
 }
 
 .assistant .content {
diff --git a/src/pages/searchNew/components/SurveyView.vue b/src/pages/searchNew/components/SurveyView.vue
index fbca1e2..001b1cf 100644
--- a/src/pages/searchNew/components/SurveyView.vue
+++ b/src/pages/searchNew/components/SurveyView.vue
@@ -171,8 +171,9 @@
                     <el-card class="result-card" :class="{ 'selected-card': selectedItemId === item.id }"
                       @click.native.stop="handleCardClick(item)">
                       <div class="image-wrapper">
-                        <el-image slot="error" :src="item.image_path" class="result-image" alt="妫�娴嬬粨鏋�" />
-                        <!-- <img slot="error" src="@/assets/01.png" class="result-image" alt="妫�娴嬬粨鏋�" /> -->
+                        <div class="image-container">
+                          <el-image slot="error" :src="item.image_path" class="result-image" alt="妫�娴嬬粨鏋�" />
+                        </div>
                         <div class="image-overlay" v-if="item.is_warning == 1">
                           <span class="check-item">
                             {{ item.task_names }}
@@ -204,7 +205,8 @@
                               <span>{{ item.video_name }}</span>
                               <el-dropdown size="small" trigger="click" @command="handleCommand" class="right-btn">
                                 <img src="@/assets/img/modelTraining.png"
-                                  style="width: 16px;height: 16px;margin-left: 10px; vertical-align: middle" @click.stop>
+                                  style="width: 16px;height: 16px;margin-left: 10px; vertical-align: middle"
+                                  @click.stop>
                                 <el-dropdown-menu slot="dropdown">
                                   <el-dropdown-item
                                     :command="{ ruleName: item.rule_names ? item.rule_names[0].fileName : '', cameraId: item.video_point_id + '', cameraName: item.video_name, imagePath: item.image_path, status: 1 }">姝g‘</el-dropdown-item>
@@ -452,11 +454,12 @@
         if (lists) {
           for (let i = 0; i < lists.length; i++) {
             console.log("333:" + lists[i].video_point_id)
-            this.results.push({
+            let item = {}
+            item = {
               task_names: lists[i].task_name,
               video_name: lists[i].video_name,
-              image_path: "/api-img" + lists[i].image_path,
-              video_path: "/api-img" + lists[i].video_path,
+              image_path: lists[i].image_path,
+              video_path: lists[i].video_path,
               detect_time: lists[i].detect_time,
               event_levels: lists[i].event_level_name,
               zh_desc_class: lists[i].zh_desc_class,
@@ -464,14 +467,16 @@
               is_desc: lists[i].is_desc,
               video_point_id: lists[i].video_point_id,
               rule_names: lists[i].rule_names,
-              knowledge_documents: lists[i].knowledge_documents.map(file => {
+            };
+            if (lists[i].knowledge_documents) {
+              item.knowledge_documents = lists[i].knowledge_documents.map(file => {
                 return {
                   ...file,
-                  file_url: "/api-img" + file.file_url,
                   fileName: file.title
                 }
               })
-            });
+            }
+            this.results.push(item)
           }
         }
 
@@ -695,11 +700,12 @@
         this.results = [];
         if (lists) {
           for (let i = 0; i < lists.length; i++) {
-            this.results.push({
+            let item = {}
+            item = {
               task_names: lists[i].task_name,
               video_name: lists[i].video_name,
-              image_path: "/api-img" + lists[i].image_path,
-              video_path: "/api-img" + lists[i].video_path,
+              image_path: lists[i].image_path,
+              video_path: lists[i].video_path,
               detect_time: lists[i].detect_time,
               event_levels: lists[i].event_level_name,
               zh_desc_class: lists[i].zh_desc_class,
@@ -707,16 +713,18 @@
               is_desc: lists[i].is_desc,
               video_point_id: lists[i].video_point_id,
               rule_names: lists[i].rule_names,
-              knowledge_documents: lists[i].knowledge_documents.map(file => {
-                return {
-                  ...file,
-                  file_url: "/api-img" + file.file_url,
-                  fileName: file.title
-                }
-              }),
               risk_description: lists[i].risk_description,
               suggestion: lists[i].suggestion
-            });
+            };
+            if (lists[i].knowledge_documents) {
+              item.knowledge_documents = lists[i].knowledge_documents.map(file => {
+                return {
+                  ...file,
+                  fileName: file.title
+                }
+              })
+            }
+            this.results.push(item)
           }
         }
         this.totalResults = response.data.pagination.total;
@@ -732,7 +740,7 @@
     },
     // 鏂板璇︽儏灞曠ず鏂规硶
     showDetail(item) {
-      // console.info(item)
+      console.log(item)
       this.backendData = item.is_warning == 1 ? true : false;
       //   console.info(item.is_warning)
       this.currentMediaType = "image";
@@ -1119,11 +1127,22 @@
       overflow: visible;
       border-radius: 6px 6px 0 0;
 
-      .result-image {
+      .image-container {
+        position: relative;
         width: 100%;
-        // height: 130px;
+        padding-top: 56.25%;
+        /* 16:9瀹介珮姣� */
+        background-color: #f5f7fa;
+        /* 鍔犺浇鏃剁殑鑳屾櫙鑹� */
+      }
+
+      .result-image {
+        position: absolute;
+        top: 0;
+        left: 0;
+        width: 100%;
+        height: 100%;
         object-fit: cover;
-        transition: transform 0.3s;
       }
 
       .image-overlay {

--
Gitblit v1.8.0