fix(GraphView): 修复文件上传和模态框关闭逻辑

添加文件上传状态验证和错误处理
修复模态框关闭时未清空文件列表的问题
统一搜索框的占位文本
移除不再使用的说明弹窗组件
This commit is contained in:
Wenjie Zhang 2025-12-20 14:51:02 +08:00
parent e04213f1e8
commit 92518e5bbc

View File

@ -25,6 +25,8 @@
:options="state.dbOptions"
@change="handleDbChange"
:loading="state.loadingDatabases"
mode="combobox"
placeholder="选择或输入KB ID"
/>
</div>
<!-- <a-button type="default" @click="openLink('http://localhost:7474/')" :icon="h(GlobalOutlined)">
@ -58,7 +60,7 @@
<div class="actions-left">
<a-input
v-model:value="state.searchInput"
:placeholder="isNeo4j ? '输入要查询的实体' : '输入要查询的实体 (*为全部)'"
placeholder="输入要查询的实体 (*为全部)"
style="width: 300px"
@keydown.enter="onSearch"
allow-clear
@ -125,9 +127,10 @@
<a-modal
:open="state.showModal" title="上传文件"
@ok="addDocumentByFile"
@cancel="() => state.showModal = false"
@cancel="handleModalCancel"
ok-text="添加到图数据库" cancel-text="取消"
:confirm-loading="state.processing">
:confirm-loading="state.processing"
:ok-button-props="{ disabled: !hasValidFile }">
<div class="upload">
<div class="note">
<p>上传的文件内容参考 test/data/A_Dream_of_Red_Mansions_tiny.jsonl 中的格式</p>
@ -177,34 +180,6 @@
</div>
</div>
</a-modal>
<!-- 说明弹窗 -->
<a-modal
:open="state.showInfoModal"
title="图数据库说明"
@cancel="() => state.showInfoModal = false"
:footer="null"
width="600px"
>
<div class="info-content" v-if="isNeo4j">
<p>本页面展示的是 Neo4j 图数据库中的知识图谱信息</p>
<p>具体展示内容包括</p>
<ul>
<li>带有 <code>Entity</code> 标签的节点</li>
<li>带有 <code>RELATION</code> 类型的关系边</li>
</ul>
<p>注意</p>
<ul>
<li>这里仅展示用户上传的实体和关系不包含知识库中自动创建的图谱</li>
<li>查询逻辑基于 <code>graphbase.py</code> 中的 <code>get_sample_nodes</code> 方法实现</li>
</ul>
</div>
<div class="info-content" v-else>
<p>本页面展示的是 LightRAG 知识库生成的图谱信息</p>
<p>数据来源于选定的知识库实例</p>
<p>支持通过实体名称进行模糊搜索输入 "*" 可查看采样全图</p>
</div>
</a-modal>
</div>
</template>
@ -252,7 +227,21 @@ const state = reactive({
lightragStats: null,
})
const isNeo4j = computed(() => state.selectedDbId === 'neo4j');
const isNeo4j = computed(() => {
// selectedDbId 'neo4j' 'kb_' Neo4j
// kb_ 使 LightRAGInfoPanel stats
// GraphInfoPanel
// GraphInfoPanel 'neo4j' model matching
// KBs (kb_*) 使 Neo4j LightRAG ""
// LightRAGInfoPanel stats (get_stats kb_),
// kb_ ID false LightRAGInfoPanel
return state.selectedDbId === 'neo4j';
});
//
const hasValidFile = computed(() => {
return fileList.value.some(file => file.status === 'done' && file.response?.file_path);
});
//
const unindexedCount = computed(() => {
@ -293,7 +282,7 @@ const handleDbChange = () => {
if (isNeo4j.value) {
loadGraphInfo();
} else {
// Also load stats for LightRAG
// Also load stats for LightRAG or KB
loadLightRAGStats();
}
loadSampleNodes();
@ -323,13 +312,37 @@ const loadGraphInfo = () => {
}
const addDocumentByFile = () => {
// 使
if (!hasValidFile.value) {
message.error('请先等待文件上传完成')
return
}
state.processing = true
const files = fileList.value.filter(file => file.status === 'done').map(file => file.response.file_path)
neo4jApi.addEntities(files[0])
//
const uploadedFile = fileList.value.find(file => file.status === 'done' && file.response?.file_path);
const filePath = uploadedFile?.response?.file_path;
//
if (!filePath) {
message.error('文件路径获取失败,请重新上传文件')
state.processing = false
return
}
neo4jApi.addEntities(filePath)
.then((data) => {
if (data.status === 'success') {
message.success(data.message);
state.showModal = false;
//
fileList.value = [];
//
setTimeout(() => {
loadGraphInfo();
loadSampleNodes();
}, 500);
} else {
throw new Error(data.message);
}
@ -372,11 +385,6 @@ const onSearch = () => {
//
}
if (!state.searchInput && isNeo4j.value) {
message.error('请输入要查询的实体')
return
}
state.searchLoading = true
unifiedApi.getSubgraph({
@ -409,9 +417,22 @@ onMounted(async () => {
loadSampleNodes();
});
const handleFileUpload = (event) => {
console.log(event)
console.log(fileList.value)
const handleFileUpload = ({ file, fileList: newFileList }) => {
//
fileList.value = newFileList;
//
if (file.status === 'error') {
message.error(`文件上传失败: ${file.name}`);
}
//
if (file.status === 'done' && file.response?.file_path) {
message.success(`文件上传成功: ${file.name}`);
}
console.log('File upload status:', file.status, file.name);
console.log('File list:', fileList.value);
}
const handleDrop = (event) => {
@ -419,6 +440,12 @@ const handleDrop = (event) => {
console.log(fileList.value)
}
const handleModalCancel = () => {
state.showModal = false;
//
fileList.value = [];
};
const graphStatusClass = computed(() => {
if (state.loadingGraphInfo) return 'loading';
return graphInfo.value?.status === 'open' ? 'open' : 'closed';