2025-12-13 15:56:12 +08:00
|
|
|
|
<template>
|
2025-12-15 10:47:01 +08:00
|
|
|
|
<AdminLayout title="知识库管理" info="管理外部和内部知识库文档">
|
|
|
|
|
|
<template #action>
|
2025-12-20 15:14:44 +08:00
|
|
|
|
<!-- 上传文档组件 -->
|
|
|
|
|
|
<FileUpload
|
|
|
|
|
|
ref="fileUploadRef"
|
|
|
|
|
|
mode="dialog"
|
|
|
|
|
|
:title="'上传文档到:' + currentKnowledgeName"
|
|
|
|
|
|
button-text="上传文档"
|
|
|
|
|
|
accept=".pdf,.doc,.docx,.txt,.md"
|
|
|
|
|
|
:max-size="50 * 1024 * 1024"
|
|
|
|
|
|
:max-count="10"
|
|
|
|
|
|
:custom-upload="customKnowledgeUpload"
|
|
|
|
|
|
@upload-error="handleUploadError"
|
|
|
|
|
|
/>
|
2025-12-13 18:44:28 +08:00
|
|
|
|
</template>
|
2025-12-15 10:47:01 +08:00
|
|
|
|
|
|
|
|
|
|
<div class="knowledge-container">
|
|
|
|
|
|
<el-card>
|
2025-12-19 17:34:30 +08:00
|
|
|
|
<el-tabs v-model="activeTab" @tab-change="handleTabChange">
|
|
|
|
|
|
<el-tab-pane v-for="tab in tabConfig" :key="tab.name" :label="tab.label" :name="tab.name" />
|
|
|
|
|
|
</el-tabs>
|
2025-12-15 10:47:01 +08:00
|
|
|
|
|
2025-12-19 17:34:30 +08:00
|
|
|
|
<p class="tab-desc">{{ currentTabDesc }}</p>
|
2025-12-15 10:47:01 +08:00
|
|
|
|
|
2025-12-19 17:34:30 +08:00
|
|
|
|
<div class="kb-categories">
|
|
|
|
|
|
<div v-for="kb in currentKnowledges" :key="kb.knowledgeId" class="kb-category-card"
|
|
|
|
|
|
:class="{ active: activeKnowledgeId === kb.knowledgeId }" @click="selectKnowledge(kb.knowledgeId || '')">
|
|
|
|
|
|
<el-icon :style="{ color: currentTabColor }"><Document /></el-icon>
|
|
|
|
|
|
<span class="cat-name">{{ kb.title }}</span>
|
|
|
|
|
|
<span class="cat-count">{{ kb.documentCount || 0 }} 个文件</span>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<el-empty v-if="currentKnowledges.length === 0" :description="'暂无' + currentTabLabel" :image-size="60" />
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div class="kb-files-section">
|
|
|
|
|
|
<div class="section-toolbar">
|
|
|
|
|
|
<h3>{{ currentKnowledgeName }}</h3>
|
|
|
|
|
|
<el-input v-model="searchKeyword" placeholder="搜索文件名" style="width: 240px;" :prefix-icon="Search" clearable />
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<el-table :data="filteredDocuments" style="width: 100%" v-loading="loading">
|
|
|
|
|
|
<el-table-column prop="name" label="文件名" min-width="280">
|
|
|
|
|
|
<template #default="{ row }">
|
|
|
|
|
|
<div class="file-name-cell">
|
|
|
|
|
|
<el-icon class="file-icon"><Document /></el-icon>
|
|
|
|
|
|
<span>{{ row.name }}</span>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
</el-table-column>
|
|
|
|
|
|
<el-table-column prop="uploader" label="上传人员" width="120" />
|
|
|
|
|
|
<el-table-column prop="uploadTime" label="上传时间" width="180" />
|
2025-12-20 17:12:42 +08:00
|
|
|
|
<!-- <el-table-column prop="wordCount" label="字数" width="100" /> -->
|
|
|
|
|
|
<!-- <el-table-column label="状态" width="100">
|
2025-12-19 17:34:30 +08:00
|
|
|
|
<template #default="{ row }">
|
|
|
|
|
|
<el-tag :type="row.enabled ? 'success' : 'info'" size="small">
|
|
|
|
|
|
{{ row.enabled ? '已启用' : '已禁用' }}
|
|
|
|
|
|
</el-tag>
|
|
|
|
|
|
</template>
|
2025-12-20 17:12:42 +08:00
|
|
|
|
</el-table-column> -->
|
|
|
|
|
|
<el-table-column label="操作" width="280" align="center" fixed="right">
|
2025-12-19 17:34:30 +08:00
|
|
|
|
<template #default="{ row }">
|
2025-12-20 17:12:42 +08:00
|
|
|
|
<el-button type="primary" link size="small" @click="openSegmentDialog(row)">
|
|
|
|
|
|
<el-icon><Edit /></el-icon>编辑
|
|
|
|
|
|
</el-button>
|
|
|
|
|
|
<el-button type="warning" link size="small" @click="openHistoryDialog(row)">
|
|
|
|
|
|
<el-icon><Clock /></el-icon>历史
|
|
|
|
|
|
</el-button>
|
2025-12-19 17:34:30 +08:00
|
|
|
|
<el-button type="primary" link size="small" @click="previewFile(row)">
|
|
|
|
|
|
<el-icon><View /></el-icon>预览
|
|
|
|
|
|
</el-button>
|
|
|
|
|
|
<el-button type="success" link size="small" @click="downloadFile(row)">
|
|
|
|
|
|
<el-icon><Download /></el-icon>下载
|
|
|
|
|
|
</el-button>
|
|
|
|
|
|
<el-button type="danger" link size="small" @click="deleteFile(row)">
|
|
|
|
|
|
<el-icon><Delete /></el-icon>删除
|
|
|
|
|
|
</el-button>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
</el-table-column>
|
|
|
|
|
|
</el-table>
|
|
|
|
|
|
</div>
|
2025-12-15 10:47:01 +08:00
|
|
|
|
</el-card>
|
|
|
|
|
|
</div>
|
2025-12-20 17:12:42 +08:00
|
|
|
|
<!-- 分段编辑弹窗(包含版本更新功能) -->
|
|
|
|
|
|
<DocumentSegment
|
|
|
|
|
|
v-model="showSegmentDialog"
|
|
|
|
|
|
:dataset-id="currentDatasetId"
|
|
|
|
|
|
:document-id="currentDifyDocId"
|
|
|
|
|
|
:knowledge-id="currentKnowledgeId"
|
|
|
|
|
|
:file-root-id="currentFileRootId"
|
|
|
|
|
|
@file-updated="handleFileUpdated"
|
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- 历史版本弹窗 -->
|
|
|
|
|
|
<FileHistory
|
|
|
|
|
|
v-model="showHistoryDialog"
|
|
|
|
|
|
:data="historyList"
|
|
|
|
|
|
:loading="historyLoading"
|
|
|
|
|
|
@preview="previewHistoryFile"
|
|
|
|
|
|
@download="downloadHistoryFile"
|
|
|
|
|
|
/>
|
2025-12-13 18:44:28 +08:00
|
|
|
|
</AdminLayout>
|
2025-12-13 15:56:12 +08:00
|
|
|
|
</template>
|
2025-12-15 10:47:01 +08:00
|
|
|
|
|
2025-12-13 15:56:12 +08:00
|
|
|
|
<script setup lang="ts">
|
2025-12-19 17:34:30 +08:00
|
|
|
|
import { ref, computed, onMounted, watch } from 'vue'
|
2025-12-15 10:47:01 +08:00
|
|
|
|
import AdminLayout from '@/views/admin/AdminLayout.vue'
|
2025-12-20 17:12:42 +08:00
|
|
|
|
import { Upload, Search, FileText as Document, Eye as View, Download, Trash2 as Delete, Pencil as Edit, Clock } from 'lucide-vue-next'
|
2025-12-20 13:33:08 +08:00
|
|
|
|
import { ElMessage, ElMessageBox } from 'element-plus'
|
2025-12-19 17:34:30 +08:00
|
|
|
|
import { aiKnowledgeAPI } from 'shared/api/ai'
|
2025-12-20 17:12:42 +08:00
|
|
|
|
import { FileUpload, FileHistory } from 'shared/components'
|
|
|
|
|
|
import DocumentSegment from 'shared/components/ai/knowledge/DocumentSegment.vue'
|
2025-12-20 15:14:44 +08:00
|
|
|
|
import { FILE_DOWNLOAD_URL } from '@/config/index'
|
2025-12-19 17:34:30 +08:00
|
|
|
|
import type { TbKnowledge } from 'shared/types'
|
|
|
|
|
|
|
|
|
|
|
|
// Tab 配置
|
|
|
|
|
|
const tabConfig = [
|
|
|
|
|
|
{ name: 'external', label: '外部知识库', desc: '面向客户的知识库内容,包含设备操作指南、故障解决方案等', color: '#409eff' },
|
|
|
|
|
|
{ name: 'internal', label: '内部知识库', desc: '内部技术资料与服务规范,仅供内部员工使用', color: '#67c23a' }
|
|
|
|
|
|
]
|
2025-12-15 10:47:01 +08:00
|
|
|
|
|
|
|
|
|
|
const activeTab = ref('external')
|
2025-12-19 17:34:30 +08:00
|
|
|
|
const searchKeyword = ref('')
|
|
|
|
|
|
const loading = ref(false)
|
2025-12-20 13:33:08 +08:00
|
|
|
|
const fileUploadRef = ref<InstanceType<typeof FileUpload> | null>(null)
|
2025-12-19 17:34:30 +08:00
|
|
|
|
|
|
|
|
|
|
// 知识库列表
|
|
|
|
|
|
const knowledges = ref<TbKnowledge[]>([])
|
|
|
|
|
|
const activeKnowledgeId = ref('')
|
|
|
|
|
|
|
|
|
|
|
|
// 文档列表
|
|
|
|
|
|
interface DocumentItem {
|
|
|
|
|
|
id: string
|
|
|
|
|
|
name: string
|
|
|
|
|
|
uploader: string
|
|
|
|
|
|
uploadTime: string
|
2025-12-20 15:14:44 +08:00
|
|
|
|
fileId?: string
|
|
|
|
|
|
fileRootId?: string
|
|
|
|
|
|
knowledgeId?: string
|
|
|
|
|
|
difyFileId?: string
|
|
|
|
|
|
version?: number
|
2025-12-19 17:34:30 +08:00
|
|
|
|
}
|
|
|
|
|
|
const documents = ref<DocumentItem[]>([])
|
2025-12-15 10:47:01 +08:00
|
|
|
|
|
2025-12-19 17:34:30 +08:00
|
|
|
|
// 当前 Tab 配置
|
|
|
|
|
|
const currentTabConfig = computed(() => tabConfig.find(t => t.name === activeTab.value) || tabConfig[0])
|
|
|
|
|
|
const currentTabDesc = computed(() => currentTabConfig.value.desc)
|
|
|
|
|
|
const currentTabLabel = computed(() => currentTabConfig.value.label)
|
|
|
|
|
|
const currentTabColor = computed(() => currentTabConfig.value.color)
|
2025-12-15 10:47:01 +08:00
|
|
|
|
|
2025-12-20 12:03:26 +08:00
|
|
|
|
// 当前 Tab 下的知识库列表(直接使用查询结果,不再前端过滤)
|
|
|
|
|
|
const currentKnowledges = computed(() => knowledges.value)
|
2025-12-19 17:34:30 +08:00
|
|
|
|
|
|
|
|
|
|
// 当前选中的知识库名称
|
|
|
|
|
|
const currentKnowledgeName = computed(() => {
|
|
|
|
|
|
const kb = knowledges.value.find((k: TbKnowledge) => k.knowledgeId === activeKnowledgeId.value)
|
|
|
|
|
|
return kb?.title || '请选择知识库'
|
2025-12-15 10:47:01 +08:00
|
|
|
|
})
|
|
|
|
|
|
|
2025-12-19 17:34:30 +08:00
|
|
|
|
// 搜索过滤后的文档列表
|
|
|
|
|
|
const filteredDocuments = computed(() => {
|
|
|
|
|
|
if (!searchKeyword.value) return documents.value
|
|
|
|
|
|
return documents.value.filter(f =>
|
|
|
|
|
|
f.name.toLowerCase().includes(searchKeyword.value.toLowerCase())
|
|
|
|
|
|
)
|
2025-12-15 10:47:01 +08:00
|
|
|
|
})
|
|
|
|
|
|
|
2025-12-20 12:03:26 +08:00
|
|
|
|
// 获取知识库列表(根据当前 Tab 的 category 查询)
|
2025-12-19 17:34:30 +08:00
|
|
|
|
const fetchKnowledges = async () => {
|
|
|
|
|
|
loading.value = true
|
|
|
|
|
|
try {
|
2025-12-20 12:03:26 +08:00
|
|
|
|
const result = await aiKnowledgeAPI.listKnowledges({
|
|
|
|
|
|
service: 'workcase',
|
|
|
|
|
|
category: activeTab.value
|
|
|
|
|
|
})
|
|
|
|
|
|
console.log('知识库列表响应:', result)
|
|
|
|
|
|
// API 返回的是 dataList 字段
|
|
|
|
|
|
knowledges.value = result.dataList || []
|
|
|
|
|
|
selectFirstKnowledge()
|
2025-12-19 17:34:30 +08:00
|
|
|
|
} catch (error) {
|
|
|
|
|
|
console.error('获取知识库列表失败:', error)
|
|
|
|
|
|
ElMessage.error('获取知识库列表失败')
|
|
|
|
|
|
} finally {
|
|
|
|
|
|
loading.value = false
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 选中当前 Tab 下的第一个知识库
|
|
|
|
|
|
const selectFirstKnowledge = () => {
|
|
|
|
|
|
const firstKb = currentKnowledges.value[0]
|
|
|
|
|
|
if (firstKb?.knowledgeId) {
|
|
|
|
|
|
activeKnowledgeId.value = firstKb.knowledgeId
|
|
|
|
|
|
} else {
|
|
|
|
|
|
activeKnowledgeId.value = ''
|
|
|
|
|
|
documents.value = []
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 获取文档列表
|
|
|
|
|
|
const fetchDocuments = async (knowledgeId: string) => {
|
|
|
|
|
|
if (!knowledgeId) {
|
|
|
|
|
|
documents.value = []
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
loading.value = true
|
|
|
|
|
|
try {
|
|
|
|
|
|
const result = await aiKnowledgeAPI.getDocumentList(knowledgeId, 1, 100)
|
2025-12-20 15:14:44 +08:00
|
|
|
|
if (result.success && result.pageDomain) {
|
|
|
|
|
|
documents.value = (result.pageDomain.dataList || []).map((file: any) => ({
|
|
|
|
|
|
id: file.fileId,
|
|
|
|
|
|
name: file.fileName || '-',
|
2025-12-20 17:12:42 +08:00
|
|
|
|
uploader: file.uploaderName || '-',
|
2025-12-20 15:14:44 +08:00
|
|
|
|
uploadTime: file.createTime ? new Date(file.createTime).toLocaleString() : '-',
|
|
|
|
|
|
fileId: file.fileId,
|
|
|
|
|
|
fileRootId: file.fileRootId,
|
|
|
|
|
|
knowledgeId: file.knowledgeId,
|
|
|
|
|
|
difyFileId: file.difyFileId,
|
|
|
|
|
|
version: file.version
|
2025-12-19 17:34:30 +08:00
|
|
|
|
}))
|
|
|
|
|
|
}
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
console.error('获取文档列表失败:', error)
|
|
|
|
|
|
ElMessage.error('获取文档列表失败')
|
|
|
|
|
|
} finally {
|
|
|
|
|
|
loading.value = false
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-12-20 12:03:26 +08:00
|
|
|
|
// Tab 切换时重新查询对应类别的知识库
|
2025-12-19 17:34:30 +08:00
|
|
|
|
const handleTabChange = () => {
|
|
|
|
|
|
searchKeyword.value = ''
|
2025-12-20 12:03:26 +08:00
|
|
|
|
knowledges.value = []
|
|
|
|
|
|
activeKnowledgeId.value = ''
|
|
|
|
|
|
documents.value = []
|
|
|
|
|
|
fetchKnowledges()
|
2025-12-19 17:34:30 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 选择知识库
|
|
|
|
|
|
const selectKnowledge = (knowledgeId: string) => {
|
|
|
|
|
|
activeKnowledgeId.value = knowledgeId
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 监听知识库选择变化
|
|
|
|
|
|
watch(activeKnowledgeId, (newVal) => {
|
|
|
|
|
|
if (newVal) fetchDocuments(newVal)
|
2025-12-15 10:47:01 +08:00
|
|
|
|
})
|
|
|
|
|
|
|
2025-12-20 15:14:44 +08:00
|
|
|
|
const previewFile = async (row: DocumentItem) => {
|
|
|
|
|
|
if (!row.fileId) {
|
|
|
|
|
|
ElMessage.warning('文件信息不完整')
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
// 使用 FILE_DOWNLOAD_URL 构建文件 URL 并在新窗口打开
|
|
|
|
|
|
const fileUrl = `${FILE_DOWNLOAD_URL}${row.fileId}`
|
|
|
|
|
|
window.open(fileUrl, '_blank')
|
2025-12-15 10:47:01 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-12-19 17:34:30 +08:00
|
|
|
|
const downloadFile = (row: DocumentItem) => {
|
2025-12-20 15:14:44 +08:00
|
|
|
|
if (!row.fileId) {
|
|
|
|
|
|
ElMessage.warning('文件信息不完整')
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
// 创建隐藏的下载链接并触发下载
|
|
|
|
|
|
const fileUrl = `${FILE_DOWNLOAD_URL}${row.fileId}`
|
|
|
|
|
|
const link = document.createElement('a')
|
|
|
|
|
|
link.href = fileUrl
|
|
|
|
|
|
link.download = row.name || 'file'
|
|
|
|
|
|
document.body.appendChild(link)
|
|
|
|
|
|
link.click()
|
|
|
|
|
|
document.body.removeChild(link)
|
|
|
|
|
|
ElMessage.success('开始下载')
|
2025-12-15 10:47:01 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-12-19 17:34:30 +08:00
|
|
|
|
const deleteFile = async (row: DocumentItem) => {
|
|
|
|
|
|
try {
|
|
|
|
|
|
await ElMessageBox.confirm(`确定要删除文件 "${row.name}" 吗?`, '提示', {
|
|
|
|
|
|
confirmButtonText: '确定',
|
|
|
|
|
|
cancelButtonText: '取消',
|
|
|
|
|
|
type: 'warning'
|
|
|
|
|
|
})
|
2025-12-30 19:16:51 +08:00
|
|
|
|
const result = await aiKnowledgeAPI.deleteFile(row.fileRootId)
|
2025-12-19 17:34:30 +08:00
|
|
|
|
if (result.success) {
|
|
|
|
|
|
ElMessage.success('删除成功')
|
|
|
|
|
|
fetchDocuments(activeKnowledgeId.value)
|
|
|
|
|
|
} else {
|
|
|
|
|
|
ElMessage.error(result.message || '删除失败')
|
|
|
|
|
|
}
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
if (error !== 'cancel') {
|
|
|
|
|
|
console.error('删除文件失败:', error)
|
|
|
|
|
|
ElMessage.error('删除文件失败')
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-12-15 10:47:01 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-12-20 13:33:08 +08:00
|
|
|
|
// 自定义知识库文件上传
|
|
|
|
|
|
const customKnowledgeUpload = async (files: File[]) => {
|
|
|
|
|
|
if (!activeKnowledgeId.value) {
|
|
|
|
|
|
ElMessage.error('请先选择知识库')
|
|
|
|
|
|
throw new Error('请先选择知识库')
|
2025-12-19 17:34:30 +08:00
|
|
|
|
}
|
2025-12-20 13:33:08 +08:00
|
|
|
|
const targetKnowledgeId = activeKnowledgeId.value
|
|
|
|
|
|
|
|
|
|
|
|
// 单文件上传
|
|
|
|
|
|
if (files.length === 1) {
|
|
|
|
|
|
const result = await aiKnowledgeAPI.uploadToKnowledge(files[0], targetKnowledgeId)
|
2025-12-19 17:34:30 +08:00
|
|
|
|
if (result.success) {
|
|
|
|
|
|
ElMessage.success('文件上传成功')
|
2025-12-31 10:45:29 +08:00
|
|
|
|
// fetchKnowledges()
|
2025-12-20 13:33:08 +08:00
|
|
|
|
fetchDocuments(activeKnowledgeId.value)
|
2025-12-19 17:34:30 +08:00
|
|
|
|
} else {
|
2025-12-20 13:33:08 +08:00
|
|
|
|
throw new Error(result.message || '上传失败')
|
2025-12-19 17:34:30 +08:00
|
|
|
|
}
|
2025-12-20 13:33:08 +08:00
|
|
|
|
} else {
|
|
|
|
|
|
// 批量上传
|
|
|
|
|
|
const result = await aiKnowledgeAPI.batchUploadToKnowledge(files, targetKnowledgeId)
|
|
|
|
|
|
if (result.success) {
|
|
|
|
|
|
ElMessage.success('文件上传成功')
|
2025-12-31 10:45:29 +08:00
|
|
|
|
// fetchKnowledges()
|
2025-12-20 13:33:08 +08:00
|
|
|
|
fetchDocuments(activeKnowledgeId.value)
|
|
|
|
|
|
} else {
|
|
|
|
|
|
throw new Error(result.message || '上传失败')
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const handleUploadError = (error: string) => {
|
|
|
|
|
|
ElMessage.error(error)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-12-20 17:12:42 +08:00
|
|
|
|
// ====================== 分段编辑功能 ======================
|
|
|
|
|
|
const showSegmentDialog = ref(false)
|
|
|
|
|
|
const currentDatasetId = ref('')
|
|
|
|
|
|
const currentDifyDocId = ref('')
|
|
|
|
|
|
const currentKnowledgeId = ref('')
|
|
|
|
|
|
const currentFileRootId = ref('')
|
|
|
|
|
|
|
|
|
|
|
|
const openSegmentDialog = (row: DocumentItem) => {
|
|
|
|
|
|
if (!row.difyFileId) {
|
|
|
|
|
|
ElMessage.warning('该文件暂无分段信息')
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
// 获取当前知识库的 difyDatasetId
|
|
|
|
|
|
const kb = knowledges.value.find((k: TbKnowledge) => k.knowledgeId === activeKnowledgeId.value)
|
|
|
|
|
|
if (!kb?.difyDatasetId) {
|
|
|
|
|
|
ElMessage.warning('知识库信息不完整')
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
currentDatasetId.value = kb.difyDatasetId
|
|
|
|
|
|
currentDifyDocId.value = row.difyFileId
|
|
|
|
|
|
currentKnowledgeId.value = row.knowledgeId || ''
|
|
|
|
|
|
currentFileRootId.value = row.fileRootId || ''
|
|
|
|
|
|
showSegmentDialog.value = true
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 文件更新后刷新列表
|
|
|
|
|
|
const handleFileUpdated = () => {
|
|
|
|
|
|
fetchDocuments(activeKnowledgeId.value)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// ====================== 历史版本功能 ======================
|
|
|
|
|
|
const showHistoryDialog = ref(false)
|
|
|
|
|
|
const historyLoading = ref(false)
|
|
|
|
|
|
const historyList = ref<any[]>([])
|
|
|
|
|
|
|
|
|
|
|
|
const openHistoryDialog = async (row: DocumentItem) => {
|
|
|
|
|
|
if (!row.fileRootId) {
|
|
|
|
|
|
ElMessage.warning('文件信息不完整')
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
showHistoryDialog.value = true
|
|
|
|
|
|
historyLoading.value = true
|
|
|
|
|
|
try {
|
|
|
|
|
|
const result = await aiKnowledgeAPI.getFileHistory(row.fileRootId)
|
|
|
|
|
|
console.log('历史版本响应:', result)
|
|
|
|
|
|
if (result.success) {
|
|
|
|
|
|
// 兼容 data 和 dataList 两种返回格式
|
|
|
|
|
|
historyList.value = result.data || result.dataList || []
|
|
|
|
|
|
} else {
|
|
|
|
|
|
ElMessage.error(result.message || '获取历史版本失败')
|
|
|
|
|
|
}
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
console.error('获取历史版本失败:', error)
|
|
|
|
|
|
ElMessage.error('获取历史版本失败')
|
|
|
|
|
|
} finally {
|
|
|
|
|
|
historyLoading.value = false
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const previewHistoryFile = (row: any) => {
|
|
|
|
|
|
if (!row.fileId) {
|
|
|
|
|
|
ElMessage.warning('文件信息不完整')
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
const fileUrl = `${FILE_DOWNLOAD_URL}${row.fileId}`
|
|
|
|
|
|
window.open(fileUrl, '_blank')
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const downloadHistoryFile = (row: any) => {
|
|
|
|
|
|
if (!row.fileId) {
|
|
|
|
|
|
ElMessage.warning('文件信息不完整')
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
const fileUrl = `${FILE_DOWNLOAD_URL}${row.fileId}`
|
|
|
|
|
|
const link = document.createElement('a')
|
|
|
|
|
|
link.href = fileUrl
|
|
|
|
|
|
link.download = row.fileName || 'file'
|
|
|
|
|
|
document.body.appendChild(link)
|
|
|
|
|
|
link.click()
|
|
|
|
|
|
document.body.removeChild(link)
|
|
|
|
|
|
ElMessage.success('开始下载')
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-12-19 17:34:30 +08:00
|
|
|
|
onMounted(() => {
|
|
|
|
|
|
fetchKnowledges()
|
|
|
|
|
|
})
|
2025-12-13 15:56:12 +08:00
|
|
|
|
</script>
|
2025-12-15 10:47:01 +08:00
|
|
|
|
|
2025-12-13 15:56:12 +08:00
|
|
|
|
<style lang="scss" scoped>
|
2025-12-15 10:47:01 +08:00
|
|
|
|
@import url("./KnowLedgeView.scss");
|
2025-12-13 15:56:12 +08:00
|
|
|
|
</style>
|