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> | + <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> 娣诲姞鎺ュ彛鍦板潃</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">{{ "鏈嶅姟鍣� " }}</span> + <span v-else class="ml20">{{ "URL " }}</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> 鏂板</span> + </div> + <div class="icon-btn" v-if="dataList.length > 0" @click="cleanSet"> + <i class="el-icon-remove-outline"></i> + <span> 娓呯┖</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">{{ "鏈嶅姟鍣� " }}</span> + <span v-if="taskEditData.pushType === '1'" class="ml20">{{ "鏈嶅姟鍣� " }}</span> + <span v-else class="ml20">{{ "URL " }}</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