refactor(ui): 移除导出数据按钮并优化上传文件提示

重构多个面板组件,移除重复的导出数据按钮和相关样式代码
在GraphView中添加上传文件提示弹窗,根据数据库类型显示不同提示信息
This commit is contained in:
Wenjie Zhang 2025-12-16 00:27:40 +08:00
parent cb9edfdb5e
commit 75a7d46327
4 changed files with 89 additions and 102 deletions

View File

@ -97,7 +97,7 @@ const filteredEdgeProperties = computed(() => {
<style scoped lang="less"> <style scoped lang="less">
.detail-card { .detail-card {
position: fixed; // fixed position: absolute; // fixed
top: 80px; top: 80px;
right: 24px; right: 24px;
width: 300px; width: 300px;

View File

@ -12,10 +12,6 @@
<span v-if="graphInfo?.relationship_count" class="info-total">/ {{ graphInfo.relationship_count }}</span> <span v-if="graphInfo?.relationship_count" class="info-total">/ {{ graphInfo.relationship_count }}</span>
</div> </div>
<div v-if="graphInfo?.graph_name" class="info-item">
<span class="info-label">图谱</span>
<span class="info-value">{{ graphInfo.graph_name }}</span>
</div>
<div v-if="unindexedCount > 0" class="info-item warning"> <div v-if="unindexedCount > 0" class="info-item warning">
<span class="info-label">未索引</span> <span class="info-label">未索引</span>
@ -35,17 +31,10 @@
</a-tooltip> </a-tooltip>
</div> </div>
<div class="actions">
<a-button type="default" size="small" @click="$emit('export-data')">
<ExportOutlined />
导出数据
</a-button>
</div> </div>
</div>
</template> </template>
<script setup> <script setup>
import { ExportOutlined } from '@ant-design/icons-vue'
const props = defineProps({ const props = defineProps({
graphInfo: { graphInfo: {
@ -66,7 +55,7 @@ const props = defineProps({
} }
}) })
defineEmits(['index-nodes', 'export-data']) defineEmits(['index-nodes'])
</script> </script>
<style lang="less" scoped> <style lang="less" scoped>
@ -120,40 +109,6 @@ defineEmits(['index-nodes', 'export-data'])
font-size: 12px; font-size: 12px;
} }
.actions {
margin-left: auto;
display: flex;
gap: 8px;
@media (max-width: 768px) {
margin-left: 0;
width: 100%;
justify-content: flex-end;
}
}
:deep(.ant-btn-default) {
font-size: 12px;
height: 28px;
padding: 0 12px;
border-radius: 6px;
border-color: var(--main-300);
color: var(--main-600);
background: var(--main-20);
transition: all 0.2s ease;
&:hover {
border-color: var(--main-500);
color: var(--main-700);
background: var(--main-40);
box-shadow: 0 2px 4px rgba(1, 97, 121, 0.1);
}
&:active {
transform: translateY(1px);
}
}
:deep(.ant-btn-primary) { :deep(.ant-btn-primary) {
font-size: 12px; font-size: 12px;
height: 28px; height: 28px;

View File

@ -10,22 +10,11 @@
<span class="info-value">{{ stats?.total_edges || 0 }}</span> <span class="info-value">{{ stats?.total_edges || 0 }}</span>
</div> </div>
<div class="info-item">
<span class="info-label">知识库</span>
<span class="info-value">{{ databaseName }}</span>
</div>
<div class="actions"> </div>
<a-button type="default" size="small" @click="$emit('export-data')">
<ExportOutlined />
导出数据
</a-button>
</div>
</div>
</template> </template>
<script setup> <script setup>
import { ExportOutlined } from '@ant-design/icons-vue'
import { computed } from 'vue' import { computed } from 'vue'
const props = defineProps({ const props = defineProps({
@ -43,7 +32,6 @@ const props = defineProps({
} }
}) })
defineEmits(['export-data'])
</script> </script>
<style lang="less" scoped> <style lang="less" scoped>
@ -83,38 +71,4 @@ defineEmits(['export-data'])
color: var(--gray-1000); color: var(--gray-1000);
font-weight: 600; font-weight: 600;
} }
.actions {
margin-left: auto;
display: flex;
gap: 8px;
@media (max-width: 768px) {
margin-left: 0;
width: 100%;
justify-content: flex-end;
}
}
:deep(.ant-btn-default) {
font-size: 12px;
height: 28px;
padding: 0 12px;
border-radius: 6px;
border-color: var(--main-300);
color: var(--main-600);
background: var(--main-20);
transition: all 0.2s ease;
&:hover {
border-color: var(--main-500);
color: var(--main-700);
background: var(--main-40);
box-shadow: 0 2px 4px rgba(1, 97, 121, 0.1);
}
&:active {
transform: translateY(1px);
}
}
</style> </style>

View File

@ -30,7 +30,14 @@
<!-- <a-button type="default" @click="openLink('http://localhost:7474/')" :icon="h(GlobalOutlined)"> <!-- <a-button type="default" @click="openLink('http://localhost:7474/')" :icon="h(GlobalOutlined)">
Neo4j 浏览器 Neo4j 浏览器
</a-button> --> </a-button> -->
<a-button type="primary" @click="state.showModal = true" ><UploadOutlined/> 上传文件</a-button> <a-button
v-if="isNeo4j"
type="primary"
@click="state.showModal = true" ><UploadOutlined/> 上传文件</a-button>
<a-button
v-else
type="primary"
@click="state.showUploadTipModal = true" ><UploadOutlined/> 上传文件</a-button>
<a-button v-if="unindexedCount > 0" type="primary" @click="indexNodes" :loading="state.indexing"> <a-button v-if="unindexedCount > 0" type="primary" @click="indexNodes" :loading="state.indexing">
<SyncOutlined v-if="!state.indexing"/> {{ unindexedCount }}个节点添加索引 <SyncOutlined v-if="!state.indexing"/> {{ unindexedCount }}个节点添加索引
</a-button> </a-button>
@ -73,6 +80,9 @@
</a-input> </a-input>
</div> </div>
<div class="actions-right"> <div class="actions-right">
<a-button type="default" @click="exportGraphData" :icon="h(ExportOutlined)">
导出数据
</a-button>
<a-button type="default" @click="state.showInfoModal = true" :icon="h(InfoCircleOutlined)"> <a-button type="default" @click="state.showInfoModal = true" :icon="h(InfoCircleOutlined)">
说明 说明
</a-button> </a-button>
@ -91,14 +101,12 @@
:unindexed-count="unindexedCount" :unindexed-count="unindexedCount"
:model-matched="modelMatched" :model-matched="modelMatched"
@index-nodes="indexNodes" @index-nodes="indexNodes"
@export-data="exportGraphData"
/> />
<LightRAGInfoPanel <LightRAGInfoPanel
v-else v-else
:stats="state.lightragStats" :stats="state.lightragStats"
:graph-data="graph.graphData" :graph-data="graph.graphData"
:database-name="getDatabaseName()" :database-name="getDatabaseName()"
@export-data="exportGraphData"
/> />
</div> </div>
</template> </template>
@ -144,6 +152,32 @@
</div> </div>
</a-modal> </a-modal>
<!-- 上传提示弹窗 -->
<a-modal
:open="state.showUploadTipModal"
title="文件上传说明"
@cancel="() => state.showUploadTipModal = false"
:footer="null"
width="500px"
>
<div class="upload-tip-content">
<a-alert
:message="getUploadTipMessage()"
type="info"
show-icon
style="margin-bottom: 16px;"
/>
<div v-if="!isNeo4j" class="upload-tip-actions">
<p>如需上传文档到当前选中的知识库请前往对应的知识库详情页面进行操作</p>
<div class="action-buttons">
<a-button type="primary" @click="goToDatabasePage">
<DatabaseOutlined/> 前往知识库详情页
</a-button>
</div>
</div>
</div>
</a-modal>
<!-- 说明弹窗 --> <!-- 说明弹窗 -->
<a-modal <a-modal
:open="state.showInfoModal" :open="state.showInfoModal"
@ -176,9 +210,10 @@
<script setup> <script setup>
import { computed, onMounted, reactive, ref, h } from 'vue'; import { computed, onMounted, reactive, ref, h } from 'vue';
import { useRouter } from 'vue-router';
import { message } from 'ant-design-vue'; import { message } from 'ant-design-vue';
import { useConfigStore } from '@/stores/config'; import { useConfigStore } from '@/stores/config';
import { UploadOutlined, SyncOutlined, GlobalOutlined, InfoCircleOutlined, SearchOutlined, ReloadOutlined, LoadingOutlined, HighlightOutlined } from '@ant-design/icons-vue'; import { UploadOutlined, SyncOutlined, GlobalOutlined, InfoCircleOutlined, SearchOutlined, ReloadOutlined, LoadingOutlined, HighlightOutlined, DatabaseOutlined, ExportOutlined } from '@ant-design/icons-vue';
import HeaderComponent from '@/components/HeaderComponent.vue'; import HeaderComponent from '@/components/HeaderComponent.vue';
import { neo4jApi, unifiedApi } from '@/apis/graph_api'; import { neo4jApi, unifiedApi } from '@/apis/graph_api';
import { useUserStore } from '@/stores/user'; import { useUserStore } from '@/stores/user';
@ -193,6 +228,7 @@ const configStore = useConfigStore();
const cur_embed_model = computed(() => configStore.config?.embed_model); const cur_embed_model = computed(() => configStore.config?.embed_model);
const modelMatched = computed(() => !graphInfo?.value?.embed_model_name || graphInfo.value.embed_model_name === cur_embed_model.value) const modelMatched = computed(() => !graphInfo?.value?.embed_model_name || graphInfo.value.embed_model_name === cur_embed_model.value)
const router = useRouter();
const graphRef = ref(null) const graphRef = ref(null)
const graphInfo = ref(null) const graphInfo = ref(null)
const fileList = ref([]); const fileList = ref([]);
@ -207,6 +243,7 @@ const state = reactive({
searchLoading: false, searchLoading: false,
showModal: false, showModal: false,
showInfoModal: false, showInfoModal: false,
showUploadTipModal: false,
processing: false, processing: false,
indexing: false, indexing: false,
showPage: true, showPage: true,
@ -458,6 +495,33 @@ const getDatabaseName = () => {
return selectedDb ? selectedDb.label : state.selectedDbId; return selectedDb ? selectedDb.label : state.selectedDbId;
}; };
const getUploadTipMessage = () => {
if (isNeo4j.value) {
return 'Neo4j 图数据库支持通过上传 JSONL 格式文件直接导入实体和关系数据。';
} else {
const selectedDb = state.dbOptions.find(db => db.value === state.selectedDbId);
const dbType = selectedDb?.type || '未知';
const dbName = selectedDb?.label || getDatabaseName();
return `当前选择的是 ${dbType.toUpperCase()} 类型的知识库"${dbName}",该类型知识库需要在文档知识库页面上传文档,系统会自动从中提取知识图谱。`;
}
};
const goToDatabasePage = () => {
state.showUploadTipModal = false;
// Neo4j ID
if (!isNeo4j.value) {
const selectedDb = state.dbOptions.find(db => db.value === state.selectedDbId);
if (selectedDb && selectedDb.type !== 'neo4j') {
//
router.push(`/database/${state.selectedDbId}`);
} else {
//
router.push('/database');
}
}
};
</script> </script>
<style lang="less" scoped> <style lang="less" scoped>
@ -478,9 +542,8 @@ const getDatabaseName = () => {
margin-right: 20px; margin-right: 20px;
.label { .label {
font-size: 14px;
margin-right: 8px; margin-right: 8px;
font-weight: 500;
color: var(--color-text-secondary);
} }
} }
@ -579,4 +642,19 @@ const getDatabaseName = () => {
box-shadow: none; box-shadow: none;
} }
} }
.upload-tip-content {
.upload-tip-actions {
p {
margin-bottom: 16px;
color: var(--color-text-secondary);
}
}
.action-buttons {
display: flex;
justify-content: center;
margin-top: 20px;
}
}
</style> </style>