feat(DataBaseInfoView): 添加待处理文件提示条和批量解析/入库功能

This commit is contained in:
Wenjie Zhang 2026-01-23 22:50:00 +08:00
parent e0adda65fc
commit e7684ad9c4

View File

@ -20,6 +20,17 @@
<div class="unified-layout">
<div class="left-panel" :style="{ width: leftPanelWidth + '%' }">
<KnowledgeBaseCard />
<!-- 待处理文件提示条 -->
<div class="info-panel" v-if="pendingParseCount > 0 || pendingIndexCount > 0">
<div class="banner-item" v-if="pendingParseCount > 0" @click="confirmBatchParse">
<FileText :size="14" />
<span>{{ pendingParseCount }} 个文件待解析点击解析</span>
</div>
<div class="banner-item" v-if="pendingIndexCount > 0" @click="confirmBatchIndex">
<Database :size="14" />
<span>{{ pendingIndexCount }} 个文件待入库点击入库</span>
</div>
</div>
<FileTable
:right-panel-visible="state.rightPanelVisible"
@show-add-files-modal="showAddFilesModal"
@ -117,8 +128,9 @@ import { onMounted, reactive, ref, watch, onUnmounted, computed } from 'vue'
import { useRoute } from 'vue-router'
import { useDatabaseStore } from '@/stores/database'
import { useTaskerStore } from '@/stores/tasker'
import { Info } from 'lucide-vue-next'
import { Info, FileText, Database } from 'lucide-vue-next'
import { SettingOutlined } from '@ant-design/icons-vue'
import { Modal } from 'ant-design-vue'
import KnowledgeBaseCard from '@/components/KnowledgeBaseCard.vue'
import FileTable from '@/components/FileTable.vue'
import FileDetailModal from '@/components/FileDetailModal.vue'
@ -149,6 +161,75 @@ const isEvaluationSupported = computed(() => {
return kbType === 'milvus'
})
// status: 'uploaded'
const pendingParseCount = computed(() => {
const files = store.database.files || {}
return Object.values(files).filter(f => !f.is_folder && f.status === 'uploaded').length
})
// status: 'parsed' 'error_indexing'
const pendingIndexCount = computed(() => {
const files = store.database.files || {}
const isLightRAG = database.value?.kb_type?.toLowerCase() === 'lightrag'
return Object.values(files).filter(f => {
if (f.is_folder) return false
if (isLightRAG) {
return f.status === 'parsed'
}
return f.status === 'parsed' || f.status === 'error_indexing'
}).length
})
//
const confirmBatchParse = () => {
const fileIds = Object.values(store.database.files || {})
.filter(f => f.status === 'uploaded')
.map(f => f.file_id)
if (fileIds.length === 0) {
return
}
Modal.confirm({
title: '批量解析',
content: `确定要解析 ${fileIds.length} 个文件吗?`,
onOk: () => store.parseFiles(fileIds)
})
}
//
const confirmBatchIndex = () => {
const isLightRAG = database.value?.kb_type?.toLowerCase() === 'lightrag'
const fileIds = Object.values(store.database.files || {})
.filter(f => {
if (f.is_folder) return false
if (isLightRAG) return f.status === 'parsed'
return f.status === 'parsed' || f.status === 'error_indexing'
})
.map(f => f.file_id)
if (fileIds.length === 0) {
return
}
if (isLightRAG) {
Modal.confirm({
title: '批量入库',
content: `确定要入库 ${fileIds.length} 个文件吗?`,
onOk: () => store.indexFiles(fileIds)
})
return
}
// LightRAG FileTable
// store.indexFiles
Modal.confirm({
title: '批量入库',
content: `确定要入库 ${fileIds.length} 个文件吗?`,
onOk: () => store.indexFiles(fileIds)
})
}
// Tab -
const activeTab = ref('query')
@ -487,9 +568,42 @@ const handleMouseUp = () => {
flex-shrink: 0;
flex-grow: 1;
padding-right: 0;
flex-direction: column;
// max-height: calc(100% - 16px);
}
.info-panel {
background: var(--gray-10);
border-radius: 12px;
border: 1px solid var(--gray-200);
display: flex;
gap: 12px;
padding: 8px 12px;
margin-bottom: 8px;
flex-shrink: 0;
.banner-item {
display: flex;
align-items: center;
gap: 6px;
padding: 4px 8px;
background: var(--color-warning-50);
border-radius: 4px;
font-size: 13px;
color: var(--color-warning-700);
cursor: pointer;
transition: all 0.2s;
&:hover {
background: var(--color-warning-100);
}
svg {
color: var(--color-warning-700);
}
}
}
.right-panel {
flex-grow: 1;
overflow: hidden;