From 83c2d201261cbee630e447f87ce4a02f4b001c79 Mon Sep 17 00:00:00 2001
From: hanyuqing <1106611654@qq.com>
Date: Wed, 31 Dec 2025 15:55:26 +0800
Subject: [PATCH] all
---
controller/QAController.py | 9 ++-
vue/src/system/GraphBuilder.vue | 13 +++-
vue/src/system/GraphQA.vue | 128 +++++++++++++++++++++++++++++++++-------
3 files changed, 125 insertions(+), 25 deletions(-)
diff --git a/controller/QAController.py b/controller/QAController.py
index 0613334..48fe2dd 100644
--- a/controller/QAController.py
+++ b/controller/QAController.py
@@ -25,7 +25,10 @@ def convert_to_g6_format(data):
nodes.append({
"id": node_id,
"label": name,
- "type": ent["t"] # 可用于 G6 的节点样式区分
+ "data":{
+ "type": ent["t"] # 可用于 G6 的节点样式区分
+ }
+
})
# 构建边
@@ -42,7 +45,9 @@ def convert_to_g6_format(data):
edges.append({
"source": source_id,
"target": target_id,
- "label": r
+ "data": {
+ "label": r
+ }
})
else:
print(f"Warning: Entity not found for relation: {rel}")
diff --git a/vue/src/system/GraphBuilder.vue b/vue/src/system/GraphBuilder.vue
index 1cd39e4..7640e46 100644
--- a/vue/src/system/GraphBuilder.vue
+++ b/vue/src/system/GraphBuilder.vue
@@ -28,7 +28,7 @@
-
+
{{ msg.content }}
@@ -51,7 +51,7 @@
:id="'entity-' + i"
:value="ent"
v-model="ent.selected"
- @click="handleEntitySelectionChange(msg,ent)"
+ @change="handleEntitySelectionChange(msg,ent)"
/>
@@ -103,13 +104,96 @@ export default {
};
},
+ // =============== 👇【新增】组件内路由守卫:离开当前路由时触发 ===============
+ beforeRouteLeave(to, from, next) {
+ this.saveDataToLocalStorage();
+ next(); // 允许导航
+ },
+ // =======================================================================
+
+ mounted() {
+ // =============== 👇【新增】页面加载时从 localStorage 恢复数据 ===============
+ this.restoreDataFromLocalStorage();
+ // =======================================================================
+
+ // 如果有初始数据,可以初始化图谱(可选)
+ if (this.answers.length > 0) {
+ this.initGraph(this.answers[0].result);
+ }
+ },
+
+ beforeUnmount() {
+ // =============== 👇【新增】组件销毁前也保存一次(兼容非路由跳转场景)==============
+ this.saveDataToLocalStorage();
+ // 移除页面卸载监听(如果用了 beforeunload)
+ window.removeEventListener('beforeunload', this.handleBeforeUnload);
+ // =======================================================================
+ },
+
+ created() {
+ // =============== 👇【新增】监听页面刷新/关闭事件 ===============
+ window.addEventListener('beforeunload', this.handleBeforeUnload);
+ // =======================================================================
+ },
methods: {
+ buildNodeLabelMap(nodes) {
+ this._nodeLabelMap = new Map();
+ nodes.forEach(node => {
+ this._nodeLabelMap.set(node.id, node.data?.type || 'default');
+ });
+ },
+// =============== 👇【新增】统一的数据保存方法 ===============
+ saveDataToLocalStorage() {
+ try {
+ localStorage.setItem('graphQA_queryRecord', this.queryRecord);
+ localStorage.setItem('graphQA_answers', JSON.stringify(this.answers));
+ console.log('✅ 数据已保存到 localStorage');
+ } catch (e) {
+ console.warn('⚠️ 无法保存到 localStorage:', e);
+ }
+ },
+ // =======================================================================
+
+ // =============== 👇【新增】统一的数据恢复方法 ===============
+ restoreDataFromLocalStorage() {
+ try {
+ const savedQuery = localStorage.getItem('graphQA_queryRecord');
+ const savedAnswers = localStorage.getItem('graphQA_answers');
+
+ if (savedQuery !== null) {
+ this.queryRecord = savedQuery;
+ }
+ if (savedAnswers !== null) {
+ this.answers = JSON.parse(savedAnswers);
+ // 确保 selected 不越界
+ if (this.answers.length > 0) {
+ this.selected = Math.min(this.selected, this.answers.length - 1);
+ }
+ }
+ console.log('✅ 数据已从 localStorage 恢复');
+ } catch (e) {
+ console.warn('⚠️ 无法从 localStorage 恢复数据:', e);
+ // 出错时清空(避免脏数据)
+ localStorage.removeItem('graphQA_queryRecord');
+ localStorage.removeItem('graphQA_answers');
+ }
+ },
+ // =======================================================================
+
+ // =============== 👇【新增】处理页面关闭/刷新的兜底保存 ===============
+ handleBeforeUnload(event) {
+ this.saveDataToLocalStorage();
+ // 注意:现代浏览器通常不显示自定义消息
+ event.preventDefault();
+ event.returnValue = ''; // 必须设置才能触发提示(但实际可能不显示)
+ },
selectGraph(index){
this.selected=index
this.formatData(this.answers[index].result)
},
handleSearch(){
this.answers=[]
+ this.formatData([])
let data={
text:this.query
}
@@ -127,8 +211,8 @@ export default {
})
},
formatData(data){
- this._graph.stopLayout();
- this.clearGraphState();
+ // this._graph.stopLayout();
+ // this.clearGraphState();
const updatedEdges = data.edges.map(edge => ({
...edge,
type: this.edgeType,
@@ -204,6 +288,7 @@ export default {
nodes: updatedNodes,
edges: updatedEdges
}
+ this.buildNodeLabelMap(updatedNodes);
const container = this.$refs.graphContainer;
console.log(container)
if (container!=null){
@@ -241,19 +326,20 @@ export default {
node: {
style: {
fill: (d) => {
- const label = d?.type;
- if (label === 'Disease') return '#EF4444'; // 红
- if (label === 'Drug') return '#91cc75'; // 绿
- if (label === 'Symptom') return '#fac858'; // 橙
- if (label === 'Check') return '#336eee'; // 橙
+
+ const label = d.data?.type;
+ if (label === '疾病') return '#EF4444'; // 红
+ if (label === '药品'||label === '药物') return '#91cc75'; // 绿
+ if (label === '症状') return '#fac858'; // 橙
+ if (label === '检查') return '#336eee'; // 橙
return '#59d1d4'; // 默认灰蓝
},
stroke: (d) => {
- const label = d?.type;
- if (label === 'Disease') return '#B91C1C';
- if (label === 'Drug') return '#047857';
- if (label === 'Check') return '#1D4ED8'; // 橙
- if (label === 'Symptom') return '#B45309';
+ const label = d.data?.type;
+ if (label === '疾病') return '#B91C1C';
+ if (label === '药品'||label === '药物') return '#047857';
+ if (label === '检查') return '#1D4ED8'; // 橙
+ if (label === '症状') return '#B45309';
return '#40999b';
},
labelText: (d) => d.label,
@@ -282,17 +368,18 @@ export default {
},
},
+
edge: {
style: {
- labelText: (d) => d.label,
+ labelText: (d) => {
+ console.log(d)
+ return d.data.label},
stroke: (d) => {
- // 获取 target 节点的 label
- // const targetLabel = this._nodeLabelMap.get(d.source); // d.target 是目标节点 ID
- // // 根据 target 节点类型返回对应浅色
- // if (targetLabel === 'Disease') return 'rgba(239,68,68,0.5)';
- // if (targetLabel === 'Drug') return 'rgba(145,204,117,0.5)';
- // if (targetLabel === 'Symptom') return 'rgba(250,200,88,0.5)';
- // if (targetLabel === 'Check') return 'rgba(51,110,238,0.5)'; // 橙
+ const targetLabel = this._nodeLabelMap.get(d.source); // d.target 是目标节点 ID
+ if (targetLabel === '疾病') return 'rgba(239,68,68,0.5)';
+ if (targetLabel === '药品'||targetLabel === '药物') return 'rgba(145,204,117,0.5)';
+ if (targetLabel === '症状') return 'rgba(250,200,88,0.5)';
+ if (targetLabel === '检查') return 'rgba(51,110,238,0.5)'; // 橙
return 'rgba(89,209,212,0.5)'; // default
},
// labelFill: (d) => {
@@ -342,6 +429,7 @@ export default {
},
+
},
};