feat: 优化知识库和文件详情展示

- 在知识库中简化了文件加载逻辑,移除了不必要的节点加载。
- 将文件详情展示从抽屉组件改为模态框,增强用户体验。
- 添加了加载状态指示,改善了文件详情的展示效果。
- 新增分页功能,提升了文件列表的可用性。
This commit is contained in:
Wenjie Zhang 2025-05-26 13:59:05 +08:00
parent d9802414f1
commit 9d2604801d
2 changed files with 72 additions and 25 deletions

View File

@ -106,7 +106,7 @@ class KnowledgeBase:
"""根据ID获取知识库"""
with db_manager.get_session_context() as session:
db = session.query(KnowledgeDatabase).options(
joinedload(KnowledgeDatabase.files).joinedload(KnowledgeFile.nodes)
joinedload(KnowledgeDatabase.files)
).filter_by(db_id=db_id).first()
return db.to_dict() if db else None # Assuming to_dict handles files and nodes

View File

@ -135,7 +135,7 @@
</div>
</div>
</div>
<a-table :columns="columns" :data-source="Object.values(database.files || {})" row-key="file_id" class="my-table">
<a-table :columns="columns" :data-source="Object.values(database.files || {})" row-key="file_id" class="my-table" size="small" bordered :pagination="pagination" >
<template #bodyCell="{ column, text, record }">
<template v-if="column.key === 'filename'">
<a-tooltip :title="record.file_id" placement="right">
@ -183,19 +183,28 @@
<span v-else>{{ text }}</span>
</template>
</a-table>
<a-drawer
width="50%"
v-model:open="state.drawer"
<a-modal
v-model:open="state.fileDetailModalVisible"
class="custom-class"
:title="selectedFile?.filename || '文件详情'"
placement="right"
@after-open-change="afterOpenChange"
width="1000px"
@after-open="afterOpenChange"
:footer="null"
>
<h2> {{ selectedFile?.lines?.length || 0 }} 个片段</h2>
<p v-for="line in selectedFile?.lines || []" :key="line.id" class="line-text">
{{ line.text }}
</p>
</a-drawer>
<template v-if="state.fileDetailLoading">
<div class="loading-container">
<a-spin tip="加载中..." />
</div>
</template>
<template v-else>
<h2> {{ selectedFile?.lines?.length || 0 }} 个片段</h2>
<div class="file-detail-content">
<p v-for="line in selectedFile?.lines || []" :key="line.id" class="line-text">
{{ line.text }}
</p>
</div>
</template>
</a-modal>
</div>
</a-tab-pane>
@ -364,7 +373,8 @@ const state = reactive({
refrashing: false,
searchLoading: false,
lock: false,
drawer: false,
fileDetailModalVisible: false,
fileDetailLoading: false,
refreshInterval: null,
curPage: "files",
indexingFile: null,
@ -394,6 +404,13 @@ const use_rewrite_queryOptions = ref([
{ value: 'hyde', payload: { title: 'hyde', subTitle: '伪文档生成' } },
])
const pagination = ref({
pageSize: 30,
current: 1,
total: 0,
showTotal: (total, range) => `${total}`,
})
const filterQueryResults = () => {
if (!queryResult.value || !queryResult.value.all_results) {
return;
@ -531,33 +548,49 @@ const deleteDatabse = () => {
}
const openFileDetail = (record) => {
state.lock = true
//
state.fileDetailModalVisible = true;
selectedFile.value = {
...record,
lines: []
};
//
state.fileDetailLoading = true;
state.lock = true;
try {
knowledgeBaseApi.getDocumentDetail(databaseId.value, record.file_id)
.then(data => {
console.log(data)
console.log(data);
if (data.status == "failed") {
message.error(data.message)
return
message.error(data.message);
state.fileDetailModalVisible = false;
return;
}
state.lock = false
selectedFile.value = {
...record,
lines: data.lines || []
}
state.drawer = true
};
})
.catch(error => {
console.error(error)
message.error(error.message)
console.error(error);
message.error(error.message);
state.fileDetailModalVisible = false;
})
.finally(() => {
state.fileDetailLoading = false;
state.lock = false;
});
} catch (error) {
console.error(error)
message.error('获取文件详情失败')
state.lock = false
console.error(error);
message.error('获取文件详情失败');
state.fileDetailLoading = false;
state.lock = false;
state.fileDetailModalVisible = false;
}
}
const formatRelativeTime = (timestamp) => {
// UTC+8
const timezoneOffset = 8 * 60 * 60 * 1000; //
@ -1245,9 +1278,16 @@ const handleIndexFile = (fileId) => {
}
}
.file-detail-content {
max-height: 60vh;
overflow-y: auto;
padding: 0 10px;
}
.custom-class .line-text {
padding: 10px;
border-radius: 4px;
margin: 8px 0;
&:hover {
background-color: var(--main-light-4);
@ -1410,6 +1450,13 @@ const handleIndexFile = (fileId) => {
margin-top: 5px;
line-height: 1.5;
}
.loading-container {
display: flex;
justify-content: center;
align-items: center;
min-height: 200px;
}
</style>
<style lang="less">