# ASL模块 - Week 2 Day 2 完成报告 **日期**: 2025-11-19 **任务**: 文献导入页 + Excel模板下载 **状态**: ✅ 100% 完成 --- ## 📋 今日目标回顾 根据Week 2开发计划,Day 2的主要目标是: 1. ✅ Excel模板生成与下载 2. ✅ Excel上传与内存解析 3. ✅ 字段验证与去重 4. ✅ 文献预览表格 5. ✅ 完整提交流程(创建项目+导入文献) --- ## 🎯 核心成果 ### 1. Excel工具函数模块 ⭐⭐⭐⭐⭐ **文件**: `frontend-v2/src/modules/asl/utils/excelUtils.ts` **包含功能**: - ✅ `downloadExcelTemplate()` - 生成并下载Excel模板 - ✅ `parseExcelFile()` - 内存解析Excel文件 - ✅ `validateLiterature()` - 验证单条文献 - ✅ `validateLiteratures()` - 批量验证文献 - ✅ `deduplicateLiteratures()` - 去重逻辑(DOI + Title) - ✅ `processExcelFile()` - 完整处理流程 **技术亮点**: ```typescript // 内存解析,不落盘(云原生要求) const buffer = await data.toBuffer(); const workbook = XLSX.read(buffer, { type: 'array' }); // 智能去重(优先DOI,其次Title) if (lit.doi && lit.doi.trim() !== '') { key = `doi:${lit.doi.toLowerCase().trim()}`; } else { key = `title:${lit.title.toLowerCase().replace(/\s+/g, '')}`; } ``` --- ### 2. 完善的"设置与启动"页面 ⭐⭐⭐⭐⭐ **文件**: `frontend-v2/src/modules/asl/pages/TitleScreeningSettings.tsx` **完整功能流程**: ``` 用户填写PICOS标准 ↓ 上传Excel文件 ↓ 前端内存解析 + 验证 + 去重 ↓ 显示预览表格 + 统计信息 ↓ 点击"开始AI初筛" ↓ 创建项目 → 导入文献 → 跳转工作台 ``` **UI组件**: - ✅ Excel Dragger上传组件 - ✅ Excel模板下载按钮 - ✅ 解析统计信息卡片(4个Statistic组件) - ✅ 文献预览表格(分页、Tooltip、省略) - ✅ 错误信息Alert - ✅ 启动按钮(带loading状态) **状态管理**: ```typescript const [fileList, setFileList] = useState([]); const [literatures, setLiteratures] = useState([]); const [parseStats, setParseStats] = useState(null); const [isUploading, setIsUploading] = useState(false); const [canStart, setCanStart] = useState(false); const [isSubmitting, setIsSubmitting] = useState(false); ``` --- ### 3. API接口优化 ⭐⭐⭐ **文件**: `frontend-v2/src/modules/asl/api/index.ts` **修改内容**: - ✅ 修改`importLiteratures`签名,接受`{projectId, literatures}`对象 - ✅ 导出统一的`aslApi`对象,便于组件引用 **使用示例**: ```typescript import { aslApi } from '../api'; // 创建项目 const response = await aslApi.createProject({...}); // 导入文献 await aslApi.importLiteratures({ projectId, literatures: [...], }); ``` --- ## 🔧 技术实现细节 ### 1. Excel模板生成 **包含两个工作表**: 1. **文献列表**: - 3行示例数据 - 7列(Title, Abstract, PMID, Authors, Journal, Year, DOI) - 自动设置列宽 2. **字段说明**: - 每个字段的说明 - 必填/可选标记 - 使用建议 **代码片段**: ```typescript const wb = XLSX.utils.book_new(); const ws = XLSX.utils.json_to_sheet(templateData); ws['!cols'] = [ { wch: 60 }, // Title { wch: 80 }, // Abstract // ... ]; XLSX.utils.book_append_sheet(wb, ws, '文献列表'); XLSX.writeFile(wb, '文献导入模板.xlsx'); ``` --- ### 2. 内存解析(云原生) **遵循云原生开发规范**: - ✅ 使用`FileReader.readAsArrayBuffer()`读取文件 - ✅ 使用`XLSX.read(buffer, { type: 'array' })`内存解析 - ✅ **不落盘**,直接在内存中处理 **字段映射(支持中英文)**: ```typescript title: row.Title || row.title || row['标题'] || '' abstract: row.Abstract || row.abstract || row['摘要'] || '' pmid: row.PMID || row.pmid || row['PMID编号'] || '' // ... ``` --- ### 3. 数据验证 **验证规则**: - `title`: 必填,至少10个字符 - `abstract`: 必填,至少50个字符 - 其他字段: 可选 **错误提示**: ```typescript if (!lit.title || lit.title.length < 10) { errors.push('标题太短(至少10个字符)'); } ``` --- ### 4. 智能去重 **去重策略**: 1. **优先级1**: DOI(如果存在) - 标准化:转小写、去空格 2. **优先级2**: Title - 标准化:转小写、去除所有空白字符 **代码逻辑**: ```typescript const seen = new Map(); for (const lit of literatures) { let key: string; if (lit.doi && lit.doi.trim() !== '') { key = `doi:${lit.doi.toLowerCase().trim()}`; } else { key = `title:${lit.title.toLowerCase().replace(/\s+/g, '')}`; } if (!seen.has(key)) { seen.set(key, lit); unique.push(lit); } else { duplicates.push(lit); } } ``` --- ### 5. 文献预览表格 **功能特性**: - ✅ 分页显示(50条/页) - ✅ 标题和摘要超长省略(Tooltip显示全文) - ✅ 响应式布局(scroll x) - ✅ 序号自动计算 **列定义**: ```typescript const columns = [ { title: '#', width: 60, render: (_, __, index) => index + 1 }, { title: '标题', width: '35%', ellipsis: true }, { title: '摘要', width: '30%', ellipsis: true, render: truncate }, { title: 'PMID', width: 100 }, { title: '年份', width: 80 }, { title: '作者', ellipsis: true }, ]; ``` --- ### 6. 统计信息展示 **4个统计指标**: ```tsx } /> ``` --- ## 📊 完整交互流程 ``` [用户进入页面] ↓ [填写PICOS表单] ← 必填(P, I, C, S, 纳入, 排除) ↓ [选择筛选风格] ← Radio(lenient/standard/strict) ↓ [点击"下载Excel模板"] ← 可选 ↓ 下载包含示例的Excel模板 ↓ [上传Excel文件] ← Dragger组件 ↓ [前端自动解析] ← xlsx.read() ↓ ├─ 字段映射(中英文兼容) ├─ 数据验证(title + abstract必填) └─ 去重逻辑(DOI → Title) ↓ [显示统计信息] ← 4个Statistic卡片 ├─ 总数: 100篇 ├─ 有效: 95篇(绿色) ├─ 重复: 3篇(橙色) └─ 无效: 2篇(红色) ↓ [显示文献预览表格] ← Table + Pagination ↓ [用户确认无误] ↓ [点击"开始AI初筛"] ← Button(disabled如果未完成) ↓ [Loading: "正在创建项目..."] ↓ [API: createProject()] ← 获得projectId ↓ [Loading: "正在导入文献..."] ↓ [API: importLiteratures({ projectId, literatures })] ↓ [Success: "项目创建成功!"] ↓ [自动跳转] → /literature/screening/title/workbench ``` --- ## 🎨 UI/UX亮点 ### 1. 友好的错误提示 **分层提示**: - ✅ 文件解析错误 → 红色Message - ✅ 数据验证失败 → 橙色Alert(显示前5条错误) - ✅ 重复数据 → 蓝色Info Message - ✅ 无效数据 → 橙色Warning Message **示例**: ```typescript if (statistics.invalid > 0) { message.warning(`有 ${statistics.invalid} 条数据验证失败,已自动过滤`, 3); } if (statistics.duplicates > 0) { message.info(`检测到 ${statistics.duplicates} 条重复数据,已自动去重`, 3); } ``` --- ### 2. 优雅的Loading状态 **三种Loading**: 1. **解析中**: `message.loading('正在解析Excel文件...')` 2. **创建项目**: `message.loading('正在创建项目...')` 3. **导入文献**: `message.loading('正在导入文献...')` **Button状态**: ```tsx ``` --- ### 3. 渐进式启用 **启动按钮激活条件**: ```typescript setCanStart(formValid && valid.length > 0); ``` - ❌ 表单未填写 → 按钮禁用 - ❌ 文献未导入 → 按钮禁用 - ✅ 表单+文献都完成 → 按钮启用 **提示信息**: ```tsx {!canStart && literatures.length === 0 && ( )} ``` --- ## 📦 新增/修改的文件 ### 新增文件 ✅ 1. **`frontend-v2/src/modules/asl/utils/excelUtils.ts`** - 366行代码 - 完整的Excel处理工具库 ### 修改文件 ✅ 1. **`frontend-v2/src/modules/asl/pages/TitleScreeningSettings.tsx`** - 从占位页面 → 完整功能页面 - 新增597行代码 2. **`frontend-v2/src/modules/asl/api/index.ts`** - 修改`importLiteratures`函数签名 - 新增`aslApi`统一导出对象 ### 依赖安装 ✅ ```bash npm install xlsx # 新增依赖:xlsx@^0.18.5 ``` --- ## ✅ 完成标准验证 ### 功能完整性 ✅ - [x] Excel模板下载功能 - [x] Excel上传与解析(内存,不落盘) - [x] 字段验证(title + abstract必填) - [x] 去重逻辑(DOI + Title) - [x] 文献预览表格 - [x] 统计信息展示 - [x] "开始AI初筛"按钮可用 - [x] 一次性创建项目+导入文献 ### 代码质量 ✅ - [x] 无TypeScript类型错误 - [x] 无ESLint警告 - [x] 符合React最佳实践 - [x] 完整的错误处理 - [x] 友好的用户提示 ### 云原生要求 ✅ - [x] 内存解析Excel(不落盘) - [x] 使用环境变量配置 - [x] 无同步阻塞操作 - [x] 完整的异步处理 --- ## 🧪 测试建议 ### 测试场景 1. **正常流程**: - 下载模板 → 填写数据 → 上传 → 预览 → 启动 2. **异常场景**: - 上传空文件 - 上传非Excel文件 - 必填字段缺失 - 数据格式错误 - 重复数据处理 3. **边界场景**: - 1篇文献 - 500+篇文献 - 中文列名 - 英文列名 - 混合列名 --- ## 📝 使用说明 ### 1. 下载模板 ``` 点击"下载Excel模板"按钮 → 自动下载"文献导入模板.xlsx" → 包含2个工作表: ├─ 文献列表(带示例) └─ 字段说明 ``` ### 2. 填写数据 **必填字段**: - `Title`: 文献标题(至少10字符) - `Abstract`: 文献摘要(至少50字符) **可选字段**: - `PMID`: PubMed ID - `Authors`: 作者列表 - `Journal`: 期刊名称 - `Year`: 发表年份 - `DOI`: DOI编号(用于去重) ### 3. 上传解析 ``` 点击或拖拽Excel文件到上传区域 → 自动解析(2-5秒) → 显示统计信息和预览表格 → 如有错误,显示详细提示 ``` ### 4. 启动筛选 ``` 确认数据无误后 → 点击"开始AI标题摘要初筛" → 自动创建项目 → 导入所有文献 → 跳转到审核工作台 ``` --- ## 🚀 下一步计划 ### Week 2 Day 3-4(明天开始) **主要任务**: 审核工作台(双行表格) **预计实现**: 1. 双行表格UI(主行 + 展开行) 2. 两个模型的判断结果对比 3. 冲突高亮显示 4. PICO判断详情 5. 双视图原文审查Modal 6. 人工复核功能 **参考原型**: `docs/03-业务模块/ASL-AI智能文献/03-UI设计/AI智能文献-标题摘要初筛原型.html` --- ## 💡 经验总结 ### 技术亮点 ⭐ 1. **内存解析**:完全符合云原生要求,无文件落盘 2. **智能去重**:DOI优先级 + Title兜底,实用性强 3. **渐进式交互**:表单验证 + 文献导入 → 启用按钮 4. **完整错误处理**:分层提示,用户体验好 ### 改进空间 1. **大文件优化**:目前未限制文件大小,可考虑添加 2. **解析进度条**:对于超大文件,可显示解析进度 3. **Excel格式检查**:可提前检查列名是否匹配 4. **批量操作**:表格可支持批量删除无效行 --- ## 📊 开发统计 | 指标 | 数值 | |------|------| | **新增代码** | ~1,000行 | | **新增文件** | 1个 | | **修改文件** | 2个 | | **新增依赖** | 1个(xlsx) | | **功能点** | 6个 | | **开发时间** | 约2小时 | | **完成度** | 100% ✅ | --- ## 🎉 Day 2 完成总结 ✅ **Excel模板生成与下载** - 完美实现 ✅ **Excel上传与解析** - 内存处理,云原生 ✅ **数据验证与去重** - 智能去重,完整验证 ✅ **文献预览表格** - 友好展示,分页支持 ✅ **完整提交流程** - 一键启动,自动跳转 **Day 2任务 100% 完成!** 🎊 **明天继续Week 2 Day 3-4开发!** 💪 --- **完成时间**: 2025-11-19 **下一个工作日**: Week 2 Day 3