Files
AIclinicalresearch/docs/03-业务模块/ASL-AI智能文献/05-开发记录/2025-11-19-Week2-Day2完成报告.md
HaHafeng 88cc049fb3 feat(asl): Complete Day 5 - Fulltext Screening Backend API Development
- Implement 5 core API endpoints (create task, get progress, get results, update decision, export Excel)
- Add FulltextScreeningController with Zod validation (652 lines)
- Implement ExcelExporter service with 4-sheet report generation (352 lines)
- Register routes under /api/v1/asl/fulltext-screening
- Create 31 REST Client test cases
- Add automated integration test script
- Fix PDF extraction fallback mechanism in LLM12FieldsService
- Update API design documentation to v3.0
- Update development plan to v1.2
- Create Day 5 development record
- Clean up temporary test files
2025-11-23 10:52:07 +08:00

12 KiB
Raw Blame History

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() - 完整处理流程

技术亮点:

// 内存解析,不落盘(云原生要求)
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状态

状态管理:

const [fileList, setFileList] = useState<UploadFile[]>([]);
const [literatures, setLiteratures] = useState<LiteratureData[]>([]);
const [parseStats, setParseStats] = useState<ParseStatistics | null>(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对象,便于组件引用

使用示例:

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. 字段说明:

    • 每个字段的说明
    • 必填/可选标记
    • 使用建议

代码片段:

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' })内存解析
  • 不落盘,直接在内存中处理

字段映射(支持中英文):

title: row.Title || row.title || row['标题'] || ''
abstract: row.Abstract || row.abstract || row['摘要'] || ''
pmid: row.PMID || row.pmid || row['PMID编号'] || ''
// ...

3. 数据验证

验证规则:

  • title: 必填至少10个字符
  • abstract: 必填至少50个字符
  • 其他字段: 可选

错误提示:

if (!lit.title || lit.title.length < 10) {
  errors.push('标题太短至少10个字符');
}

4. 智能去重

去重策略:

  1. 优先级1: DOI如果存在
    • 标准化:转小写、去空格
  2. 优先级2: Title
    • 标准化:转小写、去除所有空白字符

代码逻辑:

const seen = new Map<string, LiteratureData>();

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
  • 序号自动计算

列定义:

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个统计指标:

<Row gutter={16}>
  <Col span={6}>
    <Statistic title="总数" value={total} prefix={<CheckCircle />} />
  </Col>
  <Col span={6}>
    <Statistic title="有效" value={afterDedup} valueStyle={{ color: '#3f8600' }} />
  </Col>
  <Col span={6}>
    <Statistic title="重复" value={duplicates} valueStyle={{ color: '#faad14' }} />
  </Col>
  <Col span={6}>
    <Statistic title="无效" value={invalid} valueStyle={{ color: '#cf1322' }} />
  </Col>
</Row>

📊 完整交互流程

[用户进入页面]
  ↓
[填写PICOS表单] ← 必填P, I, C, S, 纳入, 排除)
  ↓
[选择筛选风格] ← Radiolenient/standard/strict
  ↓
[点击"下载Excel模板"] ← 可选
  ↓ 下载包含示例的Excel模板
  ↓
[上传Excel文件] ← Dragger组件
  ↓
[前端自动解析] ← xlsx.read()
  ↓ 
  ├─ 字段映射(中英文兼容)
  ├─ 数据验证title + abstract必填
  └─ 去重逻辑DOI → Title
  ↓
[显示统计信息] ← 4个Statistic卡片
  ├─ 总数: 100篇
  ├─ 有效: 95篇绿色
  ├─ 重复: 3篇橙色
  └─ 无效: 2篇红色
  ↓
[显示文献预览表格] ← Table + Pagination
  ↓
[用户确认无误]
  ↓
[点击"开始AI初筛"] ← Buttondisabled如果未完成
  ↓
[Loading: "正在创建项目..."]
  ↓
[API: createProject()] ← 获得projectId
  ↓
[Loading: "正在导入文献..."]
  ↓
[API: importLiteratures({ projectId, literatures })]
  ↓
[Success: "项目创建成功!"]
  ↓
[自动跳转] → /literature/screening/title/workbench

🎨 UI/UX亮点

1. 友好的错误提示

分层提示:

  • 文件解析错误 → 红色Message
  • 数据验证失败 → 橙色Alert显示前5条错误
  • 重复数据 → 蓝色Info Message
  • 无效数据 → 橙色Warning Message

示例:

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状态:

<Button
  type="primary"
  size="large"
  loading={isSubmitting}
  disabled={!canStart}
>
  {isSubmitting ? '正在创建项目并导入文献...' : '开始AI标题摘要初筛'}
</Button>

3. 渐进式启用

启动按钮激活条件:

setCanStart(formValid && valid.length > 0);
  • 表单未填写 → 按钮禁用
  • 文献未导入 → 按钮禁用
  • 表单+文献都完成 → 按钮启用

提示信息:

{!canStart && literatures.length === 0 && (
  <Alert
    message="请先完成以上步骤"
    description="填写PICOS标准、纳入/排除标准,并导入文献后,即可开始筛选"
    type="warning"
  />
)}

📦 新增/修改的文件

新增文件

  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统一导出对象

依赖安装

npm install xlsx
# 新增依赖xlsx@^0.18.5

完成标准验证

功能完整性

  • Excel模板下载功能
  • Excel上传与解析内存不落盘
  • 字段验证title + abstract必填
  • 去重逻辑DOI + Title
  • 文献预览表格
  • 统计信息展示
  • "开始AI初筛"按钮可用
  • 一次性创建项目+导入文献

代码质量

  • 无TypeScript类型错误
  • 无ESLint警告
  • 符合React最佳实践
  • 完整的错误处理
  • 友好的用户提示

云原生要求

  • 内存解析Excel不落盘
  • 使用环境变量配置
  • 无同步阻塞操作
  • 完整的异步处理

🧪 测试建议

测试场景

  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