293 lines
16 KiB
HTML
Executable File
293 lines
16 KiB
HTML
Executable File
<!DOCTYPE html>
|
||
<html lang="zh-CN">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
<title>阶段性综合深度报告 - 弹窗演示</title>
|
||
<script src="https://cdn.jsdelivr.net/npm/vue@3.3.4/dist/vue.global.prod.js"></script>
|
||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/element-plus@2.3.14/dist/index.css">
|
||
<script src="https://cdn.jsdelivr.net/npm/element-plus@2.3.14/dist/index.full.js"></script>
|
||
<style>
|
||
body { margin: 0; padding: 20px; font-family: 'Helvetica Neue', Arial, sans-serif; background: #f5f7fa; }
|
||
.demo-container { max-width: 1200px; margin: 0 auto; }
|
||
.stage-card { background: white; padding: 15px; margin: 10px 0; border-radius: 8px; box-shadow: 0 2px 12px rgba(0,0,0,0.1); }
|
||
.stage-header { display: flex; justify-content: space-between; align-items: center; }
|
||
.stage-title { font-size: 16px; font-weight: bold; }
|
||
.stage-status { padding: 4px 12px; border-radius: 12px; font-size: 12px; }
|
||
.status-completed { background: #67c23a; color: white; }
|
||
.status-running { background: #409eff; color: white; }
|
||
.status-pending { background: #909399; color: white; }
|
||
|
||
/* 弹窗样式 */
|
||
.interpretation-dialog .el-dialog__body { padding: 0; max-height: 70vh; overflow-y: auto; }
|
||
.report-container { padding: 20px; }
|
||
.report-header { background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; padding: 20px; margin: -20px -20px 20px -20px; }
|
||
.report-title { font-size: 20px; font-weight: bold; margin-bottom: 10px; }
|
||
.report-meta { font-size: 14px; opacity: 0.9; }
|
||
.flow-visualization { display: flex; align-items: center; justify-content: center; padding: 20px; background: #f8f9fa; border-radius: 8px; margin: 20px 0; }
|
||
.flow-stage { text-align: center; padding: 10px 20px; }
|
||
.flow-stage-icon { font-size: 24px; margin-bottom: 5px; }
|
||
.flow-stage-name { font-size: 14px; font-weight: bold; }
|
||
.flow-stage-result { font-size: 12px; color: #666; margin-top: 5px; }
|
||
.flow-arrow { font-size: 24px; color: #409eff; margin: 0 10px; }
|
||
.section-title { font-size: 18px; font-weight: bold; margin: 30px 0 15px 0; padding-bottom: 10px; border-bottom: 2px solid #409eff; }
|
||
.connection-card { background: #f0f9ff; border-left: 4px solid #409eff; padding: 15px; margin: 15px 0; border-radius: 4px; }
|
||
.connection-header { font-weight: bold; color: #409eff; margin-bottom: 10px; }
|
||
.finding-item { background: white; border: 1px solid #e4e7ed; padding: 15px; margin: 10px 0; border-radius: 8px; }
|
||
.finding-title { font-weight: bold; color: #303133; margin-bottom: 8px; }
|
||
.finding-desc { color: #606266; font-size: 14px; line-height: 1.6; }
|
||
.finding-evidence { color: #909399; font-size: 12px; margin-top: 8px; font-style: italic; }
|
||
.story-box { background: #fdf6ec; border: 1px solid #f5dab1; padding: 20px; border-radius: 8px; line-height: 1.8; color: #5d4a2a; }
|
||
.next-step-item { display: flex; align-items: flex-start; padding: 12px; background: white; border: 1px solid #e4e7ed; margin: 8px 0; border-radius: 6px; }
|
||
.next-step-priority { padding: 2px 8px; border-radius: 4px; font-size: 12px; margin-right: 12px; }
|
||
.priority-high { background: #fef0f0; color: #f56c6c; }
|
||
.priority-medium { background: #fdf6ec; color: #e6a23c; }
|
||
.next-step-content { flex: 1; }
|
||
.next-step-title { font-weight: bold; margin-bottom: 4px; }
|
||
.next-step-desc { font-size: 13px; color: #606266; }
|
||
.dialog-footer { display: flex; justify-content: flex-end; gap: 10px; padding: 15px 20px; border-top: 1px solid #e4e7ed; }
|
||
</style>
|
||
</head>
|
||
<body>
|
||
<div id="app">
|
||
<div class="demo-container">
|
||
<h1>🧬 基因家族分析流程</h1>
|
||
<p>点击任意阶段的"深度解读"按钮查看阶段性综合报告弹窗</p>
|
||
|
||
<!-- 分析流程卡片 -->
|
||
<div class="stage-card" v-for="stage in stages" :key="stage.id">
|
||
<div class="stage-header">
|
||
<div>
|
||
<span class="stage-title">{{ stage.name }}</span>
|
||
<span :class="['stage-status', 'status-' + stage.status]">
|
||
{{ statusText[stage.status] }}
|
||
</span>
|
||
</div>
|
||
<el-button
|
||
v-if="stage.status === 'completed' || stage.status === 'running'"
|
||
type="primary"
|
||
size="small"
|
||
@click="showInterpretation(stage)"
|
||
:loading="loading"
|
||
>
|
||
🔍 深度解读
|
||
</el-button>
|
||
</div>
|
||
<div v-if="stage.result" style="margin-top: 10px; color: #666; font-size: 14px;">
|
||
结果: {{ stage.result }}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 阶段性综合解读弹窗 -->
|
||
<el-dialog
|
||
v-model="dialogVisible"
|
||
title=" "
|
||
width="80%"
|
||
:close-on-click-modal="false"
|
||
class="interpretation-dialog"
|
||
>
|
||
<div class="report-container" v-if="report">
|
||
<!-- 报告头部 -->
|
||
<div class="report-header">
|
||
<div class="report-title">🔬 {{ report.metadata.title }}</div>
|
||
<div class="report-meta">
|
||
分析流程: {{ report.metadata.included_stages.join(' → ') }} |
|
||
生成时间: {{ formatTime(report.metadata.generated_at) }}
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 流程可视化 -->
|
||
<div class="section-title">📈 阶段性进展</div>
|
||
<div class="flow-visualization">
|
||
<template v-for="(stage, index) in report.stage_flow.stages" :key="stage.id">
|
||
<div class="flow-stage">
|
||
<div class="flow-stage-icon">{{ index === report.stage_flow.stages.length - 1 ? '🎯' : '✅' }}</div>
|
||
<div class="flow-stage-name">{{ stage.name }}</div>
|
||
<div class="flow-stage-result">{{ stage.key_result }}</div>
|
||
</div>
|
||
<div v-if="index < report.stage_flow.stages.length - 1" class="flow-arrow">→</div>
|
||
</template>
|
||
</div>
|
||
|
||
<!-- 阶段关联分析 -->
|
||
<div class="section-title" v-if="report.stage_connections.length > 0">🔗 阶段间关联分析</div>
|
||
<div v-for="(conn, idx) in report.stage_connections" :key="idx" class="connection-card">
|
||
<div class="connection-header">{{ conn.from }} → {{ conn.to }}</div>
|
||
<div>{{ conn.description }}</div>
|
||
<div style="margin-top: 8px; color: #409eff; font-size: 13px;">
|
||
💡 {{ conn.insight }}
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 关键发现 -->
|
||
<div class="section-title">💡 阶段性科学发现</div>
|
||
<div v-for="finding in report.key_findings" :key="finding.id" class="finding-item">
|
||
<div class="finding-title">{{ finding.id }}. {{ finding.title }}</div>
|
||
<div class="finding-desc">{{ finding.description }}</div>
|
||
<div class="finding-evidence">📋 证据: {{ finding.evidence }}</div>
|
||
</div>
|
||
|
||
<!-- 生物学故事 -->
|
||
<div class="section-title">🧬 生物学故事</div>
|
||
<div class="story-box">
|
||
{{ report.biological_story }}
|
||
</div>
|
||
|
||
<!-- 下一步建议 -->
|
||
<div class="section-title">📋 下一步建议</div>
|
||
<div v-for="(step, idx) in report.next_steps" :key="idx" class="next-step-item">
|
||
<div :class="['next-step-priority', 'priority-' + step.priority]">
|
||
{{ step.priority === 'high' ? '高优先级' : '中优先级' }}
|
||
</div>
|
||
<div class="next-step-content">
|
||
<div class="next-step-title">{{ step.stage }}: {{ step.description }}</div>
|
||
<div class="next-step-desc">{{ step.rationale }}</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 弹窗底部按钮 -->
|
||
<div class="dialog-footer">
|
||
<el-button @click="downloadReport('markdown')">
|
||
📄 Markdown
|
||
</el-button>
|
||
<el-button @click="downloadReport('json')">
|
||
📊 JSON
|
||
</el-button>
|
||
<el-button type="primary" @click="downloadReport('pdf')">
|
||
📥 下载PDF报告
|
||
</el-button>
|
||
<el-button type="success" @click="copyToClipboard">
|
||
📋 复制到剪贴板
|
||
</el-button>
|
||
<el-button @click="dialogVisible = false">
|
||
关闭
|
||
</el-button>
|
||
</div>
|
||
</el-dialog>
|
||
</div>
|
||
|
||
<script>
|
||
const { createApp } = Vue;
|
||
const { ElMessage } = ElementPlus;
|
||
|
||
createApp({
|
||
data() {
|
||
return {
|
||
loading: false,
|
||
dialogVisible: false,
|
||
report: null,
|
||
stages: [
|
||
{ id: 'identify', name: '基因家族鉴定', status: 'completed', result: '24个基因成员' },
|
||
{ id: 'phylogeny', name: '系统发育分析', status: 'completed', result: '3个亚家族' },
|
||
{ id: 'motif', name: 'Motif分析', status: 'running', result: '分析中...' },
|
||
{ id: 'promoter', name: '启动子分析', status: 'pending', result: null },
|
||
{ id: 'expression', name: '表达分析', status: 'pending', result: null }
|
||
],
|
||
statusText: {
|
||
completed: '已完成',
|
||
running: '进行中',
|
||
pending: '待开始'
|
||
}
|
||
};
|
||
},
|
||
methods: {
|
||
async showInterpretation(stage) {
|
||
this.loading = true;
|
||
|
||
// 模拟API调用
|
||
await new Promise(resolve => setTimeout(resolve, 800));
|
||
|
||
// 模拟报告数据
|
||
this.report = {
|
||
metadata: {
|
||
title: `阶段性综合深度报告(identify → phylogeny → ${stage.id})`,
|
||
included_stages: ['identify', 'phylogeny', stage.id],
|
||
stage_count: 3,
|
||
generated_at: new Date().toISOString(),
|
||
session_id: 'demo_session_001'
|
||
},
|
||
stage_flow: {
|
||
stages: [
|
||
{ id: 'identify', name: '基因家族鉴定', status: 'completed', key_result: '24个基因成员' },
|
||
{ id: 'phylogeny', name: '系统发育分析', status: 'completed', key_result: '3个亚家族' },
|
||
{ id: stage.id, name: stage.name, status: 'running', key_result: stage.result || '进行中' }
|
||
]
|
||
},
|
||
stage_connections: [
|
||
{
|
||
from: 'identify',
|
||
to: 'phylogeny',
|
||
description: '鉴定到的24个基因成员构成了进化树的叶节点,系统发育分析揭示了3个明显的亚家族分化,暗示功能分化可能发生在基因复制事件之后。',
|
||
insight: '基因数量与亚家族数量的对应关系支持了基因复制-功能分化的经典进化模式。'
|
||
},
|
||
{
|
||
from: 'phylogeny',
|
||
to: stage.id,
|
||
description: `基于进化树的亚家族分类,我们在${stage.name}中发现了特异的模式,这与亚家族分化高度一致。`,
|
||
insight: '亚家族分化不仅体现在序列水平,也在功能和调控层面有明显差异。'
|
||
}
|
||
],
|
||
key_findings: [
|
||
{
|
||
id: 1,
|
||
title: '基因家族规模适中',
|
||
description: '24个成员符合典型植物SPL家族规模(通常15-30个),表明苦荞SPL家族经历了适度的扩张,未出现大规模基因复制事件。',
|
||
evidence: '基于HMM(E-value<1e-5)和BLAST(identity>70%)双重验证的鉴定结果'
|
||
},
|
||
{
|
||
id: 2,
|
||
title: '明显的亚家族分化',
|
||
description: '系统发育分析显示3个明显的亚家族分化,与拟南芥(17成员/3亚家族)、水稻(19成员/3亚家族)等物种的SPL家族结构高度一致。',
|
||
evidence: '进化树bootstrap值均>70%,最大似然法构建,支持度高'
|
||
},
|
||
{
|
||
id: 3,
|
||
title: '阶段性功能分化证据',
|
||
description: `从${stage.name}结果看,不同亚家族表现出特异的模式,支持功能分化的假设。`,
|
||
evidence: `${stage.name}结果与亚家族分类高度关联`
|
||
}
|
||
],
|
||
biological_story: `从基因家族鉴定到系统发育分析再到${stage.name},我们构建了一个完整的SPL家族特征图谱。苦荞SPL家族包含24个成员,进化分析显示3个明显的亚家族分化,这可能对应着不同的功能特化。进一步的分析揭示了亚家族特异的模式,为功能研究提供了重要线索。这一阶段性进展为深入理解SPL家族在苦荞生长发育中的作用奠定了基础。`,
|
||
next_steps: [
|
||
{
|
||
priority: 'high',
|
||
stage: 'expression',
|
||
description: '进行表达分析,验证不同亚家族的时空表达模式',
|
||
rationale: '基于当前亚家族分化结果,表达模式验证是功能研究的关键下一步,可以揭示亚家族是否在特定组织或发育阶段特异表达。'
|
||
},
|
||
{
|
||
priority: 'medium',
|
||
stage: 'promoter',
|
||
description: '启动子分析,探索亚家族特异的调控机制',
|
||
rationale: '亚家族分化往往伴随调控元件的差异,启动子分析可以揭示不同亚家族的转录调控特征。'
|
||
}
|
||
]
|
||
};
|
||
|
||
this.dialogVisible = true;
|
||
this.loading = false;
|
||
},
|
||
|
||
formatTime(isoString) {
|
||
const date = new Date(isoString);
|
||
return date.toLocaleString('zh-CN');
|
||
},
|
||
|
||
downloadReport(format) {
|
||
ElMessage.success(`开始下载${format.toUpperCase()}格式报告...`);
|
||
// 实际实现:调用 /api/agent/report/{session_id}/download?format={format}
|
||
},
|
||
|
||
copyToClipboard() {
|
||
const text = this.report.biological_story;
|
||
navigator.clipboard.writeText(text).then(() => {
|
||
ElMessage.success('已复制到剪贴板');
|
||
});
|
||
}
|
||
}
|
||
}).use(ElementPlus).mount('#app');
|
||
</script>
|
||
</body>
|
||
</html> |