Files
AIclinicalresearch/docs/03-业务模块/RVW-稿件审查系统/01-需求分析/智能审稿V7.html
HaHafeng 179afa2c6b feat(rvw): Complete RVW module development Phase 1-3
Summary:
- Migrate backend to modules/rvw with v2 API routes (/api/v2/rvw)
- Add new database fields: selectedAgents, editorialScore, methodologyStatus, picoExtract, isArchived
- Create frontend module in frontend-v2/src/modules/rvw
- Implement Dashboard with task list, filtering, batch operations
- Implement ReportDetail with dual tabs (editorial/methodology)
- Implement AgentModal for intelligent agent selection
- Register RVW module in moduleRegistry.ts
- Add navigation entry in TopNavigation
- Update documentation for RVW module status (v3.0)
- Update system status document (v2.9)

Features:
- User can select agents: editorial, methodology, or both
- Support batch task execution
- Task status filtering
- Replace console.log with logger service
- Maintain v1 API backward compatibility

Tested: Frontend and backend verified locally
Status: 85% complete (Phase 1-3 done)
2026-01-07 22:39:08 +08:00

529 lines
37 KiB
HTML
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.
<!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.tailwindcss.com"></script>
<!-- 引入 Lucide 图标 (UMD版) -->
<script src="https://unpkg.com/lucide@latest/dist/umd/lucide.min.js"></script>
<style>
body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif; background-color: #f8fafc; color: #334155; }
/* 状态标签 */
.tag { display: inline-flex; align-items: center; padding: 2px 8px; border-radius: 4px; font-size: 11px; font-weight: 600; line-height: 1.5; border: 1px solid transparent; }
.tag-blue { background: #eff6ff; color: #1d4ed8; border-color: #dbeafe; }
.tag-purple { background: #f5f3ff; color: #6d28d9; border-color: #ede9fe; }
.tag-green { background: #f0fdf4; color: #15803d; border-color: #dcfce7; }
.tag-amber { background: #fffbeb; color: #b45309; border-color: #fef3c7; }
.tag-gray { background: #f8fafc; color: #64748b; border-color: #e2e8f0; }
/* 筛选 Chips */
.filter-chip {
padding: 4px 12px; border-radius: 9999px; font-size: 13px; font-weight: 500; cursor: pointer; transition: all 0.2s; border: 1px solid transparent; color: #64748b;
}
.filter-chip:hover { background-color: #f1f5f9; color: #0f172a; }
.filter-chip.active { background-color: #eff6ff; color: #2563eb; border-color: #bfdbfe; font-weight: 600; }
/* 选中行样式 */
tr.selected { background-color: #eff6ff; }
/* Tab 激活样式 */
.tab-btn { border-bottom: 2px solid transparent; color: #64748b; }
.tab-btn:hover { color: #334155; }
.tab-btn.active { color: #2563eb; border-bottom: 2px solid #2563eb; font-weight: 600; }
/* 动画 */
.fade-in { animation: fadeIn 0.4s cubic-bezier(0.16, 1, 0.3, 1); }
.slide-up { animation: slideUp 0.4s cubic-bezier(0.16, 1, 0.3, 1); }
@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }
@keyframes slideUp { from { opacity: 0; transform: translateY(20px); } to { opacity: 1; transform: translateY(0); } }
/* 侧边栏 Tooltip */
.sidebar-btn:hover::after {
content: attr(data-title); position: absolute; left: 100%; top: 50%; transform: translateY(-50%); margin-left: 12px; background: #1e293b; color: white; padding: 6px 10px; border-radius: 6px; font-size: 12px; white-space: nowrap; z-index: 50; box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
}
/* 评分环 */
.score-circle {
width: 80px; height: 80px; border-radius: 50%; display: flex; flex-direction: column; align-items: center; justify-content: center; border: 6px solid #e2e8f0;
}
.score-circle.pass { border-color: #22c55e; background: #f0fdf4; color: #15803d; }
.score-circle.warn { border-color: #f59e0b; background: #fffbeb; color: #b45309; }
/* 登录页背景 */
.login-bg {
background-image: radial-gradient(circle at 10% 20%, rgb(239, 246, 255) 0%, rgb(255, 255, 255) 90%);
}
</style>
</head>
<body class="h-screen overflow-hidden">
<!-- 视图 0: 登录页 (新增模块) -->
<div id="view-login" class="fixed inset-0 z-50 login-bg flex flex-col items-center justify-center p-4">
<div class="w-full max-w-md bg-white rounded-2xl shadow-xl p-8 slide-up border border-slate-100">
<!-- 品牌 LOGO 区域 -->
<div class="flex flex-col items-center mb-8">
<div class="w-16 h-16 bg-indigo-600 rounded-2xl flex items-center justify-center text-white shadow-lg mb-4 transform rotate-3">
<i data-lucide="brain-circuit" class="w-10 h-10"></i>
</div>
<h1 class="text-2xl font-bold text-slate-800">中华脑血管病杂志</h1>
<p class="text-sm text-slate-500 mt-2">智能审稿辅助系统 v1.0</p>
</div>
<!-- 登录表单 -->
<form onsubmit="handleLogin(event)" class="space-y-5">
<div>
<label class="block text-sm font-bold text-slate-700 mb-1.5">账号</label>
<div class="relative">
<i data-lucide="user" class="absolute left-3 top-2.5 w-5 h-5 text-slate-400"></i>
<input type="text" value="editor_admin" class="w-full pl-10 pr-4 py-2 border border-slate-300 rounded-lg focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500 outline-none transition-all" placeholder="请输入编辑账号">
</div>
</div>
<div>
<label class="block text-sm font-bold text-slate-700 mb-1.5">密码</label>
<div class="relative">
<i data-lucide="lock" class="absolute left-3 top-2.5 w-5 h-5 text-slate-400"></i>
<input type="password" value="123456" class="w-full pl-10 pr-4 py-2 border border-slate-300 rounded-lg focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500 outline-none transition-all" placeholder="请输入密码">
</div>
</div>
<div class="flex items-center justify-between text-sm">
<label class="flex items-center gap-2 cursor-pointer">
<input type="checkbox" checked class="w-4 h-4 text-indigo-600 rounded border-gray-300">
<span class="text-slate-600">记住我</span>
</label>
<a href="#" class="text-indigo-600 hover:underline font-medium">忘记密码?</a>
</div>
<button type="submit" class="w-full bg-indigo-600 hover:bg-indigo-700 text-white font-bold py-2.5 rounded-lg shadow-md transition-all hover:shadow-lg flex items-center justify-center gap-2">
登录系统 <i data-lucide="arrow-right" class="w-4 h-4"></i>
</button>
</form>
<p class="text-center text-xs text-slate-400 mt-8">
&copy; 2025 AI审稿技术支持平台 · 技术支持
</p>
</div>
</div>
<!-- 主系统容器 (登录后显示) -->
<div id="app-container" class="hidden h-full flex">
<!-- 侧边栏 -->
<aside class="w-18 bg-slate-900 flex flex-col items-center py-6 gap-4 z-20 shadow-xl flex-shrink-0 relative">
<!-- 客户 LOGO (侧边栏折叠版) -->
<div class="w-10 h-10 bg-indigo-500 rounded-xl flex items-center justify-center text-white shadow-lg mb-4" title="中华脑血管病杂志">
<i data-lucide="brain-circuit" class="w-6 h-6"></i>
</div>
<button onclick="switchView('list')" class="sidebar-btn w-10 h-10 rounded-lg bg-white/10 text-white flex items-center justify-center hover:bg-indigo-600 transition-colors relative" data-title="审稿工作台">
<i data-lucide="layout-grid" class="w-5 h-5"></i>
</button>
<button onclick="alert('历史归档模式此处将显示7天前已完成的稿件。')" class="sidebar-btn w-10 h-10 rounded-lg text-slate-400 flex items-center justify-center hover:bg-white/10 hover:text-white transition-colors relative" data-title="历史归档">
<i data-lucide="archive" class="w-5 h-5"></i>
</button>
<div class="mt-auto flex flex-col gap-4 relative">
<button onclick="openSettings()" class="sidebar-btn w-10 h-10 rounded-lg text-slate-400 flex items-center justify-center hover:bg-white/10 hover:text-white transition-colors relative" data-title="系统设置">
<i data-lucide="settings" class="w-5 h-5"></i>
</button>
<!-- 用户头像 (点击触发菜单) -->
<div class="relative">
<div onclick="toggleUserMenu()" class="w-10 h-10 rounded-full bg-gradient-to-tr from-indigo-500 to-purple-500 flex items-center justify-center text-xs font-bold text-white border-2 border-slate-700 cursor-pointer hover:border-white transition-all shadow-md">
主编
</div>
<!-- 用户悬浮菜单 -->
<div id="user-menu" class="hidden absolute bottom-0 left-12 ml-2 w-48 bg-white rounded-lg shadow-xl border border-gray-100 py-1 z-50 animate-in fade-in zoom-in-95 origin-bottom-left">
<div class="px-4 py-3 border-b border-gray-50 bg-slate-50">
<p class="text-sm font-bold text-slate-800">王主编</p>
<p class="text-xs text-slate-500 truncate">editor@chinastroke.com</p>
</div>
<button onclick="openChangePassword()" class="w-full text-left px-4 py-2 text-sm text-slate-700 hover:bg-indigo-50 hover:text-indigo-600 flex items-center gap-2">
<i data-lucide="key" class="w-4 h-4"></i> 修改密码
</button>
<button onclick="handleLogout()" class="w-full text-left px-4 py-2 text-sm text-red-600 hover:bg-red-50 flex items-center gap-2">
<i data-lucide="log-out" class="w-4 h-4"></i> 退出登录
</button>
</div>
</div>
</div>
</aside>
<!-- 主内容区 -->
<main class="flex-1 flex flex-col min-w-0 bg-white">
<!-- 视图 1: 审稿列表 (Dashboard) -->
<div id="view-list" class="flex-1 flex flex-col h-full relative fade-in">
<!-- 顶部核心操作区 -->
<header class="bg-white px-8 pt-6 pb-4 border-b border-gray-100 flex-shrink-0 z-10">
<div class="flex justify-between items-center mb-6">
<!-- 客户 LOGO 展示区 (新增) -->
<div class="flex items-center gap-3">
<div class="bg-indigo-50 p-2 rounded-lg text-indigo-700">
<i data-lucide="brain-circuit" class="w-6 h-6"></i>
</div>
<div>
<h1 class="text-xl font-bold text-slate-800">中华脑血管病杂志 · 智能审稿系统</h1>
<p class="text-xs text-slate-500">当前工作区:编辑部初审组</p>
</div>
</div>
<div class="flex gap-3">
<input type="file" id="file-upload" multiple class="hidden" onchange="handleFileUpload(this)">
<button onclick="document.getElementById('file-upload').click()" class="px-5 py-2.5 bg-indigo-600 hover:bg-indigo-700 text-white rounded-lg text-sm font-bold flex items-center gap-2 shadow-sm transition-all hover:-translate-y-0.5">
<i data-lucide="upload-cloud" class="w-4 h-4"></i> 上传新稿件
</button>
</div>
</div>
<!-- 筛选栏 -->
<div class="flex items-center justify-between">
<div class="flex items-center gap-2">
<span class="text-xs font-bold text-slate-400 uppercase tracking-wider mr-2">状态:</span>
<div class="filter-chip active" onclick="activateFilter(this)">全部 <span class="ml-1 text-xs opacity-60 bg-black/10 px-1.5 rounded-full">3</span></div>
<div class="filter-chip" onclick="activateFilter(this)">待处理 <span class="ml-1 text-xs opacity-60 bg-slate-200 px-1.5 rounded-full">1</span></div>
<div class="filter-chip" onclick="activateFilter(this)">已完成</div>
</div>
<div class="h-4 w-px bg-gray-200 mx-2"></div>
<div class="flex items-center gap-2">
<span class="text-xs font-bold text-slate-400 uppercase tracking-wider mr-2">时间:</span>
<div class="filter-chip active" onclick="activateFilter(this)">不限</div>
<div class="filter-chip" onclick="activateFilter(this)">今天</div>
<div class="filter-chip" onclick="activateFilter(this)">近7天</div>
</div>
</div>
</header>
<!-- 批量操作栏 -->
<div id="batch-toolbar" class="hidden absolute top-36 left-1/2 transform -translate-x-1/2 bg-slate-800 text-white px-5 py-3 rounded-full shadow-2xl flex items-center gap-6 z-30 fade-in border border-slate-700">
<div class="flex items-center gap-2">
<div class="w-5 h-5 rounded-full bg-indigo-500 flex items-center justify-center text-[10px] font-bold" id="selected-count">0</div>
<span class="text-sm font-medium">个文件已选中</span>
</div>
<div class="h-4 w-px bg-slate-600"></div>
<button onclick="openAgentModal()" class="text-sm font-bold text-white hover:text-indigo-300 flex items-center gap-2 transition-colors">
<i data-lucide="play" class="w-4 h-4 text-green-400"></i> 运行智能审稿
</button>
<button onclick="clearSelection()" class="text-slate-400 hover:text-white ml-2">
<i data-lucide="x" class="w-4 h-4"></i>
</button>
</div>
<!-- 列表区域 -->
<div class="flex-1 overflow-auto bg-slate-50/50 p-6">
<div class="bg-white border border-gray-200 rounded-xl shadow-sm overflow-hidden min-h-[500px]">
<table class="w-full text-left text-sm" id="file-table">
<thead class="bg-gray-50 border-b border-gray-200 text-gray-500 font-semibold uppercase tracking-wider text-xs">
<tr>
<th class="px-6 py-4 w-12"><input type="checkbox" onchange="toggleSelectAll(this)" class="rounded border-gray-300 text-indigo-600 focus:ring-indigo-500 cursor-pointer"></th>
<th class="px-6 py-4 w-1/3">文件名称 / 信息</th>
<th class="px-6 py-4">上传时间</th>
<th class="px-6 py-4">审稿维度</th>
<th class="px-6 py-4">结果摘要</th>
<th class="px-6 py-4 text-right">操作</th>
</tr>
</thead>
<tbody class="divide-y divide-gray-100" id="table-body">
<!-- 已完成示例 -->
<tr class="hover:bg-slate-50 group transition-colors">
<td class="px-6 py-4"><input type="checkbox" onchange="toggleRowSelection(this)" class="row-checkbox rounded border-gray-300 text-indigo-600 focus:ring-indigo-500 cursor-pointer"></td>
<td class="px-6 py-4">
<div class="flex items-center gap-3">
<div class="bg-red-50 text-red-600 p-2.5 rounded-lg border border-red-100">
<i data-lucide="file-text" class="w-5 h-5"></i>
</div>
<div>
<div class="font-bold text-slate-800 text-base mb-0.5 cursor-pointer hover:text-indigo-600" onclick="viewReport(true)">
替雷利珠单抗治疗非小细胞肺癌的临床研究.pdf
</div>
<div class="text-xs text-slate-400 flex items-center gap-2">
<span class="bg-slate-100 px-1.5 rounded">12.5 MB</span> <span></span> <span>王某某</span>
</div>
</div>
</div>
</td>
<td class="px-6 py-4 text-slate-500 font-mono text-xs">10:30</td>
<td class="px-6 py-4">
<div class="flex gap-1.5">
<span class="tag tag-blue">规范性</span>
<span class="tag tag-purple">方法学</span>
</div>
</td>
<td class="px-6 py-4">
<div class="flex flex-col gap-1.5">
<div class="flex items-center gap-2 text-xs">
<div class="w-2 h-2 rounded-full bg-green-500"></div>
<span class="text-slate-600">规范性:</span>
<span class="font-bold text-green-700">92分</span>
</div>
<div class="flex items-center gap-2 text-xs">
<div class="w-2 h-2 rounded-full bg-amber-500"></div>
<span class="text-slate-600">方法学:</span>
<span class="font-bold text-amber-700">存疑</span>
</div>
</div>
</td>
<td class="px-6 py-4 text-right">
<button onclick="viewReport(true)" class="text-indigo-600 font-bold hover:bg-indigo-50 px-3 py-1.5 rounded-md transition-colors text-xs">查看</button>
</td>
</tr>
<!-- 待处理示例 -->
<tr class="hover:bg-slate-50 group transition-colors status-pending">
<td class="px-6 py-4"><input type="checkbox" onchange="toggleRowSelection(this)" class="row-checkbox rounded border-gray-300 text-indigo-600 focus:ring-indigo-500 cursor-pointer"></td>
<td class="px-6 py-4">
<div class="flex items-center gap-3">
<div class="bg-blue-50 text-blue-600 p-2.5 rounded-lg border border-blue-100">
<i data-lucide="file-type-2" class="w-5 h-5"></i>
</div>
<div>
<div class="font-bold text-slate-800 text-base mb-0.5">
高血压药物多中心随机对照试验_V2.docx
</div>
<div class="text-xs text-slate-400 flex items-center gap-2">
<span class="bg-slate-100 px-1.5 rounded">4.2 MB</span> <span></span> <span>李四</span>
</div>
</div>
</div>
</td>
<td class="px-6 py-4 text-slate-500 font-mono text-xs">刚刚</td>
<td class="px-6 py-4"><span class="tag tag-gray">未运行</span></td>
<td class="px-6 py-4"><span class="text-xs text-slate-400 italic">等待发起...</span></td>
<td class="px-6 py-4 text-right">
<button onclick="selectRowAndOpenModal(this)" class="border border-indigo-200 text-indigo-600 hover:bg-indigo-50 px-3 py-1.5 rounded-md transition-colors text-xs font-medium flex items-center gap-1 ml-auto">
<i data-lucide="play" class="w-3 h-3"></i> 开始
</button>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<!-- 视图 2: 详情报告页 (保持 V6 的真实数据) -->
<div id="view-detail" class="hidden flex-1 flex flex-col h-full bg-slate-50 relative animate-in fade-in slide-in-from-bottom-4">
<header class="h-16 bg-white border-b border-gray-200 px-6 flex items-center justify-between sticky top-0 z-20 shadow-sm">
<div class="flex items-center gap-4">
<button onclick="switchView('list')" class="flex items-center gap-2 text-slate-500 hover:text-slate-800 transition-colors px-2 py-1 rounded hover:bg-slate-100">
<i data-lucide="arrow-left" class="w-5 h-5"></i>
<span class="text-sm font-medium">返回列表</span>
</button>
<div class="h-6 w-px bg-slate-200"></div>
<div>
<h1 class="text-base font-bold text-slate-800 flex items-center gap-2">
替雷利珠单抗治疗非小细胞肺癌的临床研究.pdf
<span class="tag tag-blue">V2 修回稿</span>
</h1>
</div>
</div>
<div class="flex items-center gap-3">
<button class="px-3 py-1.5 bg-indigo-600 text-white rounded text-sm font-medium hover:bg-indigo-700 transition shadow-sm flex items-center gap-2">
<i data-lucide="file-check" class="w-4 h-4"></i> 导出报告
</button>
</div>
</header>
<div class="flex-1 overflow-auto p-8 max-w-5xl mx-auto w-full">
<div class="flex gap-1 bg-slate-200/50 p-1 rounded-lg mb-8 w-fit mx-auto">
<button onclick="switchTab('compliance')" id="tab-compliance" class="px-6 py-2 rounded-md text-sm font-bold bg-white text-indigo-600 shadow-sm transition-all">稿约规范性 (92分)</button>
<button onclick="switchTab('methodology')" id="tab-methodology" class="px-6 py-2 rounded-md text-sm font-medium text-slate-500 hover:text-slate-700 transition-all">方法学评估 (存疑)</button>
</div>
<!-- 规范性报告 -->
<div id="content-compliance" class="space-y-6 fade-in">
<div class="bg-white p-6 rounded-2xl shadow-sm border border-green-200 flex items-center gap-8">
<div class="score-circle pass">
<span class="text-2xl font-bold">92</span>
<span class="text-[10px] font-bold uppercase">Pass</span>
</div>
<div class="flex-1">
<h3 class="font-bold text-lg text-slate-800">基本符合稿约规范</h3>
<p class="text-slate-600 text-sm mt-1">AI 已完成 11 项维度检查。主要问题集中在图片清晰度,其他格式(参考文献、伦理声明)均已合规。</p>
</div>
</div>
<div class="bg-white rounded-xl shadow-sm border border-gray-200 overflow-hidden">
<div class="p-4 bg-slate-50 border-b border-gray-200 font-bold text-sm text-slate-700">检测详情</div>
<div class="p-5 border-b border-gray-100 flex gap-4 bg-amber-50/50">
<div class="mt-1 text-amber-500"><i data-lucide="alert-triangle" class="w-5 h-5"></i></div>
<div class="flex-1">
<div class="flex justify-between"><h4 class="font-bold text-sm text-slate-800">图片分辨率不足 (Figure 3)</h4><span class="tag tag-amber">警告</span></div>
<p class="text-sm text-slate-600 mt-1">检测到病理切片图 DPI 为 150低于期刊要求的 300 DPI。</p>
<div class="mt-3 bg-white border border-amber-200 p-3 rounded-lg text-xs text-slate-600"><strong>建议:</strong> 请提供原始高清大图。</div>
</div>
</div>
</div>
</div>
<!-- 方法学报告 -->
<div id="content-methodology" class="hidden space-y-6 fade-in">
<div class="bg-indigo-900 text-white rounded-2xl p-6 shadow-lg">
<div class="flex items-center gap-2 mb-4 opacity-80 text-xs font-bold uppercase tracking-wider"><i data-lucide="brain-circuit" class="w-4 h-4"></i> DeepSeek 智能提取</div>
<div class="grid grid-cols-4 gap-4">
<div class="bg-white/10 p-3 rounded-lg"><div class="text-indigo-300 text-xs uppercase mb-1 font-bold">P</div><div class="text-sm font-medium">非小细胞肺癌</div></div>
<div class="bg-white/10 p-3 rounded-lg"><div class="text-indigo-300 text-xs uppercase mb-1 font-bold">I</div><div class="text-sm font-medium">替雷利珠单抗</div></div>
<div class="bg-white/10 p-3 rounded-lg"><div class="text-indigo-300 text-xs uppercase mb-1 font-bold">C</div><div class="text-sm font-medium">传统化疗</div></div>
<div class="bg-white/10 p-3 rounded-lg"><div class="text-indigo-300 text-xs uppercase mb-1 font-bold">O</div><div class="text-sm font-medium">OS, PFS</div></div>
</div>
</div>
<div class="bg-white rounded-xl border border-red-200 shadow-sm overflow-hidden">
<div class="p-4 bg-red-50 border-b border-red-100 text-red-700 font-bold text-sm flex items-center gap-2"><i data-lucide="x-circle" class="w-4 h-4"></i> 核心逻辑漏洞</div>
<div class="p-6"><h5 class="font-bold text-slate-800 text-sm">统计检验方法缺失</h5><p class="text-sm text-slate-600 mt-1">比较 AUC 时未提及具体检验方法(如 Delong Test仅给出 P 值不严谨。</p></div>
</div>
</div>
</div>
</div>
</main>
<!-- 弹窗:选择智能体 -->
<div id="modal-agent" class="fixed inset-0 bg-slate-900/50 hidden z-50 flex items-center justify-center backdrop-blur-sm">
<div class="bg-white rounded-2xl shadow-2xl w-[400px] overflow-hidden transform transition-all scale-100">
<div class="bg-slate-900 p-5 text-white"><h3 class="font-bold text-lg flex items-center gap-2"><i data-lucide="play-circle" class="w-5 h-5 text-indigo-400"></i> 发起智能审稿</h3></div>
<div class="p-6 space-y-4">
<label class="flex items-start gap-3 p-3 border border-gray-200 rounded-xl hover:border-indigo-500 cursor-pointer transition-colors"><input type="checkbox" checked class="mt-1 w-4 h-4 text-indigo-600 rounded"><div><span class="block font-bold text-slate-800 text-sm">稿约规范性智能体</span><span class="block text-xs text-slate-500 mt-0.5">格式、参考文献、图片</span></div></label>
<label class="flex items-start gap-3 p-3 border border-gray-200 rounded-xl hover:border-indigo-500 cursor-pointer transition-colors"><input type="checkbox" class="mt-1 w-4 h-4 text-indigo-600 rounded"><div><span class="block font-bold text-slate-800 text-sm">方法学统计智能体</span><span class="block text-xs text-slate-500 mt-0.5">DeepSeek 深度逻辑推理</span></div></label>
</div>
<div class="p-4 bg-slate-50 flex justify-end gap-3 border-t border-gray-100">
<button onclick="closeModal()" class="px-4 py-2 text-sm text-slate-600 hover:bg-gray-200 rounded-lg">取消</button>
<button onclick="runBatchTask()" class="px-4 py-2 bg-indigo-600 hover:bg-indigo-700 text-white text-sm font-bold rounded-lg shadow-sm">立即运行</button>
</div>
</div>
</div>
<!-- 弹窗:系统设置 -->
<div id="modal-settings" class="fixed inset-0 bg-slate-900/50 hidden z-50 flex items-center justify-center backdrop-blur-sm">
<div class="bg-white rounded-2xl shadow-2xl w-[400px] p-6">
<h3 class="font-bold text-lg mb-4 text-slate-800">系统设置</h3>
<div class="space-y-4">
<div><label class="block text-sm font-bold text-slate-700 mb-1">期刊 Logo 上传</label><input type="file" class="block w-full text-sm text-slate-500 file:mr-4 file:py-2 file:px-4 file:rounded-full file:border-0 file:text-xs file:font-semibold file:bg-indigo-50 file:text-indigo-700 hover:file:bg-indigo-100"/></div>
<div><label class="block text-sm font-bold text-slate-700 mb-1">默认 AI 模型</label><select class="w-full border border-gray-300 rounded-lg p-2 text-sm"><option>DeepSeek V3</option><option>DeepSeek R1</option></select></div>
</div>
<div class="mt-6 pt-4 border-t border-gray-100 flex justify-end"><button onclick="closeSettings()" class="px-4 py-2 bg-indigo-600 text-white rounded-lg text-sm font-bold">保存设置</button></div>
</div>
</div>
<!-- 弹窗:修改密码 -->
<div id="modal-password" class="fixed inset-0 bg-slate-900/50 hidden z-50 flex items-center justify-center backdrop-blur-sm">
<div class="bg-white rounded-2xl shadow-2xl w-[400px] p-6">
<h3 class="font-bold text-lg mb-4 text-slate-800">修改密码</h3>
<div class="space-y-4">
<div><label class="block text-sm font-bold text-slate-700 mb-1">旧密码</label><input type="password" class="w-full p-2 border rounded-lg"></div>
<div><label class="block text-sm font-bold text-slate-700 mb-1">新密码</label><input type="password" class="w-full p-2 border rounded-lg"></div>
<div><label class="block text-sm font-bold text-slate-700 mb-1">确认新密码</label><input type="password" class="w-full p-2 border rounded-lg"></div>
</div>
<div class="mt-6 pt-4 border-t border-gray-100 flex justify-end gap-2">
<button onclick="closeChangePassword()" class="px-4 py-2 text-sm text-slate-600">取消</button>
<button onclick="closeChangePassword(); alert('密码修改成功');" class="px-4 py-2 bg-indigo-600 text-white rounded-lg text-sm font-bold">确认修改</button>
</div>
</div>
</div>
</div>
<script>
lucide.createIcons();
// 1. 登录逻辑
function handleLogin(e) {
e.preventDefault();
const btn = e.target.querySelector('button');
const originalText = btn.innerHTML;
btn.innerHTML = `<i data-lucide="loader-2" class="w-4 h-4 animate-spin"></i> 登录中...`;
lucide.createIcons();
setTimeout(() => {
document.getElementById('view-login').classList.add('hidden');
document.getElementById('app-container').classList.remove('hidden');
lucide.createIcons();
}, 1000);
}
function handleLogout() {
if(confirm('确定要退出登录吗?')) {
window.location.reload();
}
}
// 视图切换
function switchView(viewId) {
document.getElementById('view-list').classList.add('hidden');
document.getElementById('view-detail').classList.add('hidden');
document.getElementById('view-' + viewId).classList.remove('hidden');
if(viewId === 'list') lucide.createIcons();
}
function viewReport(isReal) { switchView('detail'); }
// Tab 切换
function switchTab(tabId) {
document.getElementById('content-compliance').classList.add('hidden');
document.getElementById('content-methodology').classList.add('hidden');
document.getElementById('tab-compliance').className = "px-6 py-2 rounded-md text-sm font-medium text-slate-500 hover:text-slate-700 transition-all";
document.getElementById('tab-methodology').className = "px-6 py-2 rounded-md text-sm font-medium text-slate-500 hover:text-slate-700 transition-all";
document.getElementById('content-' + tabId).classList.remove('hidden');
document.getElementById('tab-' + tabId).className = "px-6 py-2 rounded-md text-sm font-bold bg-white text-indigo-600 shadow-sm transition-all";
}
// 筛选逻辑 (Visual Only)
function activateFilter(chip) {
Array.from(chip.parentElement.children).forEach(c => c.classList.remove('active', 'bg-eff6ff', 'text-2563eb', 'border-bfdbfe', 'font-600'));
chip.classList.add('active');
}
// 弹窗逻辑
function openAgentModal() { document.getElementById('modal-agent').classList.remove('hidden'); }
function closeModal() { document.getElementById('modal-agent').classList.add('hidden'); }
function openSettings() { document.getElementById('modal-settings').classList.remove('hidden'); }
function closeSettings() { document.getElementById('modal-settings').classList.add('hidden'); }
// 用户菜单逻辑
function toggleUserMenu() { document.getElementById('user-menu').classList.toggle('hidden'); }
function openChangePassword() {
toggleUserMenu();
document.getElementById('modal-password').classList.remove('hidden');
}
function closeChangePassword() { document.getElementById('modal-password').classList.add('hidden'); }
// 点击外部关闭菜单
document.addEventListener('click', function(e) {
const menu = document.getElementById('user-menu');
const avatar = document.querySelector('[onclick="toggleUserMenu()"]');
if (!menu.classList.contains('hidden') && !menu.contains(e.target) && !avatar.contains(e.target)) {
menu.classList.add('hidden');
}
});
// 批量选择
function toggleRowSelection(checkbox) { checkbox.checked ? checkbox.closest('tr').classList.add('selected') : checkbox.closest('tr').classList.remove('selected'); updateBatchToolbar(); }
function toggleSelectAll(mainCheckbox) { document.querySelectorAll('.row-checkbox').forEach(cb => { cb.checked = mainCheckbox.checked; toggleRowSelection(cb); }); }
function updateBatchToolbar() {
const count = document.querySelectorAll('.row-checkbox:checked').length;
const toolbar = document.getElementById('batch-toolbar');
document.getElementById('selected-count').innerText = count;
count > 0 ? toolbar.classList.remove('hidden') : toolbar.classList.add('hidden');
}
function clearSelection() { document.querySelectorAll('.row-checkbox').forEach(cb => cb.checked = false); document.querySelectorAll('tr').forEach(tr => tr.classList.remove('selected')); document.querySelector('thead input').checked = false; updateBatchToolbar(); }
function selectRowAndOpenModal(btn) { clearSelection(); const cb = btn.closest('tr').querySelector('.row-checkbox'); cb.checked = true; toggleRowSelection(cb); openAgentModal(); }
// 模拟运行
function runBatchTask() {
closeModal();
const btn = document.querySelector('.status-pending button');
if(btn) {
btn.innerHTML = `<i data-lucide="loader-2" class="w-3 h-3 animate-spin"></i> 运行中`;
btn.className = "text-indigo-600 font-bold px-3 py-1.5 text-xs flex items-center gap-1";
}
clearSelection();
alert("任务已提交!");
}
function handleFileUpload(input) {
if(input.files.length) alert(`已选择 ${input.files.length} 个文件`);
}
</script>
</body>
</html>