Browse Source

all

hanyuqing
hanyuqing 3 months ago
parent
commit
83c2d20126
  1. 5
      controller/QAController.py
  2. 13
      vue/src/system/GraphBuilder.vue
  3. 128
      vue/src/system/GraphQA.vue

5
controller/QAController.py

@ -25,7 +25,10 @@ def convert_to_g6_format(data):
nodes.append({
"id": node_id,
"label": name,
"data":{
"type": ent["t"] # 可用于 G6 的节点样式区分
}
})
# 构建边
@ -42,7 +45,9 @@ def convert_to_g6_format(data):
edges.append({
"source": source_id,
"target": target_id,
"data": {
"label": r
}
})
else:
print(f"Warning: Entity not found for relation: {rel}")

13
vue/src/system/GraphBuilder.vue

@ -28,7 +28,7 @@
</div>
<div v-if="msg.role === 'user'" style="display: flex;align-items: flex-start; justify-content: flex-end;">
<div class="bubble">
<div class="bubble" v-if="msg.content">
{{ msg.content }}
</div>
@ -51,7 +51,7 @@
:id="'entity-' + i"
:value="ent"
v-model="ent.selected"
@click="handleEntitySelectionChange(msg,ent)"
@change="handleEntitySelectionChange(msg,ent)"
/>
<!-- 使用 for 关联到 input id -->
<label
@ -508,7 +508,8 @@ export default {
this.messages.forEach((message) => {
this.saveMessage(message);
});
}
},
},
watch: {
messages() {
@ -519,6 +520,12 @@ export default {
const container = this.$refs.messagesContainer;
container.removeEventListener('scroll', this.handleScroll);
},
beforeRouteLeave(to, from, next) {
console.log('【守卫触发】离开 /graph 路由');
// alert(''); //
this.handleBeforeUnload();
next();
},
mounted() {
const container = this.$refs.messagesContainer;
container.addEventListener('scroll', this.handleScroll);

128
vue/src/system/GraphQA.vue

@ -19,6 +19,7 @@
v-model="query"
placeholder="请输入问题..."
clearable
@keydown.enter="handleSearch"
/>
<el-button type="primary" @click="handleSearch" style=" background: #114FE6;">查询</el-button>
</div>
@ -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 {
},
},
};

Loading…
Cancel
Save