137 lines
5.2 KiB
Vue
137 lines
5.2 KiB
Vue
<template>
|
|
<div style="padding:16px">
|
|
<div style="margin-bottom:16px;display:flex;justify-content:space-between;align-items:center">
|
|
<span style="font-size:18px;font-weight:bold">实体关系管理</span>
|
|
<div>
|
|
<el-button type="primary" @click="loadData">刷新</el-button>
|
|
<el-button type="success" @click="showForm = true">新增关系</el-button>
|
|
</div>
|
|
</div>
|
|
|
|
<el-card shadow="never" style="margin-bottom:16px">
|
|
<el-form inline>
|
|
<el-form-item label="源实体类型">
|
|
<el-select v-model="filters.sourceType" clearable placeholder="全部" style="width:130px">
|
|
<el-option v-for="t in entityTypes" :key="t.code" :label="t.name" :value="t.code" />
|
|
</el-select>
|
|
</el-form-item>
|
|
<el-form-item label="目标实体类型">
|
|
<el-select v-model="filters.targetType" clearable placeholder="全部" style="width:130px">
|
|
<el-option v-for="t in entityTypes" :key="t.code" :label="t.name" :value="t.code" />
|
|
</el-select>
|
|
</el-form-item>
|
|
<el-form-item label="关系类型">
|
|
<el-select v-model="filters.relationType" clearable placeholder="全部" style="width:150px">
|
|
<el-option v-for="r in relationTypes" :key="r.code" :label="r.name" :value="r.code" />
|
|
</el-select>
|
|
</el-form-item>
|
|
<el-form-item>
|
|
<el-button type="primary" @click="loadData">搜索</el-button>
|
|
<el-button @click="resetFilters">重置</el-button>
|
|
</el-form-item>
|
|
</el-form>
|
|
</el-card>
|
|
|
|
<el-table v-loading="loading" :data="tableData" border stripe>
|
|
<el-table-column prop="sourceType" label="源实体类型" width="120" align="center">
|
|
<template #default="{row}">
|
|
<el-tag size="small" :style="{background: typeColor(row.sourceType), color:'#fff', border:'none'}">
|
|
{{ typeName(row.sourceType) }}
|
|
</el-tag>
|
|
</template>
|
|
</el-table-column>
|
|
<el-table-column prop="sourceId" label="源实体ID" width="140" show-overflow-tooltip />
|
|
<el-table-column prop="targetType" label="目标实体类型" width="120" align="center">
|
|
<template #default="{row}">
|
|
<el-tag size="small" :style="{background: typeColor(row.targetType), color:'#fff', border:'none'}">
|
|
{{ typeName(row.targetType) }}
|
|
</el-tag>
|
|
</template>
|
|
</el-table-column>
|
|
<el-table-column prop="targetId" label="目标实体ID" width="140" show-overflow-tooltip />
|
|
<el-table-column prop="relationType" label="关系类型" width="140" align="center">
|
|
<template #default="{row}">
|
|
<el-tag size="small" type="warning">{{ relationName(row.relationType) }}</el-tag>
|
|
</template>
|
|
</el-table-column>
|
|
<el-table-column prop="relationStrength" label="强度" width="80" align="center" />
|
|
<el-table-column prop="description" label="描述" min-width="150" show-overflow-tooltip />
|
|
<el-table-column prop="createTime" label="创建时间" width="160" />
|
|
</el-table>
|
|
|
|
<el-pagination
|
|
v-model:current-page="pageNo"
|
|
v-model:page-size="pageSize"
|
|
style="margin-top:12px;justify-content:flex-end"
|
|
:total="total"
|
|
layout="total, sizes, prev, pager, next, jumper"
|
|
@size-change="loadData"
|
|
@current-change="loadData"
|
|
/>
|
|
|
|
<RelationForm v-model:visible="showForm" @success="loadData" />
|
|
</div>
|
|
</template>
|
|
|
|
<script setup>
|
|
import { ref, onMounted } from 'vue'
|
|
import { getRelationPage } from '@/api/knowledgegraph/api'
|
|
import RelationForm from './RelationForm.vue'
|
|
|
|
const loading = ref(false)
|
|
const tableData = ref([])
|
|
const total = ref(0)
|
|
const pageNo = ref(1)
|
|
const pageSize = ref(10)
|
|
const showForm = ref(false)
|
|
|
|
const filters = ref({ sourceType: '', targetType: '', relationType: '' })
|
|
|
|
const entityTypes = [
|
|
{ code: 'disease', name: '疾病' },
|
|
{ code: 'symptom', name: '症状' },
|
|
{ code: 'drug', name: '药物' },
|
|
{ code: 'exam', name: '检查' }
|
|
]
|
|
|
|
const relationTypes = [
|
|
{ code: 'CAUSES', name: '导致' },
|
|
{ code: 'TREATS', name: '治疗' },
|
|
{ code: 'CONTRAINDICATES', name: '禁忌' },
|
|
{ code: 'INTERACTS_WITH', name: '相互作用' },
|
|
{ code: 'REQUIRES_EXAM', name: '需要检查' },
|
|
{ code: 'HAS_SYMPTOM', name: '具有症状' },
|
|
{ code: 'SIDE_EFFECT', name: '副作用' },
|
|
{ code: 'ALTERNATIVE', name: '替代' }
|
|
]
|
|
|
|
const typeColorMap = { disease: '#f56c6c', symptom: '#409eff', drug: '#67c23a', exam: '#e6a23c' }
|
|
const typeColor = (t) => typeColorMap[t] || '#909399'
|
|
const typeName = (t) => (entityTypes.find(e => e.code === t) || {}).name || t
|
|
const relationName = (r) => (relationTypes.find(e => e.code === r) || {}).name || r
|
|
|
|
function resetFilters() {
|
|
filters.value = { sourceType: '', targetType: '', relationType: '' }
|
|
loadData()
|
|
}
|
|
|
|
async function loadData() {
|
|
loading.value = true
|
|
try {
|
|
const r = await getRelationPage({
|
|
sourceType: filters.value.sourceType,
|
|
targetType: filters.value.targetType,
|
|
relationType: filters.value.relationType,
|
|
pageNo: pageNo.value,
|
|
pageSize: pageSize.value
|
|
})
|
|
tableData.value = r.data?.records || []
|
|
total.value = r.data?.total || 0
|
|
} finally {
|
|
loading.value = false
|
|
}
|
|
}
|
|
|
|
onMounted(() => loadData())
|
|
</script>
|