evidence-med / index_bak2.html
leonsimon23's picture
Rename index.html to index_bak2.html
55bed48 verified
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>EvidenceMed - 循证医学论文智能检索平台</title>
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css" rel="stylesheet">
<style>
:root {
--primary-color: #2E86AB;
--secondary-color: #A23B72;
--accent-color: #F18F01;
--success-color: #16A085;
--danger-color: #E74C3C;
--warning-color: #F39C12;
--light-color: #F8F9FA;
--dark-color: #2C3E50;
--gradient-primary: linear-gradient(135deg, #2E86AB 0%, #A23B72 100%);
--gradient-secondary: linear-gradient(135deg, #16A085 0%, #F18F01 100%);
--shadow-light: 0 4px 6px rgba(0, 0, 0, 0.1);
--shadow-medium: 0 8px 25px rgba(0, 0, 0, 0.15);
--shadow-heavy: 0 15px 35px rgba(0, 0, 0, 0.1);
--border-radius: 12px;
--transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
background: linear-gradient(135deg, #667eea 0%, #764ba2 50%, #f093fb 100%);
min-height: 100vh;
color: var(--dark-color);
line-height: 1.6;
}
.container {
max-width: 1400px;
margin: 0 auto;
padding: 20px;
}
/* Header */
.header {
background: rgba(255, 255, 255, 0.95);
backdrop-filter: blur(20px);
border-radius: var(--border-radius);
box-shadow: var(--shadow-medium);
padding: 30px;
margin-bottom: 30px;
text-align: center;
border: 1px solid rgba(255, 255, 255, 0.2);
}
.header h1 {
background: var(--gradient-primary);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
font-size: 3em;
font-weight: 800;
margin-bottom: 10px;
letter-spacing: -0.02em;
}
.header .subtitle {
color: var(--secondary-color);
font-size: 1.3em;
font-weight: 300;
margin-bottom: 20px;
}
.header .tagline {
display: flex;
justify-content: center;
gap: 30px;
flex-wrap: wrap;
margin-top: 20px;
}
.tag {
/* 修改 #2: 修改标签背景颜色 */
background: linear-gradient(135deg, #4F80C8, #6C63FF);
color: white;
padding: 8px 16px;
border-radius: 25px;
font-size: 0.9em;
font-weight: 500;
display: flex;
align-items: center;
gap: 8px;
box-shadow: var(--shadow-light);
}
/* Search Section */
.search-section {
background: rgba(255, 255, 255, 0.95);
backdrop-filter: blur(20px);
border-radius: var(--border-radius);
box-shadow: var(--shadow-medium);
padding: 40px;
margin-bottom: 30px;
border: 1px solid rgba(255, 255, 255, 0.2);
}
.search-form {
display: flex;
flex-direction: column;
gap: 25px;
}
.search-input-group {
position: relative;
}
.search-input {
width: 100%;
padding: 20px 60px 20px 20px;
border: 2px solid #e1e8ed;
border-radius: var(--border-radius);
font-size: 1.1em;
background: white;
transition: var(--transition);
resize: vertical;
min-height: 120px;
}
.search-input:focus {
outline: none;
border-color: var(--primary-color);
box-shadow: 0 0 0 3px rgba(46, 134, 171, 0.1);
}
.search-btn {
position: absolute;
right: 15px;
top: 50%;
transform: translateY(-50%);
background: var(--gradient-primary);
color: white;
border: none;
padding: 15px 20px;
border-radius: var(--border-radius);
cursor: pointer;
transition: var(--transition);
font-weight: 600;
display: flex;
align-items: center;
gap: 8px;
box-shadow: var(--shadow-light);
}
.search-btn:hover {
transform: translateY(-50%) scale(1.05);
box-shadow: var(--shadow-medium);
}
.search-btn:disabled {
opacity: 0.7;
cursor: not-allowed;
transform: translateY(-50%) scale(1);
}
.platform-selector {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 15px;
}
.platform-option {
display: flex;
align-items: center;
padding: 15px;
background: white;
border: 2px solid #e1e8ed;
border-radius: var(--border-radius);
cursor: pointer;
transition: var(--transition);
position: relative;
}
.platform-option:hover {
border-color: var(--primary-color);
box-shadow: var(--shadow-light);
}
.platform-option.selected {
border-color: var(--primary-color);
background: rgba(46, 134, 171, 0.05);
}
.platform-option input {
margin-right: 12px;
transform: scale(1.2);
}
.platform-info {
flex-grow: 1;
}
.platform-name {
font-weight: 600;
color: var(--dark-color);
margin-bottom: 4px;
}
.platform-desc {
font-size: 0.85em;
color: #6c757d;
}
/* AI Features - 修改 #3: 优化AI功能区布局,使其更紧凑 */
.ai-features {
display: flex;
justify-content: space-around;
flex-wrap: wrap;
gap: 20px;
margin-bottom: 30px;
}
.ai-feature {
background: rgba(255, 255, 255, 0.95);
backdrop-filter: blur(20px);
border-radius: var(--border-radius);
padding: 20px;
box-shadow: var(--shadow-medium);
text-align: center;
transition: var(--transition);
border: 1px solid rgba(255, 255, 255, 0.2);
flex: 1;
min-width: 250px;
max-width: 350px;
}
.ai-feature:hover {
transform: translateY(-5px);
box-shadow: var(--shadow-heavy);
}
.ai-feature-icon {
font-size: 2.5em; /* 减小图标大小 */
background: var(--gradient-primary);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
margin-bottom: 10px; /* 减小边距 */
}
.ai-feature h3 {
color: var(--dark-color);
margin-bottom: 8px; /* 减小边距 */
font-size: 1.1em; /* 减小标题字号 */
}
.ai-feature p {
color: #6c757d;
font-size: 0.9em; /* 减小描述字号 */
}
/* Loading */
.loading {
display: none;
text-align: center;
padding: 40px;
background: rgba(255, 255, 255, 0.95);
backdrop-filter: blur(20px);
border-radius: var(--border-radius);
box-shadow: var(--shadow-medium);
margin-bottom: 30px;
}
.loading.show {
display: block;
}
.spinner {
width: 50px;
height: 50px;
border: 4px solid #f3f3f3;
border-top: 4px solid var(--primary-color);
border-radius: 50%;
animation: spin 1s linear infinite;
margin: 0 auto 20px;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
/* Results */
.results-section {
background: rgba(255, 255, 255, 0.95);
backdrop-filter: blur(20px);
border-radius: var(--border-radius);
box-shadow: var(--shadow-medium);
padding: 30px;
display: none;
border: 1px solid rgba(255, 255, 255, 0.2);
}
.results-section.show {
display: block;
}
.results-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 25px;
padding-bottom: 15px;
border-bottom: 2px solid #e1e8ed;
}
.results-count {
color: var(--primary-color);
font-weight: 600;
font-size: 1.1em;
}
.paper-card {
background: white;
border-radius: var(--border-radius);
padding: 25px;
margin-bottom: 20px;
box-shadow: var(--shadow-light);
border-left: 4px solid var(--primary-color);
transition: var(--transition);
}
.paper-card:hover {
box-shadow: var(--shadow-medium);
transform: translateX(5px);
}
.paper-title {
font-size: 1.3em;
font-weight: 600;
color: var(--dark-color);
margin-bottom: 10px;
line-height: 1.4;
}
.paper-title a {
color: inherit;
text-decoration: none;
transition: var(--transition);
}
.paper-title a:hover {
color: var(--primary-color);
}
.paper-authors {
color: var(--secondary-color);
margin-bottom: 10px;
font-weight: 500;
}
.paper-journal {
color: var(--accent-color);
font-style: italic;
margin-bottom: 10px;
}
.paper-date {
color: #6c757d;
font-size: 0.9em;
margin-bottom: 15px;
}
.paper-abstract {
color: #495057;
line-height: 1.6;
margin-bottom: 20px;
background: #f8f9fa;
padding: 15px;
border-radius: 8px;
border-left: 3px solid var(--accent-color);
}
.paper-actions {
display: flex;
gap: 10px;
flex-wrap: wrap;
}
.action-btn {
padding: 8px 16px;
border: none;
border-radius: 6px;
cursor: pointer;
font-size: 0.9em;
font-weight: 500;
text-decoration: none;
display: inline-flex;
align-items: center;
gap: 6px;
transition: var(--transition);
}
.btn-primary {
background: var(--primary-color);
color: white;
}
.btn-success {
background: var(--success-color);
color: white;
}
.btn-outline {
background: transparent;
color: var(--primary-color);
border: 1px solid var(--primary-color);
}
.action-btn:hover {
transform: translateY(-2px);
box-shadow: var(--shadow-light);
}
/* Error */
.error-message {
background: rgba(231, 76, 60, 0.1);
color: var(--danger-color);
padding: 20px;
border-radius: var(--border-radius);
border: 1px solid rgba(231, 76, 60, 0.2);
margin-bottom: 20px;
display: none;
}
.error-message.show {
display: block;
}
/* Success Message */
.success-message {
background: rgba(22, 160, 133, 0.1);
color: var(--success-color);
padding: 15px;
border-radius: var(--border-radius);
border: 1px solid rgba(22, 160, 133, 0.2);
margin: 10px 0;
display: none;
animation: fadeInUp 0.3s ease-out;
}
.success-message.show {
display: block;
}
/* Modal */
.modal {
display: none;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.5);
z-index: 1000;
animation: fadeIn 0.3s ease-out;
}
.modal.show {
display: flex;
align-items: center;
justify-content: center;
}
.modal-content {
background: white;
border-radius: var(--border-radius);
padding: 30px;
max-width: 500px;
width: 90%;
animation: slideUp 0.3s ease-out;
}
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
@keyframes slideUp {
from {
opacity: 0;
transform: translateY(30px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
/* Responsive */
@media (max-width: 768px) {
.container {
padding: 10px;
}
.header h1 {
font-size: 2em;
}
.header .tagline {
gap: 15px;
}
.search-section {
padding: 25px;
}
.search-input {
padding: 15px 50px 15px 15px;
min-height: 100px;
}
.platform-selector {
grid-template-columns: 1fr;
}
.ai-features {
flex-direction: column;
}
.results-header {
flex-direction: column;
align-items: flex-start;
gap: 10px;
}
.paper-actions {
justify-content: center;
}
}
/* Animations */
@keyframes fadeInUp {
from {
opacity: 0;
transform: translateY(30px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.fade-in-up {
animation: fadeInUp 0.6s ease-out forwards;
}
/* Evidence levels */
.evidence-level {
display: inline-block;
padding: 4px 10px;
border-radius: 12px;
font-size: 0.8em;
font-weight: 600;
text-transform: uppercase;
margin-left: 10px;
}
.level-1 { background: #e8f5e8; color: #2e7d32; }
.level-2 { background: #f3e5f5; color: #7b1fa2; }
.level-3 { background: #e3f2fd; color: #1976d2; }
.level-4 { background: #fff3e0; color: #f57c00; }
</style>
</head>
<body>
<div class="container">
<!-- Header -->
<header class="header fade-in-up">
<h1><i class="fas fa-microscope"></i> EvidenceMed</h1>
<p class="subtitle">循证医学论文智能检索平台</p>
<div class="tagline">
<div class="tag">
<i class="fas fa-brain"></i>
AI智能检索
</div>
<div class="tag">
<i class="fas fa-download"></i>
全文下载
</div>
<div class="tag">
<i class="fas fa-language"></i>
自然语言查询
</div>
<div class="tag">
<i class="fas fa-shield-alt"></i>
循证医学
</div>
</div>
</header>
<!-- AI Features -->
<div class="ai-features fade-in-up">
<div class="ai-feature">
<div class="ai-feature-icon">
<i class="fas fa-search-plus"></i>
</div>
<h3>智能语义理解</h3>
<p>精准理解医学术语与复杂查询</p>
</div>
<div class="ai-feature">
<div class="ai-feature-icon">
<i class="fas fa-filter"></i>
</div>
<h3>循证分级筛选</h3>
<p>按证据等级自动分类筛选文献</p>
</div>
<div class="ai-feature">
<div class="ai-feature-icon">
<i class="fas fa-chart-line"></i>
</div>
<h3>研究趋势分析</h3>
<p>洞察领域前沿,发现研究热点</p>
</div>
</div>
<!-- Search Section -->
<section class="search-section fade-in-up">
<form class="search-form" id="searchForm">
<div class="search-input-group">
<textarea
class="search-input"
id="searchQuery"
placeholder="请输入您的医学研究问题 (建议使用英文以获得更佳搜索效果),例如:
• Efficacy and safety of metformin in type 2 diabetes
• Immune response to COVID-19 vaccines in elderly
• Lifestyle interventions for hypertension
• Adjuvant chemotherapy for breast cancer
AI将自动理解您的意图并提供最相关的文献..."
required></textarea>
<button type="submit" class="search-btn" id="searchBtn">
<i class="fas fa-search"></i>
智能搜索
</button>
</div>
<div class="platform-selector">
<label class="platform-option selected">
<input type="checkbox" name="platform" value="pubmed" checked>
<div class="platform-info">
<div class="platform-name">PubMed</div>
<div class="platform-desc">生物医学文献数据库</div>
</div>
</label>
<label class="platform-option">
<input type="checkbox" name="platform" value="arxiv">
<div class="platform-info">
<div class="platform-name">arXiv</div>
<div class="platform-desc">预印本论文平台</div>
</div>
</label>
<label class="platform-option">
<input type="checkbox" name="platform" value="biorxiv">
<div class="platform-info">
<div class="platform-name">bioRxiv</div>
<div class="platform-desc">生物学预印本</div>
</div>
</label>
<label class="platform-option">
<input type="checkbox" name="platform" value="semantic">
<div class="platform-info">
<div class="platform-name">Semantic Scholar</div>
<div class="platform-desc">AI驱动的学术搜索</div>
</div>
</label>
</div>
<!-- 修改 #1: 添加结果数量选择器 -->
<div class="results-limiter" style="display: flex; align-items: center; gap: 10px; margin-top: 15px;">
<label for="maxResults" style="font-weight: 600; color: var(--dark-color);">
<i class="fas fa-list-ol"></i> 最大结果数量:
</label>
<select id="maxResults" style="padding: 10px; border-radius: 8px; border: 2px solid #e1e8ed; font-size: 1em; background: white; transition: var(--transition);">
<option value="10">10</option>
<option value="20">20</option>
<option value="50" selected>50</option>
<option value="100">100</option>
</select>
</div>
</form>
</section>
<!-- Loading -->
<div class="loading" id="loading">
<div class="spinner"></div>
<p><i class="fas fa-robot"></i> AI正在分析您的查询并检索相关文献...</p>
</div>
<!-- Success Message -->
<div class="success-message" id="successMessage"></div>
<!-- Error Message -->
<div class="error-message" id="errorMessage"></div>
<!-- Results -->
<section class="results-section" id="resultsSection">
<div class="results-header">
<div class="results-count" id="resultsCount"></div>
<div>
<button class="action-btn btn-outline" onclick="exportResults()">
<i class="fas fa-download"></i> 导出结果
</button>
</div>
</div>
<div id="resultsContainer"></div>
</section>
</div>
<!-- Modal for sharing -->
<div class="modal" id="shareModal">
<div class="modal-content">
<h3 style="margin-bottom: 20px; color: var(--primary-color);">
<i class="fas fa-share-alt"></i> 分享文献
</h3>
<p style="margin-bottom: 20px; color: #6c757d;">选择分享方式:</p>
<div style="display: flex; gap: 10px; flex-wrap: wrap;">
<button class="action-btn btn-primary" onclick="shareViaEmail()">
<i class="fas fa-envelope"></i> 邮件
</button>
<button class="action-btn btn-success" onclick="copyToClipboard()">
<i class="fas fa-copy"></i> 复制链接
</button>
<button class="action-btn btn-outline" onclick="closeModal()">
取消
</button>
</div>
</div>
</div>
<script>
// API配置 - 演示模式,实际使用时替换为真实API
//const API_BASE_URL = 'https://leonsimon23-paper-mcp-agent.hf.space';
const API_BASE_URL = 'https://leonsimon23-ai-search-agent.hf.space';
const DEMO_MODE = false; // 设置为false以使用真实API
// 全局变量
let searchResults = [];
let savedPapers = JSON.parse(localStorage.getItem('savedPapers') || '[]');
let currentSharePaper = null;
// DOM元素
const searchForm = document.getElementById('searchForm');
const searchQuery = document.getElementById('searchQuery');
const searchBtn = document.getElementById('searchBtn');
const loading = document.getElementById('loading');
const errorMessage = document.getElementById('errorMessage');
const successMessage = document.getElementById('successMessage');
const resultsSection = document.getElementById('resultsSection');
const resultsContainer = document.getElementById('resultsContainer');
const resultsCount = document.getElementById('resultsCount');
const shareModal = document.getElementById('shareModal');
// 平台选择处理
document.querySelectorAll('.platform-option').forEach(option => {
option.addEventListener('click', function(e) {
if (e.target.tagName !== 'INPUT') {
const checkbox = this.querySelector('input');
checkbox.checked = !checkbox.checked;
}
this.classList.toggle('selected', this.querySelector('input').checked);
});
});
// 搜索表单提交
searchForm.addEventListener('submit', async (e) => {
e.preventDefault();
await performSearch();
});
// 点击模态框背景关闭
shareModal.addEventListener('click', (e) => {
if (e.target === shareModal) {
closeModal();
}
});
// 执行搜索
async function performSearch() {
const query = searchQuery.value.trim();
if (!query) {
showError('请输入搜索查询');
return;
}
const selectedPlatforms = Array.from(document.querySelectorAll('input[name="platform"]:checked'))
.map(input => input.value);
if (selectedPlatforms.length === 0) {
showError('请至少选择一个数据库平台');
return;
}
showLoading(true);
hideError();
hideSuccess();
hideResults();
try {
searchResults = [];
if (DEMO_MODE) {
// 演示数据
searchResults = generateDemoResults(query, selectedPlatforms);
// 模拟加载时间
await new Promise(resolve => setTimeout(resolve, 2000));
} else {
// 对每个平台执行搜索
for (const platform of selectedPlatforms) {
try {
const results = await searchPlatform(platform, query);
if (results && results.length > 0) {
searchResults.push(...results.map(paper => ({
...paper,
platform: platform
})));
}
} catch (error) {
console.error(`搜索${platform}时出错:`, error);
}
}
}
if (searchResults.length === 0) {
showError('未找到相关文献,请尝试调整搜索关键词或选择其他数据库');
return;
}
// 按相关性排序
searchResults.sort((a, b) => (b.relevance_score || Math.random()) - (a.relevance_score || Math.random()));
displayResults();
showSuccess(`成功检索到 ${searchResults.length} 篇相关文献`);
} catch (error) {
console.error('搜索出错:', error);
showError('搜索过程中发生错误,请稍后重试');
} finally {
showLoading(false);
}
}
// 生成演示数据
function generateDemoResults(query, platforms) {
const demoResults = [];
const baseResults = [
{
title: "Metformin in type 2 diabetes: A systematic review and meta-analysis",
authors: ["Smith J", "Johnson A", "Williams B"],
journal: "The Lancet Diabetes & Endocrinology",
published_date: "2023-08-15",
abstract: "Background: Metformin remains the first-line treatment for type 2 diabetes, but its efficacy and safety profile continues to be evaluated. Methods: We conducted a systematic review and meta-analysis of randomized controlled trials examining metformin use in type 2 diabetes patients...",
url: "https://pubmed.ncbi.nlm.nih.gov/demo1",
pdf_url: "https://example.com/demo1.pdf",
relevance_score: 0.95,
study_type: "meta-analysis"
},
{
title: "COVID-19 vaccines effectiveness in elderly populations: A real-world evidence study",
authors: ["Brown C", "Davis M", "Wilson K"],
journal: "Nature Medicine",
published_date: "2023-07-22",
abstract: "The effectiveness of COVID-19 vaccines in elderly populations has been a critical public health concern. This real-world evidence study analyzes vaccination outcomes in patients aged 65 and older across multiple healthcare systems...",
url: "https://pubmed.ncbi.nlm.nih.gov/demo2",
pdf_url: "https://example.com/demo2.pdf",
relevance_score: 0.92,
study_type: "cohort"
},
{
title: "Lifestyle interventions for hypertension management: A randomized controlled trial",
authors: ["Taylor R", "Anderson L", "Thompson D"],
journal: "Journal of the American College of Cardiology",
published_date: "2023-06-10",
abstract: "Objective: To evaluate the effectiveness of comprehensive lifestyle interventions in managing hypertension. Design: Randomized controlled trial with 12-month follow-up. Participants: 500 adults with newly diagnosed hypertension...",
url: "https://pubmed.ncbi.nlm.nih.gov/demo3",
pdf_url: "https://example.com/demo3.pdf",
relevance_score: 0.88,
study_type: "rct"
},
{
title: "Comparative effectiveness of adjuvant chemotherapy regimens in breast cancer: Network meta-analysis",
authors: ["Garcia M", "Rodriguez P", "Martinez S"],
journal: "Journal of Clinical Oncology",
published_date: "2023-09-05",
abstract: "Purpose: To compare the effectiveness of different adjuvant chemotherapy regimens in early-stage breast cancer through network meta-analysis. Methods: We systematically searched multiple databases for randomized controlled trials comparing adjuvant chemotherapy regimens...",
url: "https://pubmed.ncbi.nlm.nih.gov/demo4",
pdf_url: "https://example.com/demo4.pdf",
relevance_score: 0.85,
study_type: "meta-analysis"
},
{
title: "Novel biomarkers for early detection of Alzheimer's disease: A prospective cohort study",
authors: ["Lee H", "Park S", "Kim J"],
journal: "Alzheimer's & Dementia",
published_date: "2023-05-18",
abstract: "Background: Early detection of Alzheimer's disease remains challenging. This study investigates novel blood-based biomarkers for preclinical diagnosis. Methods: Prospective cohort study following 1,200 cognitively normal adults over 5 years...",
url: "https://pubmed.ncbi.nlm.nih.gov/demo5",
pdf_url: "https://example.com/demo5.pdf",
relevance_score: 0.82,
study_type: "cohort"
}
];
// 根据查询和平台生成结果
platforms.forEach(platform => {
baseResults.forEach((result, index) => {
if (Math.random() > 0.3) { // 随机包含一些结果
demoResults.push({
...result,
platform: platform,
id: `${platform}_${index}`,
title: result.title + (platform !== 'pubmed' ? ` [${platform.toUpperCase()}]` : '')
});
}
});
});
return demoResults.slice(0, Math.min(15, demoResults.length));
}
// 搜索特定平台(真实API调用)- 修改 #1: 修改函数以使用选择器的值
async function searchPlatform(platform, query) {
// 从新增的下拉框中获取用户选择的数量
const maxResultsValue = document.getElementById('maxResults').value;
const response = await fetch(`${API_BASE_URL}/search`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
platform: platform,
query: query,
// 使用从下拉框获取的值,并将其转换为整数
max_results: parseInt(maxResultsValue, 10)
})
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const data = await response.json();
if (data.error) {
throw new Error(data.error);
}
return data.results || [];
}
// 显示搜索结果
function displayResults() {
resultsCount.textContent = `找到 ${searchResults.length} 篇相关文献`;
resultsContainer.innerHTML = '';
searchResults.forEach((paper, index) => {
const paperCard = createPaperCard(paper, index);
resultsContainer.appendChild(paperCard);
});
resultsSection.classList.add('show');
resultsSection.scrollIntoView({ behavior: 'smooth' });
}
// 创建论文卡片
function createPaperCard(paper, index) {
const card = document.createElement('div');
card.className = 'paper-card fade-in-up';
card.style.animationDelay = `${index * 0.1}s`;
// 确定证据等级
const evidenceLevel = getEvidenceLevel(paper);
// 检查是否已保存
const isSaved = savedPapers.some(saved => saved.id === paper.id || saved.title === paper.title);
card.innerHTML = `
<div class="paper-title">
<a href="${paper.url || '#'}" target="_blank">
${paper.title || '标题未知'}
</a>
${evidenceLevel ? `<span class="evidence-level ${evidenceLevel.class}">${evidenceLevel.text}</span>` : ''}
</div>
${paper.authors ? `<div class="paper-authors">
<i class="fas fa-user-md"></i> ${Array.isArray(paper.authors) ? paper.authors.join(', ') : paper.authors}
</div>` : ''}
${paper.journal ? `<div class="paper-journal">
<i class="fas fa-book-open"></i> ${paper.journal}
</div>` : ''}
${paper.published_date || paper.date ? `<div class="paper-date">
<i class="fas fa-calendar-alt"></i> ${paper.published_date || paper.date}
</div>` : ''}
${paper.abstract || paper.summary ? `<div class="paper-abstract">
<strong>摘要:</strong> ${truncateText(paper.abstract || paper.summary, 300)}
</div>` : ''}
<div class="paper-actions">
${paper.url ? `<a href="${paper.url}" target="_blank" class="action-btn btn-primary">
<i class="fas fa-external-link-alt"></i> 查看原文
</a>` : ''}
${paper.pdf_url ? `<a href="${paper.pdf_url}" target="_blank" class="action-btn btn-success">
<i class="fas fa-file-pdf"></i> 下载PDF
</a>` : ''}
<button class="action-btn ${isSaved ? 'btn-success' : 'btn-outline'}" onclick="toggleSavePaper(${index})" id="save-btn-${index}">
<i class="fas ${isSaved ? 'fa-check' : 'fa-bookmark'}"></i> ${isSaved ? '已保存' : '保存'}
</button>
<button class="action-btn btn-outline" onclick="sharePaper(${index})">
<i class="fas fa-share-alt"></i> 分享
</button>
<span class="platform-badge" style="background: var(--accent-color); color: white; padding: 4px 8px; border-radius: 4px; font-size: 0.8em; margin-left: auto;">
${paper.platform?.toUpperCase() || 'UNKNOWN'}
</span>
</div>
`;
return card;
}
// 获取证据等级
function getEvidenceLevel(paper) {
const title = (paper.title || '').toLowerCase();
const abstract = (paper.abstract || paper.summary || '').toLowerCase();
const studyType = (paper.study_type || '').toLowerCase();
// 基于研究类型和关键词的分类
if (studyType === 'meta-analysis' || title.includes('meta-analysis') || title.includes('systematic review') ||
abstract.includes('meta-analysis') || abstract.includes('systematic review')) {
return { class: 'level-1', text: '系统评价' };
}
if (studyType === 'rct' || title.includes('randomized') || title.includes('rct') ||
abstract.includes('randomized controlled trial') || abstract.includes('randomized trial')) {
return { class: 'level-2', text: 'RCT' };
}
if (studyType === 'cohort' || title.includes('cohort') || title.includes('case-control') ||
abstract.includes('cohort study') || abstract.includes('case-control')) {
return { class: 'level-3', text: '队列研究' };
}
if (title.includes('case report') || title.includes('case series') ||
abstract.includes('case report') || abstract.includes('case series')) {
return { class: 'level-4', text: '病例报告' };
}
return null;
}
// 截断文本
function truncateText(text, maxLength) {
if (!text) return '';
if (text.length <= maxLength) return text;
return text.substring(0, maxLength) + '...';
}
// 切换保存论文状态
function toggleSavePaper(index) {
const paper = searchResults[index];
const savedIndex = savedPapers.findIndex(saved => saved.id === paper.id || saved.title === paper.title);
const saveBtn = document.getElementById(`save-btn-${index}`);
if (savedIndex > -1) {
// 取消保存
savedPapers.splice(savedIndex, 1);
saveBtn.innerHTML = '<i class="fas fa-bookmark"></i> 保存';
saveBtn.classList.remove('btn-success');
saveBtn.classList.add('btn-outline');
showSuccess('已取消保存该文献');
} else {
// 保存论文
savedPapers.push({
...paper,
savedAt: new Date().toISOString()
});
saveBtn.innerHTML = '<i class="fas fa-check"></i> 已保存';
saveBtn.classList.remove('btn-outline');
saveBtn.classList.add('btn-success');
showSuccess('文献已保存到收藏夹');
}
// 保存到本地存储
localStorage.setItem('savedPapers', JSON.stringify(savedPapers));
}
// 分享论文
function sharePaper(index) {
currentSharePaper = searchResults[index];
shareModal.classList.add('show');
}
// 通过邮件分享
function shareViaEmail() {
if (!currentSharePaper) return;
const subject = encodeURIComponent(`推荐文献: ${currentSharePaper.title}`);
const body = encodeURIComponent(`我发现了一篇可能对您有用的医学文献:
标题: ${currentSharePaper.title}
作者: ${Array.isArray(currentSharePaper.authors) ? currentSharePaper.authors.join(', ') : currentSharePaper.authors || '未知'}
期刊: ${currentSharePaper.journal || '未知'}
发表日期: ${currentSharePaper.published_date || currentSharePaper.date || '未知'}
链接: ${currentSharePaper.url || '暂无链接'}
摘要:
${currentSharePaper.abstract || currentSharePaper.summary || '暂无摘要'}
通过 EvidenceMed 循证医学检索平台分享`);
window.open(`mailto:?subject=${subject}&body=${body}`);
closeModal();
showSuccess('邮件分享链接已打开');
}
// 复制到剪贴板
async function copyToClipboard() {
if (!currentSharePaper) return;
const shareText = `【推荐文献】
标题: ${currentSharePaper.title}
作者: ${Array.isArray(currentSharePaper.authors) ? currentSharePaper.authors.join(', ') : currentSharePaper.authors || '未知'}
期刊: ${currentSharePaper.journal || '未知'}
链接: ${currentSharePaper.url || '暂无链接'}
通过 EvidenceMed 循证医学检索平台分享`;
try {
await navigator.clipboard.writeText(shareText);
showSuccess('文献信息已复制到剪贴板');
} catch (err) {
// 降级方案
const textArea = document.createElement('textarea');
textArea.value = shareText;
document.body.appendChild(textArea);
textArea.select();
document.execCommand('copy');
document.body.removeChild(textArea);
showSuccess('文献信息已复制到剪贴板');
}
closeModal();
}
// 关闭模态框
function closeModal() {
shareModal.classList.remove('show');
currentSharePaper = null;
}
// 导出结果
function exportResults() {
if (searchResults.length === 0) {
showError('没有可导出的搜索结果');
return;
}
// 生成导出数据
const exportData = {
searchQuery: searchQuery.value,
searchDate: new Date().toISOString(),
totalResults: searchResults.length,
results: searchResults.map(paper => ({
title: paper.title,
authors: Array.isArray(paper.authors) ? paper.authors.join(', ') : paper.authors,
journal: paper.journal,
publishedDate: paper.published_date || paper.date,
abstract: paper.abstract || paper.summary,
url: paper.url,
pdfUrl: paper.pdf_url,
platform: paper.platform,
evidenceLevel: getEvidenceLevel(paper)?.text || '未分级'
}))
};
// 创建CSV格式
const csvHeaders = ['标题', '作者', '期刊', '发表日期', '摘要', '链接', 'PDF链接', '数据库', '证据等级'];
const csvRows = [
csvHeaders.join(','),
...exportData.results.map(paper => [
`"${(paper.title || '').replace(/"/g, '""')}"`,
`"${(paper.authors || '').replace(/"/g, '""')}"`,
`"${(paper.journal || '').replace(/"/g, '""')}"`,
`"${(paper.publishedDate || '').replace(/"/g, '""')}"`,
`"${(paper.abstract || '').replace(/"/g, '""')}"`,
`"${(paper.url || '').replace(/"/g, '""')}"`,
`"${(paper.pdfUrl || '').replace(/"/g, '""')}"`,
`"${(paper.platform || '').replace(/"/g, '""')}"`,
`"${(paper.evidenceLevel || '').replace(/"/g, '""')}"`
].join(','))
];
// 下载CSV文件
const csvContent = csvRows.join('\n');
const blob = new Blob(['\ufeff' + csvContent], { type: 'text/csv;charset=utf-8;' });
const link = document.createElement('a');
const url = URL.createObjectURL(blob);
link.setAttribute('href', url);
link.setAttribute('download', `EvidenceMed_搜索结果_${new Date().toISOString().split('T')[0]}.csv`);
link.style.visibility = 'hidden';
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
showSuccess('搜索结果已导出为CSV文件');
}
// 显示/隐藏加载状态
function showLoading(show) {
loading.classList.toggle('show', show);
searchBtn.disabled = show;
searchBtn.innerHTML = show ?
'<i class="fas fa-spinner fa-spin"></i> 搜索中...' :
'<i class="fas fa-search"></i> 智能搜索';
}
// 显示错误信息
function showError(message) {
errorMessage.textContent = message;
errorMessage.classList.add('show');
setTimeout(() => {
hideError();
}, 5000);
}
// 隐藏错误信息
function hideError() {
errorMessage.classList.remove('show');
}
// 显示成功信息
function showSuccess(message) {
successMessage.textContent = message;
successMessage.classList.add('show');
setTimeout(() => {
hideSuccess();
}, 3000);
}
// 隐藏成功信息
function hideSuccess() {
successMessage.classList.remove('show');
}
// 隐藏搜索结果
function hideResults() {
resultsSection.classList.remove('show');
}
// 初始化页面
document.addEventListener('DOMContentLoaded', function() {
// 添加淡入动画
document.querySelectorAll('.fade-in-up').forEach((element, index) => {
element.style.animationDelay = `${index * 0.2}s`;
});
// 如果是演示模式,显示提示
if (DEMO_MODE) {
const demoNotice = document.createElement('div');
demoNotice.innerHTML = `
<div style="background: rgba(255, 193, 7, 0.1); color: #856404; padding: 15px; margin-bottom: 20px; border-radius: var(--border-radius); border: 1px solid rgba(255, 193, 7, 0.2); text-align: center;">
<i class="fas fa-info-circle"></i> 当前处于演示模式,搜索结果为模拟数据
</div>
`;
document.querySelector('.container').insertBefore(demoNotice, document.querySelector('.ai-features'));
}
// 显示保存的论文数量
if (savedPapers.length > 0) {
const savedNotice = document.createElement('div');
savedNotice.innerHTML = `
<div style="background: rgba(22, 160, 133, 0.1); color: var(--success-color); padding: 10px; margin-bottom: 15px; border-radius: 6px; text-align: center; font-size: 0.9em;">
<i class="fas fa-bookmark"></i> 您已保存 ${savedPapers.length} 篇文献
</div>
`;
document.querySelector('.search-section').insertBefore(savedNotice, document.querySelector('.search-form'));
}
});
// 键盘快捷键
document.addEventListener('keydown', function(e) {
// Ctrl/Cmd + Enter 执行搜索
if ((e.ctrlKey || e.metaKey) && e.key === 'Enter') {
e.preventDefault();
if (!searchBtn.disabled) {
performSearch();
}
}
// Escape 关闭模态框
if (e.key === 'Escape') {
closeModal();
}
});
// 平滑滚动到顶部功能
function scrollToTop() {
window.scrollTo({
top: 0,
behavior: 'smooth'
});
}
// 添加返回顶部按钮
const backToTopBtn = document.createElement('button');
backToTopBtn.innerHTML = '<i class="fas fa-chevron-up"></i>';
backToTopBtn.style.cssText = `
position: fixed;
bottom: 30px;
right: 30px;
width: 50px;
height: 50px;
background: var(--gradient-primary);
color: white;
border: none;
border-radius: 50%;
cursor: pointer;
display: none;
z-index: 999;
box-shadow: var(--shadow-medium);
transition: var(--transition);
font-size: 1.2em;
`;
backToTopBtn.onclick = scrollToTop;
document.body.appendChild(backToTopBtn);
// 滚动时显示/隐藏返回顶部按钮
window.addEventListener('scroll', function() {
if (window.pageYOffset > 300) {
backToTopBtn.style.display = 'block';
} else {
backToTopBtn.style.display = 'none';
}
});
</script>
</body>
</html>