Files
HaHafeng 8137e3cde2 feat(ssa): Complete SSA-Pro MVP development plan v1.3
Summary:

- Add PRD and architecture design V4 (Brain-Hand model)

- Complete 5 development guide documents

- Pass 3 rounds of team review (v1.0 -> v1.3)

- Add module status guide document

- Update system status document

Key Features:

- Brain-Hand architecture: Node.js + R Docker

- Statistical guardrails with auto degradation

- HITL workflow: PlanCard -> ExecutionTrace -> ResultCard

- Mixed data protocol: inline vs OSS

- Reproducible R code delivery

MVP Scope: 10 statistical tools

Status: Design 100%, ready for development
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-18 21:58:37 +08:00

478 lines
30 KiB
HTML
Raw Permalink 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.
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>SSA-Pro 智能统计分析原型 V2.0</title>
<!-- Tailwind CSS -->
<script src="https://cdn.tailwindcss.com"></script>
<!-- Font Awesome -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<!-- Google Fonts -->
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600&display=swap" rel="stylesheet">
<style>
body { font-family: 'Inter', sans-serif; background-color: #f8fafc; }
/* 自定义滚动条 */
::-webkit-scrollbar { width: 6px; height: 6px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: #cbd5e1; border-radius: 3px; }
::-webkit-scrollbar-thumb:hover { background: #94a3b8; }
/* 动画类 */
.fade-in { animation: fadeIn 0.4s ease-out forwards; opacity: 0; }
.slide-up { animation: slideUp 0.4s ease-out forwards; opacity: 0; transform: translateY(10px); }
.pulse-border { animation: pulseBorder 2s infinite; }
@keyframes fadeIn { to { opacity: 1; } }
@keyframes slideUp { to { transform: translateY(0); opacity: 1; } }
@keyframes pulseBorder { 0% { border-color: #3b82f6; box-shadow: 0 0 0 0 rgba(59, 130, 246, 0.4); } 70% { border-color: #3b82f6; box-shadow: 0 0 0 6px rgba(59, 130, 246, 0); } 100% { border-color: #3b82f6; box-shadow: 0 0 0 0 rgba(59, 130, 246, 0); } }
/* 三线表样式 (APA Style) */
.apa-table { width: 100%; border-collapse: collapse; font-variant-numeric: tabular-nums; }
.apa-table thead th { border-top: 2px solid #1e293b; border-bottom: 1px solid #1e293b; padding: 8px; text-align: left; font-weight: 600; }
.apa-table tbody td { padding: 8px; border-bottom: 1px solid #e2e8f0; }
.apa-table tbody tr:last-child td { border-bottom: 2px solid #1e293b; }
/* 树状结构连接线 */
.tree-line { position: absolute; left: 14px; top: 24px; bottom: -16px; width: 1px; background-color: #e2e8f0; }
.tree-item:last-child .tree-line { display: none; }
</style>
</head>
<body class="h-screen flex overflow-hidden text-slate-800">
<!-- 左侧侧边栏 -->
<aside class="w-64 bg-white border-r border-slate-200 flex flex-col z-20 flex-shrink-0 shadow-sm">
<!-- Logo -->
<div class="h-16 flex items-center px-5 border-b border-slate-100">
<div class="w-8 h-8 bg-blue-600 rounded-lg flex items-center justify-center text-white mr-3 shadow-sm">
<i class="fa-solid fa-dna"></i>
</div>
<div>
<div class="font-bold text-slate-800 leading-none">SSA-Pro</div>
<div class="text-[10px] text-slate-400 mt-1">智能统计分析 V2.0</div>
</div>
</div>
<!-- Action Buttons (New) -->
<div class="p-4 space-y-3">
<button onclick="triggerUpload()" class="w-full bg-blue-600 hover:bg-blue-700 text-white py-2.5 rounded-lg text-sm font-medium transition flex items-center justify-center gap-2 shadow-md shadow-blue-100">
<i class="fa-solid fa-upload"></i> 导入数据 (Excel/CSV)
</button>
<button onclick="location.reload()" class="w-full bg-white border border-slate-200 text-slate-600 hover:bg-slate-50 py-2.5 rounded-lg text-sm font-medium transition flex items-center justify-center gap-2">
<i class="fa-solid fa-plus"></i> 新建会话
</button>
</div>
<!-- History -->
<div class="flex-1 overflow-y-auto px-3 py-2 space-y-1">
<div class="px-3 text-xs font-semibold text-slate-400 uppercase tracking-wider mb-2">最近分析</div>
<div class="group flex items-center gap-3 px-3 py-2 bg-blue-50 text-blue-700 rounded-md cursor-pointer border border-blue-100">
<i class="fa-regular fa-chart-bar text-blue-500"></i>
<div class="flex-1 truncate text-xs font-medium">血糖性别差异分析</div>
</div>
<div class="group flex items-center gap-3 px-3 py-2 hover:bg-slate-50 text-slate-600 rounded-md cursor-pointer transition">
<i class="fa-regular fa-clock text-slate-400"></i>
<div class="flex-1 truncate text-xs">肺癌生存期 Cox 回归</div>
</div>
</div>
<!-- Current Data Status -->
<div id="sidebar-data-status" class="p-4 border-t border-slate-100 bg-slate-50 transition-all duration-500 opacity-50 grayscale pointer-events-none">
<div class="flex items-center justify-between mb-2">
<div class="flex items-center gap-2 text-xs font-bold text-slate-700">
<i class="fa-solid fa-database text-blue-500"></i> 当前数据集
</div>
<span class="w-2 h-2 bg-green-500 rounded-full animate-pulse"></span>
</div>
<div class="bg-white border border-slate-200 rounded p-2.5 shadow-sm">
<div class="flex items-center gap-2 mb-1">
<i class="fa-solid fa-file-csv text-green-600 text-lg"></i>
<span class="text-xs font-medium truncate text-slate-700">diabetes_data.csv</span>
</div>
<div class="text-[10px] text-slate-400 flex gap-3 mt-1">
<span>150 行</span>
<span>12 列</span>
<span>24KB</span>
</div>
</div>
</div>
</aside>
<!-- 主工作区 -->
<main class="flex-1 flex flex-col bg-[#f8fafc] relative">
<!-- Header -->
<header class="h-16 border-b border-slate-200 flex items-center justify-between px-8 bg-white shadow-sm z-10">
<h2 class="font-medium text-slate-700 flex items-center gap-2">
<span class="text-slate-400">会话 /</span> 血糖性别差异分析
</h2>
<div class="flex items-center gap-3">
<button class="w-8 h-8 rounded-full hover:bg-slate-100 text-slate-500 flex items-center justify-center transition"><i class="fa-regular fa-bell"></i></button>
<button class="w-8 h-8 rounded-full bg-slate-200 flex items-center justify-center text-slate-600 font-bold text-xs border-2 border-white shadow-sm">DR</button>
</div>
</header>
<!-- Chat Flow -->
<div id="chat-container" class="flex-1 overflow-y-auto p-8 space-y-8 scroll-smooth pb-32">
<!-- 1. System Welcome (Upload Guide) -->
<div class="flex gap-4 max-w-4xl mx-auto">
<div class="w-10 h-10 rounded-full bg-blue-600 flex items-center justify-center text-white flex-shrink-0 shadow-md">
<i class="fa-solid fa-robot"></i>
</div>
<div class="space-y-4 flex-1">
<div class="bg-white p-5 rounded-2xl rounded-tl-none shadow-sm border border-slate-100 max-w-2xl text-slate-600 text-sm leading-relaxed">
<p class="mb-3 font-medium text-slate-800">你好!我是 SSA 智能统计助手。</p>
<p>请先上传您的研究数据Excel 或 CSV我将为您自动解析数据结构并规划分析方案。</p>
<!-- Upload Area Inside Chat -->
<div id="upload-zone" onclick="triggerUpload()" class="mt-4 border-2 border-dashed border-blue-200 bg-blue-50/50 rounded-xl p-6 text-center cursor-pointer hover:border-blue-400 hover:bg-blue-50 transition group">
<div class="w-12 h-12 bg-white rounded-full flex items-center justify-center text-blue-500 mx-auto mb-3 shadow-sm group-hover:scale-110 transition">
<i class="fa-solid fa-cloud-arrow-up text-xl"></i>
</div>
<p class="text-blue-700 font-medium">点击上传数据文件</p>
<p class="text-xs text-slate-400 mt-1">支持 .xlsx, .csv (最大 20MB)</p>
</div>
<!-- Upload Progress (Hidden Initially) -->
<div id="upload-progress" class="hidden mt-4 bg-slate-50 rounded-xl p-4 border border-slate-200">
<div class="flex items-center gap-3 mb-2">
<i class="fa-solid fa-file-csv text-green-500 text-xl"></i>
<div class="flex-1">
<div class="flex justify-between text-xs mb-1">
<span class="font-medium text-slate-700">diabetes_data.csv</span>
<span class="text-blue-600">上传中...</span>
</div>
<div class="h-1.5 bg-slate-200 rounded-full overflow-hidden">
<div class="h-full bg-blue-500 rounded-full w-2/3 animate-pulse"></div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- 2. System Confirmation (Hidden Initially) -->
<div id="data-loaded-msg" class="hidden flex gap-4 max-w-4xl mx-auto fade-in">
<div class="w-10 h-10 rounded-full bg-blue-600 flex items-center justify-center text-white flex-shrink-0 shadow-md">
<i class="fa-solid fa-robot"></i>
</div>
<div class="bg-white p-4 rounded-2xl rounded-tl-none shadow-sm border border-slate-100 max-w-2xl text-slate-600 text-sm">
<div class="flex items-center gap-2 text-green-600 font-medium mb-2">
<i class="fa-solid fa-circle-check"></i> 数据加载成功
</div>
<p>已解析 <strong>150 条记录</strong>,包含 Gender, Age, GLU, BMI 等 12 个变量。</p>
<p class="mt-2 text-slate-500">您可以直接告诉我您的分析目标,例如:<br>“分析性别对血糖的影响” 或 “做一下年龄和血压的相关性”。</p>
</div>
</div>
<!-- 3. User Intent (Hidden Initially) -->
<div id="user-msg" class="hidden flex gap-4 max-w-4xl mx-auto flex-row-reverse fade-in">
<div class="w-10 h-10 rounded-full bg-slate-200 flex items-center justify-center text-slate-500 flex-shrink-0">
<i class="fa-solid fa-user"></i>
</div>
<div class="bg-blue-600 px-5 py-3 rounded-2xl rounded-tr-none max-w-2xl text-white shadow-md text-sm">
比较不同性别组的血糖GLU是否有差异。
</div>
</div>
<!-- 4. Plan Card (Hidden Initially) -->
<div id="plan-card-container" class="hidden flex gap-4 max-w-4xl mx-auto fade-in">
<div class="w-10 h-10 rounded-full bg-blue-600 flex items-center justify-center text-white flex-shrink-0 shadow-md">
<i class="fa-solid fa-wand-magic-sparkles"></i>
</div>
<div class="flex-1 space-y-3 max-w-2xl">
<p class="text-sm text-slate-600 bg-white p-3 rounded-xl rounded-tl-none shadow-sm border border-slate-100 inline-block">
收到,我为您规划了以下分析方案,请确认:
</p>
<!-- Plan Card -->
<div class="border border-slate-200 bg-white rounded-xl shadow-sm overflow-hidden">
<div class="bg-slate-50 px-4 py-3 border-b border-slate-200 flex justify-between items-center">
<span class="font-semibold text-slate-800 text-sm"><i class="fa-solid fa-list-check text-blue-500 mr-2"></i>分析方案确认</span>
<span class="text-xs bg-blue-100 text-blue-700 px-2 py-0.5 rounded font-medium">T-Test</span>
</div>
<div class="p-5 space-y-4">
<!-- Variables -->
<div class="flex gap-4">
<div class="flex-1 bg-slate-50 p-3 rounded border border-slate-100">
<div class="text-[10px] text-slate-400 uppercase font-bold mb-1">分组变量 (Group)</div>
<div class="text-sm font-medium text-slate-800">Gender <span class="text-xs text-slate-400 font-normal">(分类: Male/Female)</span></div>
</div>
<div class="flex-1 bg-slate-50 p-3 rounded border border-slate-100">
<div class="text-[10px] text-slate-400 uppercase font-bold mb-1">检验变量 (Value)</div>
<div class="text-sm font-medium text-slate-800">GLU <span class="text-xs text-slate-400 font-normal">(数值型)</span></div>
</div>
</div>
<!-- Guardrails -->
<div class="text-xs text-amber-700 bg-amber-50 p-3 rounded border border-amber-100">
<div class="font-bold mb-1"><i class="fa-solid fa-shield-halved mr-1"></i> 统计护栏 (自动执行)</div>
<ul class="list-disc list-inside space-y-0.5 opacity-80">
<li>Shapiro-Wilk 正态性检验</li>
<li>Levene 方差齐性检验</li>
</ul>
<div class="mt-2 pt-2 border-t border-amber-200 font-medium">
⚠️ 若正态性检验失败,将自动降级为 Wilcoxon 秩和检验。
</div>
</div>
</div>
<!-- Actions -->
<div class="px-5 py-3 border-t border-slate-100 flex justify-end gap-3 bg-slate-50">
<button class="text-xs text-slate-500 hover:text-slate-700 font-medium px-3 py-2 rounded hover:bg-slate-200 transition">修改参数</button>
<button onclick="executeAnalysis()" id="btn-execute" class="text-xs bg-blue-600 text-white px-4 py-2 rounded font-medium hover:bg-blue-700 transition shadow-sm flex items-center gap-2">
<i class="fa-solid fa-play"></i> 确认并执行
</button>
</div>
</div>
</div>
</div>
<!-- 5. Execution & Result (Dynamic) -->
<div id="execution-result-container" class="hidden flex-col gap-6 max-w-4xl mx-auto">
<!-- Trace -->
<div class="flex gap-4">
<div class="w-10 h-10 rounded-full bg-white border border-slate-200 flex items-center justify-center text-slate-400 flex-shrink-0 mt-1">
<i class="fa-solid fa-terminal text-sm"></i>
</div>
<div class="bg-white border border-slate-200 rounded-xl p-4 shadow-sm max-w-2xl w-full slide-up">
<div class="text-xs font-bold text-slate-400 uppercase mb-3 tracking-wider flex justify-between">
<span>执行路径</span>
<span class="text-green-600"><i class="fa-solid fa-check"></i> 完成</span>
</div>
<div class="space-y-3 font-mono text-xs relative pl-2">
<!-- Line -->
<div class="absolute left-[19px] top-2 bottom-4 w-px bg-slate-200"></div>
<!-- Items -->
<div class="flex items-center gap-3 relative z-10">
<div class="w-4 h-4 rounded-full bg-green-100 border border-green-300 flex items-center justify-center text-[8px] text-green-600"><i class="fa-solid fa-check"></i></div>
<span class="text-slate-600">加载数据 (n=150)</span>
</div>
<div class="flex items-start gap-3 relative z-10">
<div class="w-4 h-4 rounded-full bg-blue-100 border border-blue-300 flex items-center justify-center text-[8px] text-blue-600 mt-0.5"><i class="fa-solid fa-shield"></i></div>
<div>
<span class="text-slate-800 font-medium">正态性检验 (Shapiro-Wilk)</span>
<div class="mt-1">
<span class="bg-red-50 text-red-600 px-1.5 py-0.5 rounded border border-red-100 font-bold">P = 0.002 (< 0.05) </span>
<span class="ml-2 text-slate-400">-> 拒绝正态假设</span>
</div>
</div>
</div>
<div class="flex items-center gap-3 relative z-10">
<div class="w-4 h-4 rounded-full bg-amber-100 border border-amber-300 flex items-center justify-center text-[8px] text-amber-600"><i class="fa-solid fa-arrow-right-arrow-left"></i></div>
<span class="text-amber-700 font-medium">策略切换: T-Test -> Wilcoxon Test</span>
</div>
<div class="flex items-center gap-3 relative z-10">
<div class="w-4 h-4 rounded-full bg-indigo-100 border border-indigo-300 flex items-center justify-center text-[8px] text-indigo-600"><i class="fa-solid fa-calculator"></i></div>
<span class="text-slate-800 font-bold">计算完成</span>
</div>
</div>
</div>
</div>
<!-- Final Result Card (V2 Major Update) -->
<div class="flex gap-4 slide-up" style="animation-delay: 0.2s;">
<div class="w-10 h-10 rounded-full bg-gradient-to-br from-blue-600 to-indigo-600 flex items-center justify-center text-white flex-shrink-0 shadow-lg mt-1">
<i class="fa-solid fa-file-medical-alt"></i>
</div>
<div class="bg-white border border-slate-200 rounded-xl shadow-md overflow-hidden max-w-3xl w-full">
<!-- Header -->
<div class="bg-slate-50 px-6 py-4 border-b border-slate-200">
<h3 class="font-bold text-slate-800">分析结果报告</h3>
<p class="text-xs text-slate-500 mt-1">基于非参数检验 (Wilcoxon rank sum test)</p>
</div>
<!-- 1. Statistical Tables & Plots -->
<div class="p-6 border-b border-slate-100">
<div class="flex items-center gap-2 mb-4">
<div class="w-1 h-4 bg-blue-600 rounded-full"></div>
<h4 class="font-semibold text-slate-800 text-sm">表 1. 组间差异比较 (三线表)</h4>
</div>
<!-- APA Table -->
<div class="overflow-x-auto mb-6">
<table class="apa-table text-sm text-slate-700">
<thead>
<tr>
<th class="w-32">Group</th>
<th>N</th>
<th>GLU (Median [IQR])</th>
<th>Statistic (W)</th>
<th>P-Value</th>
</tr>
</thead>
<tbody>
<tr>
<td>Male</td>
<td>78</td>
<td>5.80 [5.20 - 6.50]</td>
<td rowspan="2" class="align-middle border-l border-slate-100">1254.5</td>
<td rowspan="2" class="align-middle border-l border-slate-100 font-bold text-slate-900">0.002 **</td>
</tr>
<tr>
<td>Female</td>
<td>72</td>
<td>5.10 [4.80 - 5.50]</td>
</tr>
</tbody>
</table>
<p class="text-[10px] text-slate-400 mt-2 italic">Note: IQR = Interquartile Range; ** P < 0.01.</p>
</div>
<!-- Plot Area -->
<div class="flex items-center gap-2 mb-3">
<div class="w-1 h-4 bg-blue-600 rounded-full"></div>
<h4 class="font-semibold text-slate-800 text-sm">图 1. 可视化结果</h4>
</div>
<div class="bg-slate-50 border border-slate-100 rounded-lg p-4 flex justify-center">
<!-- Mock Plot -->
<div class="relative w-64 h-40 bg-white border border-slate-200 shadow-sm rounded flex items-end justify-around px-8 pb-6">
<!-- Bars -->
<div class="w-8 h-24 bg-blue-400 border border-blue-600 relative opacity-80"></div>
<div class="w-8 h-16 bg-red-400 border border-red-600 relative opacity-80"></div>
<!-- Axes -->
<div class="absolute bottom-6 left-4 right-4 h-px bg-slate-800"></div>
<div class="absolute bottom-6 left-4 top-4 w-px bg-slate-800"></div>
<!-- Labels -->
<div class="absolute bottom-2 left-10 text-[8px]">Male</div>
<div class="absolute bottom-2 right-10 text-[8px]">Female</div>
<!-- Significance -->
<div class="absolute top-6 left-10 right-10 h-2 border-t border-l border-r border-slate-800"></div>
<div class="absolute top-2 left-0 right-0 text-center text-[8px] font-bold">P < 0.01</div>
</div>
</div>
</div>
<!-- 2. Methodology & Interpretation -->
<div class="p-6 bg-slate-50/50 border-b border-slate-100">
<div class="flex items-center gap-2 mb-3">
<div class="w-1 h-4 bg-indigo-600 rounded-full"></div>
<h4 class="font-semibold text-slate-800 text-sm">方法与结果解读</h4>
</div>
<div class="prose prose-sm max-w-none text-slate-600 text-sm leading-relaxed">
<p><strong>统计方法:</strong>首先对数据进行正态性检验Shapiro-Wilk test。由于 GLU 数据不满足正态分布P < 0.05故采用非参数的 <strong>Wilcoxon 秩和检验</strong> (Mann-Whitney U test) 比较两组差异。</p>
<p class="mt-2"><strong>结果解读:</strong>结果表明,男性组和女性组的血糖水平存在显著差异 (W=1254.5, P=0.002)。男性组的中位血糖水平 (5.80) 显著高于女性组 (5.10)。</p>
</div>
</div>
<!-- 3. Assets Delivery (New) -->
<div class="bg-slate-100 p-4 flex items-center justify-between">
<div class="flex items-center gap-2 text-slate-500 text-xs font-semibold uppercase tracking-wide">
<i class="fa-solid fa-box-archive"></i> 资产交付
</div>
<div class="flex gap-3">
<button class="bg-white border border-slate-300 text-slate-700 px-3 py-1.5 rounded-lg text-xs font-medium hover:bg-slate-50 hover:text-blue-600 hover:border-blue-300 transition shadow-sm flex items-center gap-2">
<i class="fa-brands fa-r-project text-blue-600"></i> 下载 R 代码
</button>
<button class="bg-blue-600 border border-blue-600 text-white px-3 py-1.5 rounded-lg text-xs font-medium hover:bg-blue-700 transition shadow-sm flex items-center gap-2">
<i class="fa-regular fa-file-word"></i> 导出分析报告 (Word)
</button>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Input Area -->
<div class="p-6 bg-white border-t border-slate-200 z-20">
<div class="max-w-4xl mx-auto relative">
<textarea id="user-input" class="w-full bg-slate-50 border border-slate-200 rounded-xl px-4 py-3.5 pr-14 focus:outline-none focus:ring-2 focus:ring-blue-500/20 focus:border-blue-500 resize-none text-sm shadow-inner transition placeholder-slate-400" rows="1" placeholder="在此输入新的分析需求..."></textarea>
<button onclick="handleSend()" class="absolute right-2 bottom-2 w-9 h-9 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition flex items-center justify-center shadow-md">
<i class="fa-solid fa-paper-plane text-xs"></i>
</button>
</div>
<div class="text-center mt-2.5">
<span class="text-[10px] text-slate-400 flex items-center justify-center gap-1">
<i class="fa-solid fa-shield-halved text-slate-300"></i> SSA-Pro Generate | 仅供科研参考
</span>
</div>
</div>
</main>
<script>
// --- 交互逻辑 ---
// 1. 触发上传
function triggerUpload() {
// 隐藏上传区域,显示进度
const uploadZone = document.getElementById('upload-zone');
const progress = document.getElementById('upload-progress');
if(uploadZone) uploadZone.classList.add('hidden');
if(progress) progress.classList.remove('hidden');
// 模拟延迟
setTimeout(() => {
// 更新侧边栏状态
const sbStatus = document.getElementById('sidebar-data-status');
sbStatus.classList.remove('opacity-50', 'grayscale', 'pointer-events-none');
// 显示系统确认消息
document.getElementById('data-loaded-msg').classList.remove('hidden');
// 滚动到底部
scrollToBottom();
}, 1500);
}
// 2. 发送消息
function handleSend() {
const input = document.getElementById('user-input');
if (!input.value && !document.getElementById('user-msg').classList.contains('hidden')) return;
// 如果是第一次点击发送 (Demo模式)
if (document.getElementById('user-msg').classList.contains('hidden')) {
// 显示用户消息
document.getElementById('user-msg').classList.remove('hidden');
input.value = '';
scrollToBottom();
// 延迟显示 Plan Card
setTimeout(() => {
document.getElementById('plan-card-container').classList.remove('hidden');
scrollToBottom();
}, 1000);
}
}
// 3. 执行分析
function executeAnalysis() {
const btn = document.getElementById('btn-execute');
btn.innerHTML = '<i class="fa-solid fa-circle-notch fa-spin"></i> 计算中...';
btn.classList.add('opacity-75', 'cursor-not-allowed');
// 延迟显示结果
setTimeout(() => {
document.getElementById('execution-result-container').classList.remove('hidden');
document.getElementById('execution-result-container').classList.add('flex');
// 恢复按钮状态
btn.innerHTML = '<i class="fa-solid fa-check"></i> 已执行';
btn.className = "text-xs bg-green-100 text-green-700 border border-green-200 px-4 py-2 rounded font-medium cursor-default";
scrollToBottom();
}, 1500);
}
function scrollToBottom() {
const container = document.getElementById('chat-container');
container.scrollTo({ top: container.scrollHeight, behavior: 'smooth' });
}
// 回车发送
document.getElementById('user-input').addEventListener('keypress', function (e) {
if (e.key === 'Enter') handleSend();
});
</script>
</body>
</html>