Summary: - Implement DC module Portal page with 3 tool cards - Create ToolCard component with decorative background and hover animations - Implement TaskList component with table layout and progress bars - Implement AssetLibrary component with tab switching and file cards - Complete database verification (4 tables confirmed) - Complete backend API verification (6 endpoints ready) - Optimize UI to match prototype design (V2.html) Frontend Components (~715 lines): - components/ToolCard.tsx - Tool cards with animations - components/TaskList.tsx - Recent tasks table view - components/AssetLibrary.tsx - Data asset library with tabs - hooks/useRecentTasks.ts - Task state management - hooks/useAssets.ts - Asset state management - pages/Portal.tsx - Main portal page - types/portal.ts - TypeScript type definitions Backend Verification: - Backend API: 1495 lines code verified - Database: dc_schema with 4 tables verified - API endpoints: 6 endpoints tested (templates API works) Documentation: - Database verification report - Backend API test report - Phase 1 completion summary - UI optimization report - Development task checklist - Development plan for Tool B Status: Phase 1 completed (100%), ready for browser testing Next: Phase 2 - Tool B Step 1 and 2 development
213 lines
17 KiB
HTML
213 lines
17 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="zh-CN">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>智能数据清洗工作台 V2 - 数据资产库升级版</title>
|
|
<!-- 引入 Tailwind CSS (CDN) -->
|
|
<script src="https://cdn.tailwindcss.com"></script>
|
|
<!-- 引入 Lucide Icons (CDN) -->
|
|
<script src="https://unpkg.com/lucide@latest"></script>
|
|
<!-- 引入 Alpine.js 用于简单的交互逻辑 (Tab切换) -->
|
|
<script src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js"></script>
|
|
<style>
|
|
.fade-in { animation: fadeIn 0.3s ease-in-out; }
|
|
@keyframes fadeIn { from { opacity: 0; transform: translateY(5px); } to { opacity: 1; transform: translateY(0); } }
|
|
</style>
|
|
</head>
|
|
<body class="min-h-screen bg-slate-50 font-sans text-slate-800">
|
|
|
|
<!-- 1. 顶部一级导航 -->
|
|
<header class="bg-white border-b border-slate-200 sticky top-0 z-50">
|
|
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
|
<div class="flex justify-between h-16">
|
|
<div class="flex items-center">
|
|
<div class="flex-shrink-0 flex items-center gap-2">
|
|
<div class="w-8 h-8 bg-blue-600 rounded-lg flex items-center justify-center">
|
|
<i data-lucide="database" class="text-white w-5 h-5"></i>
|
|
</div>
|
|
<span class="font-bold text-xl text-slate-900">MedData AI</span>
|
|
</div>
|
|
<nav class="hidden md:ml-10 md:flex md:space-x-8">
|
|
<a href="#" class="text-slate-500 hover:text-slate-900 px-1 pt-1 border-b-2 border-transparent text-sm font-medium">AI问答</a>
|
|
<a href="#" class="text-slate-500 hover:text-slate-900 px-1 pt-1 border-b-2 border-transparent text-sm font-medium">智能数据分析</a>
|
|
<a href="#" class="text-slate-500 hover:text-slate-900 px-1 pt-1 border-b-2 border-transparent text-sm font-medium">知识库</a>
|
|
<a href="#" class="border-blue-500 text-slate-900 px-1 pt-1 border-b-2 text-sm font-medium">智能数据清洗</a>
|
|
</nav>
|
|
</div>
|
|
<div class="flex items-center gap-4">
|
|
<div class="text-sm text-slate-500">张医生 (主治医师)</div>
|
|
<div class="w-8 h-8 bg-slate-200 rounded-full flex items-center justify-center text-slate-500 text-sm font-bold">ZH</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</header>
|
|
|
|
<!-- 2. 主内容区 -->
|
|
<main class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8 fade-in">
|
|
|
|
<div class="mb-8">
|
|
<h1 class="text-2xl font-bold text-slate-900">数据清洗工作台</h1>
|
|
<p class="text-slate-500 mt-1">从原始 Excel 到科研级数据集,只需三步。</p>
|
|
</div>
|
|
|
|
<!-- 3. 功能启动区 -->
|
|
<div class="grid grid-cols-1 md:grid-cols-3 gap-6 mb-10">
|
|
<!-- 卡片 A -->
|
|
<div class="bg-white rounded-xl shadow-sm border border-slate-200 p-6 hover:shadow-md transition-shadow cursor-pointer group relative overflow-hidden">
|
|
<div class="absolute top-0 right-0 w-24 h-24 bg-blue-50 rounded-bl-full -mr-4 -mt-4 transition-transform group-hover:scale-110"></div>
|
|
<div class="relative">
|
|
<div class="w-12 h-12 bg-blue-100 rounded-lg flex items-center justify-center mb-4 text-blue-600"><i data-lucide="file-spreadsheet" class="w-7 h-7"></i></div>
|
|
<h3 class="text-lg font-bold text-slate-900 mb-2 group-hover:text-blue-600 transition-colors">超级合并器</h3>
|
|
<p class="text-sm text-slate-500 mb-4 h-10">解决多源数据时间轴对齐难题。支持 HIS 导出数据按病人 ID 自动合并。</p>
|
|
<div class="flex items-center text-sm font-medium text-blue-600">开始合并 <i data-lucide="arrow-right" class="w-4 h-4 ml-1 group-hover:translate-x-1 transition-transform"></i></div>
|
|
</div>
|
|
</div>
|
|
<!-- 卡片 B -->
|
|
<div class="bg-white rounded-xl shadow-sm border border-slate-200 p-6 hover:shadow-md transition-shadow cursor-pointer group relative overflow-hidden">
|
|
<div class="absolute top-0 right-0 w-24 h-24 bg-purple-50 rounded-bl-full -mr-4 -mt-4 transition-transform group-hover:scale-110"></div>
|
|
<div class="relative">
|
|
<div class="w-12 h-12 bg-purple-100 rounded-lg flex items-center justify-center mb-4 text-purple-600"><i data-lucide="bot" class="w-7 h-7"></i></div>
|
|
<h3 class="text-lg font-bold text-slate-900 mb-2 group-hover:text-purple-600 transition-colors">病历结构化机器人</h3>
|
|
<p class="text-sm text-slate-500 mb-4 h-10">利用大模型提取非结构化文本。支持自动脱敏、批量处理与抽检。</p>
|
|
<div class="flex items-center text-sm font-medium text-purple-600">新建提取任务 <i data-lucide="arrow-right" class="w-4 h-4 ml-1 group-hover:translate-x-1 transition-transform"></i></div>
|
|
</div>
|
|
</div>
|
|
<!-- 卡片 C -->
|
|
<div class="bg-white rounded-xl shadow-sm border border-slate-200 p-6 hover:shadow-md transition-shadow cursor-pointer group relative overflow-hidden">
|
|
<div class="absolute top-0 right-0 w-24 h-24 bg-emerald-50 rounded-bl-full -mr-4 -mt-4 transition-transform group-hover:scale-110"></div>
|
|
<div class="relative">
|
|
<div class="w-12 h-12 bg-emerald-100 rounded-lg flex items-center justify-center mb-4 text-emerald-600"><i data-lucide="table-2" class="w-7 h-7"></i></div>
|
|
<h3 class="text-lg font-bold text-slate-900 mb-2 group-hover:text-emerald-600 transition-colors">科研数据编辑器</h3>
|
|
<p class="text-sm text-slate-500 mb-4 h-10">Excel 风格的在线清洗工具。支持缺失值填补、值替换与分析集导出。</p>
|
|
<div class="flex items-center text-sm font-medium text-emerald-600">打开编辑器 <i data-lucide="arrow-right" class="w-4 h-4 ml-1 group-hover:translate-x-1 transition-transform"></i></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 4. 任务与资产中心 -->
|
|
<div class="grid grid-cols-1 lg:grid-cols-3 gap-8">
|
|
|
|
<!-- 左侧:最近任务 (不变) -->
|
|
<div class="lg:col-span-2">
|
|
<div class="flex items-center justify-between mb-4">
|
|
<h2 class="text-lg font-bold text-slate-900 flex items-center gap-2"><i data-lucide="history" class="w-5 h-5 text-slate-500"></i> 最近处理任务</h2>
|
|
<button class="text-sm text-blue-600 hover:underline">查看全部</button>
|
|
</div>
|
|
<div class="bg-white rounded-xl shadow-sm border border-slate-200 overflow-hidden min-h-[400px]">
|
|
<table class="min-w-full divide-y divide-slate-200">
|
|
<thead class="bg-slate-50">
|
|
<tr>
|
|
<th class="px-6 py-3 text-left text-xs font-medium text-slate-500 uppercase tracking-wider">任务名称</th>
|
|
<th class="px-6 py-3 text-left text-xs font-medium text-slate-500 uppercase tracking-wider">工具</th>
|
|
<th class="px-6 py-3 text-left text-xs font-medium text-slate-500 uppercase tracking-wider">状态</th>
|
|
<th class="px-6 py-3 text-right text-xs font-medium text-slate-500 uppercase tracking-wider">操作</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody class="bg-white divide-y divide-slate-200">
|
|
<tr class="hover:bg-slate-50 transition-colors">
|
|
<td class="px-6 py-4 whitespace-nowrap"><div class="flex flex-col"><span class="text-sm font-medium text-slate-900">肺癌门诊数据_2023合并任务</span><span class="text-xs text-slate-500">10分钟前</span></div></td>
|
|
<td class="px-6 py-4 whitespace-nowrap"><span class="inline-flex items-center gap-1.5 px-2.5 py-0.5 rounded-full text-xs font-medium bg-blue-100 text-blue-700"><i data-lucide="database" class="w-3 h-3"></i> 超级合并器</span></td>
|
|
<td class="px-6 py-4 whitespace-nowrap"><span class="inline-flex items-center text-xs text-emerald-600 font-medium"><i data-lucide="check-circle-2" class="w-4 h-4 mr-1.5"></i> 完成 (12,450 行)</span></td>
|
|
<td class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium"><div class="flex justify-end gap-3"><button class="text-slate-500 hover:text-slate-900"><i data-lucide="download" class="w-4 h-4"></i></button><button class="text-purple-600 hover:text-purple-800 flex items-center gap-1">去 AI 提取 <i data-lucide="arrow-right" class="w-4 h-4"></i></button></div></td>
|
|
</tr>
|
|
<tr class="hover:bg-slate-50 transition-colors">
|
|
<td class="px-6 py-4 whitespace-nowrap"><div class="flex flex-col"><span class="text-sm font-medium text-slate-900">Q3出院小结_批量提取</span><span class="text-xs text-slate-500">正在运行</span></div></td>
|
|
<td class="px-6 py-4 whitespace-nowrap"><span class="inline-flex items-center gap-1.5 px-2.5 py-0.5 rounded-full text-xs font-medium bg-purple-100 text-purple-700"><i data-lucide="bot" class="w-3 h-3"></i> AI 结构化</span></td>
|
|
<td class="px-6 py-4 whitespace-nowrap"><div class="w-32"><div class="flex justify-between text-xs mb-1"><span class="text-blue-600 font-medium">处理中</span><span class="text-slate-500">45%</span></div><div class="w-full bg-slate-200 rounded-full h-1.5"><div class="bg-blue-600 h-1.5 rounded-full" style="width: 45%"></div></div></div></td>
|
|
<td class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium"><span class="text-slate-400 text-xs">等待完成...</span></td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 右侧:数据资产库 (V2 核心修改) -->
|
|
<div class="lg:col-span-1 flex flex-col h-full" x-data="{ activeTab: 'all' }">
|
|
<div class="flex items-center justify-between mb-4">
|
|
<h2 class="text-lg font-bold text-slate-900 flex items-center gap-2">
|
|
<i data-lucide="database" class="w-5 h-5 text-slate-500"></i> 数据资产库
|
|
</h2>
|
|
<div class="flex gap-1">
|
|
<button class="p-1 hover:bg-slate-100 rounded-full"><i data-lucide="search" class="w-4 h-4 text-slate-400"></i></button>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="bg-white rounded-xl shadow-sm border border-slate-200 flex flex-col flex-1 min-h-[400px]">
|
|
<!-- Tabs -->
|
|
<div class="flex border-b border-slate-200">
|
|
<button @click="activeTab = 'all'" :class="{ 'border-blue-500 text-blue-600': activeTab === 'all', 'border-transparent text-slate-500 hover:text-slate-700': activeTab !== 'all' }" class="flex-1 py-3 text-xs font-medium text-center border-b-2 transition-colors">全部</button>
|
|
<button @click="activeTab = 'output'" :class="{ 'border-emerald-500 text-emerald-600': activeTab === 'output', 'border-transparent text-slate-500 hover:text-slate-700': activeTab !== 'output' }" class="flex-1 py-3 text-xs font-medium text-center border-b-2 transition-colors">处理结果</button>
|
|
<button @click="activeTab = 'input'" :class="{ 'border-slate-400 text-slate-600': activeTab === 'input', 'border-transparent text-slate-500 hover:text-slate-700': activeTab !== 'input' }" class="flex-1 py-3 text-xs font-medium text-center border-b-2 transition-colors">原始上传</button>
|
|
</div>
|
|
|
|
<!-- 列表内容 -->
|
|
<div class="p-4 space-y-3 flex-1 overflow-y-auto">
|
|
|
|
<!-- 结果文件 1 -->
|
|
<div x-show="activeTab === 'all' || activeTab === 'output'" class="group p-3 rounded-lg border border-slate-100 hover:border-blue-200 hover:bg-blue-50 transition-all cursor-pointer">
|
|
<div class="flex justify-between items-start mb-2">
|
|
<div class="flex items-center gap-2">
|
|
<i data-lucide="file-spreadsheet" class="w-4 h-4 text-emerald-600"></i>
|
|
<h4 class="text-sm font-bold text-slate-800 group-hover:text-blue-700 truncate max-w-[150px]">2024_肺癌分析最终版.csv</h4>
|
|
</div>
|
|
<button class="text-slate-400 hover:text-slate-600"><i data-lucide="more-horizontal" class="w-4 h-4"></i></button>
|
|
</div>
|
|
<div class="flex items-center gap-2 mb-3">
|
|
<span class="px-1.5 py-0.5 bg-emerald-50 text-emerald-600 border border-emerald-100 text-[10px] rounded">已清洗</span>
|
|
<span class="px-1.5 py-0.5 bg-emerald-50 text-emerald-600 border border-emerald-100 text-[10px] rounded">已脱敏</span>
|
|
</div>
|
|
<div class="flex items-center justify-between text-xs text-slate-500"><span>12,405 行</span><span>2023-10-24</span></div>
|
|
</div>
|
|
|
|
<!-- 原始文件 2 -->
|
|
<div x-show="activeTab === 'all' || activeTab === 'input'" class="group p-3 rounded-lg border border-slate-100 hover:border-blue-200 hover:bg-blue-50 transition-all cursor-pointer">
|
|
<div class="flex justify-between items-start mb-2">
|
|
<div class="flex items-center gap-2">
|
|
<i data-lucide="file-input" class="w-4 h-4 text-slate-400"></i>
|
|
<h4 class="text-sm font-bold text-slate-800 group-hover:text-blue-700 truncate max-w-[150px]">心血管回顾性研究_raw.xlsx</h4>
|
|
</div>
|
|
<button class="text-slate-400 hover:text-slate-600"><i data-lucide="more-horizontal" class="w-4 h-4"></i></button>
|
|
</div>
|
|
<div class="flex items-center gap-2 mb-3">
|
|
<span class="px-1.5 py-0.5 bg-slate-100 text-slate-500 border border-slate-200 text-[10px] rounded">原始底表</span>
|
|
<span class="px-1.5 py-0.5 bg-slate-100 text-slate-500 border border-slate-200 text-[10px] rounded">未处理</span>
|
|
</div>
|
|
<div class="flex items-center justify-between text-xs text-slate-500"><span>45,200 行</span><span>2023-10-22</span></div>
|
|
</div>
|
|
|
|
<!-- 结果文件 3 -->
|
|
<div x-show="activeTab === 'all' || activeTab === 'output'" class="group p-3 rounded-lg border border-slate-100 hover:border-blue-200 hover:bg-blue-50 transition-all cursor-pointer">
|
|
<div class="flex justify-between items-start mb-2">
|
|
<div class="flex items-center gap-2">
|
|
<i data-lucide="file-spreadsheet" class="w-4 h-4 text-emerald-600"></i>
|
|
<h4 class="text-sm font-bold text-slate-800 group-hover:text-blue-700 truncate max-w-[150px]">药物临床试验组_提取结果.csv</h4>
|
|
</div>
|
|
<button class="text-slate-400 hover:text-slate-600"><i data-lucide="more-horizontal" class="w-4 h-4"></i></button>
|
|
</div>
|
|
<div class="flex items-center gap-2 mb-3">
|
|
<span class="px-1.5 py-0.5 bg-emerald-50 text-emerald-600 border border-emerald-100 text-[10px] rounded">AI提取</span>
|
|
</div>
|
|
<div class="flex items-center justify-between text-xs text-slate-500"><span>800 行</span><span>2023-10-20</span></div>
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<!-- 底部上传 -->
|
|
<div class="p-4 border-t border-slate-100 bg-slate-50 rounded-b-xl">
|
|
<button class="w-full py-2 text-sm text-slate-600 border border-dashed border-slate-300 bg-white rounded-lg hover:border-blue-400 hover:text-blue-600 hover:bg-blue-50 transition-colors flex items-center justify-center gap-2">
|
|
<i data-lucide="upload-cloud" class="w-4 h-4"></i> + 上传原始文件到库
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
</main>
|
|
|
|
<!-- 初始化 Icons -->
|
|
<script>
|
|
lucide.createIcons();
|
|
</script>
|
|
</body>
|
|
</html> |