AutoMedinfo/frontend/src/views/inquiry/DataSourceSelection.vue

442 lines
12 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="data-source-selection">
<el-card v-loading="loading">
<template #header>
<div class="card-header">
<span>选择数据源 - {{ inquiry.requestNumber }}</span>
<el-button @click="goBack" text>返回</el-button>
</div>
</template>
<!-- 关键词展示 -->
<el-alert
title="已确认的关键词"
type="success"
:closable="false"
style="margin-bottom: 20px;"
>
<div class="keywords-display">
<el-tag
v-if="keywords.drugNameChinese"
type="success"
size="large"
style="margin-right: 10px;"
>
{{ keywords.drugNameChinese }}
</el-tag>
<el-tag
v-if="keywords.drugNameEnglish"
type="primary"
size="large"
style="margin-right: 10px;"
>
{{ keywords.drugNameEnglish }}
</el-tag>
<el-tag
v-if="keywords.requestItem"
type="warning"
size="large"
style="margin-right: 10px;"
>
{{ keywords.requestItem }}
</el-tag>
<el-tag
v-for="(tag, index) in keywords.additionalKeywords"
:key="index"
type="info"
size="large"
style="margin-right: 10px;"
>
{{ tag }}
</el-tag>
</div>
</el-alert>
<!-- 数据源选择 -->
<div class="source-selection">
<h3 style="margin-bottom: 20px;">请选择需要检索的数据源:</h3>
<el-form :model="form" label-position="top">
<el-row :gutter="20">
<el-col :span="12">
<el-card
shadow="hover"
:class="{ 'source-card': true, 'selected': form.searchInternalData }"
@click="toggleSource('searchInternalData')"
>
<div class="source-content">
<el-checkbox
v-model="form.searchInternalData"
size="large"
@click.stop
/>
<div class="source-info">
<div class="source-title">
<el-icon :size="24" color="#409EFF"><Document /></el-icon>
<span>内部数据</span>
</div>
<div class="source-desc">
企业自有研究数据、历史回复记录、内部文献等
</div>
<el-tag size="small" type="primary">企业数据</el-tag>
</div>
</div>
</el-card>
</el-col>
<el-col :span="12">
<el-card
shadow="hover"
:class="{ 'source-card': true, 'selected': form.searchKnowledgeBase }"
@click="toggleSource('searchKnowledgeBase')"
>
<div class="source-content">
<el-checkbox
v-model="form.searchKnowledgeBase"
size="large"
@click.stop
/>
<div class="source-info">
<div class="source-title">
<el-icon :size="24" color="#67C23A"><FolderOpened /></el-icon>
<span>知识库</span>
</div>
<div class="source-desc">
已整理的企业知识库数据、专家意见等
</div>
<el-tag size="small" type="success">推荐</el-tag>
</div>
</div>
</el-card>
</el-col>
<el-col :span="12">
<el-card
shadow="hover"
:class="{ 'source-card': true, 'selected': form.searchCnki }"
@click="toggleSource('searchCnki')"
>
<div class="source-content">
<el-checkbox
v-model="form.searchCnki"
size="large"
@click.stop
/>
<div class="source-info">
<div class="source-title">
<el-icon :size="24" color="#E6A23C"><Reading /></el-icon>
<span>知网 (CNKI)</span>
</div>
<div class="source-desc">
中国知网学术文献数据库
</div>
<el-tag size="small" type="warning">中文文献</el-tag>
</div>
</div>
</el-card>
</el-col>
<el-col :span="12">
<el-card
shadow="hover"
:class="{ 'source-card': true, 'selected': form.searchClinicalTrials }"
@click="toggleSource('searchClinicalTrials')"
>
<div class="source-content">
<el-checkbox
v-model="form.searchClinicalTrials"
size="large"
@click.stop
/>
<div class="source-info">
<div class="source-title">
<el-icon :size="24" color="#F56C6C"><Experiment /></el-icon>
<span>ClinicalTrials.gov</span>
</div>
<div class="source-desc">
美国国家医学图书馆临床试验数据库
</div>
<el-tag size="small" type="danger">临床试验</el-tag>
</div>
</div>
</el-card>
</el-col>
</el-row>
</el-form>
<!-- 选择提示 -->
<el-alert
v-if="!hasSelectedSource"
title="请至少选择一个数据源"
type="warning"
:closable="false"
style="margin-top: 20px;"
/>
<el-alert
v-else
:title="`已选择 ${selectedCount} 个数据源`"
type="info"
:closable="false"
style="margin-top: 20px;"
>
<div>将在以下数据源中进行检索:{{ selectedSourcesText }}</div>
</el-alert>
<!-- 操作按钮 -->
<div class="action-buttons">
<el-button
type="primary"
size="large"
@click="handleConfirm"
:loading="confirming"
:disabled="!hasSelectedSource"
>
确认并开始检索
</el-button>
<el-button size="large" @click="handleSelectAll">
全选
</el-button>
<el-button size="large" @click="handleClearAll">
清空
</el-button>
<el-button size="large" @click="goBack">
返回
</el-button>
</div>
</div>
</el-card>
</div>
</template>
<script setup>
import { ref, reactive, computed, onMounted } from 'vue'
import { useRouter, useRoute } from 'vue-router'
import { getInquiryDetail, selectDataSources, performSearch } from '@/api/inquiry'
import { ElMessage, ElMessageBox } from 'element-plus'
import { Document, FolderOpened, Reading, Experiment } from '@element-plus/icons-vue'
const router = useRouter()
const route = useRoute()
const loading = ref(false)
const confirming = ref(false)
const inquiry = ref({})
const keywords = ref({})
const form = reactive({
searchInternalData: false,
searchKnowledgeBase: true, // 默认选中推荐项
searchCnki: false,
searchClinicalTrials: true // 默认选中推荐项
})
const hasSelectedSource = computed(() => {
return form.searchInternalData ||
form.searchKnowledgeBase ||
form.searchCnki ||
form.searchClinicalTrials
})
const selectedCount = computed(() => {
let count = 0
if (form.searchInternalData) count++
if (form.searchKnowledgeBase) count++
if (form.searchCnki) count++
if (form.searchClinicalTrials) count++
return count
})
const selectedSourcesText = computed(() => {
const sources = []
if (form.searchInternalData) sources.push('内部数据')
if (form.searchKnowledgeBase) sources.push('知识库')
if (form.searchCnki) sources.push('知网')
if (form.searchClinicalTrials) sources.push('ClinicalTrials.gov')
return sources.join('、')
})
onMounted(() => {
loadDetail()
})
const loadDetail = async () => {
loading.value = true
try {
const id = route.params.id
const data = await getInquiryDetail(id)
inquiry.value = data
// 解析关键词
if (data.keywords) {
try {
keywords.value = JSON.parse(data.keywords)
} catch (error) {
console.error('解析关键词失败', error)
}
}
// 如果已有数据源选择,恢复状态
if (data.searchInternalData !== null) {
form.searchInternalData = data.searchInternalData || false
}
if (data.searchKnowledgeBase !== null) {
form.searchKnowledgeBase = data.searchKnowledgeBase || false
}
if (data.searchCnki !== null) {
form.searchCnki = data.searchCnki || false
}
if (data.searchClinicalTrials !== null) {
form.searchClinicalTrials = data.searchClinicalTrials || false
}
} catch (error) {
ElMessage.error('加载详情失败')
} finally {
loading.value = false
}
}
const toggleSource = (source) => {
form[source] = !form[source]
}
const handleSelectAll = () => {
form.searchInternalData = true
form.searchKnowledgeBase = true
form.searchCnki = true
form.searchClinicalTrials = true
}
const handleClearAll = () => {
form.searchInternalData = false
form.searchKnowledgeBase = false
form.searchCnki = false
form.searchClinicalTrials = false
}
const handleConfirm = async () => {
if (!hasSelectedSource.value) {
ElMessage.warning('请至少选择一个数据源')
return
}
ElMessageBox.confirm(
`确认在以下数据源中检索:${selectedSourcesText.value}`,
'确认检索',
{
confirmButtonText: '开始检索',
cancelButtonText: '取消',
type: 'info'
}
).then(async () => {
confirming.value = true
try {
// 保存数据源选择
await selectDataSources(inquiry.value.id, form)
ElMessage.success('数据源选择已保存')
// 开始检索
await performSearch(inquiry.value.id)
ElMessage.success('检索已完成,正在跳转到结果页面...')
// 跳转到检索结果页面
router.push(`/inquiry/${inquiry.value.id}/search-results`)
} catch (error) {
ElMessage.error('操作失败: ' + (error.message || '未知错误'))
} finally {
confirming.value = false
}
}).catch(() => {
// 用户取消
})
}
const goBack = () => {
router.back()
}
</script>
<style scoped>
.data-source-selection {
width: 100%;
max-width: 1200px;
margin: 0 auto;
}
.card-header {
display: flex;
justify-content: space-between;
align-items: center;
}
.keywords-display {
padding: 10px 0;
}
.source-selection {
padding: 20px 0;
}
.source-card {
cursor: pointer;
transition: all 0.3s;
margin-bottom: 20px;
}
.source-card:hover {
transform: translateY(-5px);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}
.source-card.selected {
border: 2px solid #409EFF;
background-color: #ecf5ff;
}
.source-content {
display: flex;
align-items: flex-start;
gap: 15px;
}
.source-info {
flex: 1;
}
.source-title {
display: flex;
align-items: center;
gap: 10px;
font-size: 18px;
font-weight: 600;
margin-bottom: 10px;
color: #303133;
}
.source-desc {
color: #606266;
line-height: 1.6;
margin-bottom: 10px;
font-size: 14px;
}
.action-buttons {
margin-top: 30px;
text-align: center;
}
.action-buttons .el-button {
margin: 0 10px;
}
:deep(.el-checkbox__label) {
display: none;
}
</style>