diff --git a/docs/03-业务模块/ASL-AI智能文献/04-开发计划/05-全文复筛前端开发计划.md b/docs/03-业务模块/ASL-AI智能文献/04-开发计划/05-全文复筛前端开发计划.md new file mode 100644 index 00000000..c12719b2 --- /dev/null +++ b/docs/03-业务模块/ASL-AI智能文献/04-开发计划/05-全文复筛前端开发计划.md @@ -0,0 +1,1233 @@ +# 全文复筛前端开发计划 + +> **文档版本:** v1.0 +> **创建日期:** 2025-11-23 +> **最后更新:** 2025-11-23 +> **预计工期:** 2.5天 +> **开发阶段:** 全文复筛模块 - 前端UI实现 + +--- + +## 📋 目录 + +- [1. 开发目标](#1-开发目标) +- [2. 页面架构](#2-页面架构) +- [3. 详细设计](#3-详细设计) +- [4. 组件清单](#4-组件清单) +- [5. 开发排期](#5-开发排期) +- [6. 技术实现](#6-技术实现) +- [7. 测试计划](#7-测试计划) + +--- + +## 1. 开发目标 + +### 1.1 核心目标 + +实现全文复筛模块的完整前端UI,包括: +- 4个核心页面 +- 支持独立运行和衔接标题摘要初筛两种模式 +- 实时任务进度监控 +- 双模型判断对比 +- 简单PDF全文预览 +- Excel结果导出 + +### 1.2 设计原则 + +1. **灵活性** - 既能独立运行,也能衔接标题摘要初筛 +2. **实时性** - 长时间LLM任务需要实时进度反馈 +3. **可视化** - 冲突检测、PICS符合性清晰展示 +4. **易用性** - 简化操作流程,降低学习成本 +5. **一致性** - 与标题摘要初筛保持UI风格一致 + +--- + +## 2. 页面架构 + +### 2.1 路由设计 + +``` +/asl/fulltext-screening + ├── /settings - 设置与启动页面 + ├── /progress/:taskId - 任务进度监控页面 + ├── /workbench/:taskId - 审核工作台页面 + └── /results/:taskId - 结果展示页面 +``` + +### 2.2 页面流转 + +``` +设置页面 (Settings) + ↓ 点击"开始全文复筛" + ↓ POST /api/v1/asl/fulltext-screening/tasks + ↓ +进度监控页面 (Progress) + ↓ 轮询 GET /tasks/:taskId/progress (每3秒) + ↓ status === 'completed' + ↓ +审核工作台 (Workbench) + ↓ 人工审核冲突和待定文献 + ↓ PUT /results/:resultId/decision + ↓ 点击"完成审核" + ↓ +结果展示页面 (Results) + ↓ GET /tasks/:taskId/results + ↓ GET /tasks/:taskId/export (下载Excel) +``` + +### 2.3 灵活导航 + +用户可以通过左侧导航随时在4个页面之间跳转: +- 进度页面未完成时,工作台显示"部分结果" +- 任何阶段都可以导出当前状态的Excel +- 支持返回设置页面重新开始 + +--- + +## 3. 详细设计 + +### 3.1 设置与启动页面 (Settings) + +#### 3.1.1 页面结构 + +``` +┌─────────────────────────────────────────────┐ +│ 全文复筛 / 设置与启动 │ +├─────────────────────────────────────────────┤ +│ │ +│ 📋 PICOS标准 [调整标准] │ +│ ┌─────────────────────────────────────────┐ │ +│ │ P: 2型糖尿病成人患者 │ │ +│ │ I: SGLT2抑制剂 │ │ +│ │ C: 安慰剂或常规降糖疗法 │ │ +│ │ O: 心血管事件、死亡率 │ │ +│ │ S: 随机对照试验 (RCT) │ │ +│ └─────────────────────────────────────────┘ │ +│ │ +│ ⚙️ 模型配置 │ +│ ┌─────────────────────────────────────────┐ │ +│ │ Model A: [DeepSeek-V3 ▼] │ │ +│ │ Model B: [Qwen-Max ▼] │ │ +│ │ 并发数: [3 ] │ │ +│ └─────────────────────────────────────────┘ │ +│ │ +│ 📚 全文文献管理 (5篇) [📤 上传PDF] │ +│ ┌─────────────────────────────────────────┐ │ +│ │ ☑ 文献A.pdf ✅ 已上传 [查看][删除] │ │ +│ │ ☑ 文献B.pdf ✅ 已上传 [查看][删除] │ │ +│ │ ☑ 文献C.pdf ⏳ 上传中... 45% │ │ +│ │ □ 文献D.pdf ❌ 上传失败 [重试] │ │ +│ └─────────────────────────────────────────┘ │ +│ │ +│ [开始全文复筛] ← 大绿色按钮 │ +└─────────────────────────────────────────────┘ +``` + +#### 3.1.2 功能模块 + +**(1)PICOS标准卡片** +- 显示当前PICOS标准(来自项目或手动编辑) +- "[调整标准]" 按钮 → 打开编辑弹窗 +- 支持临时调整本次筛选标准 + +**(2)模型配置** +- Model A 下拉选择:DeepSeek-V3 / Qwen-Max / GPT-4o / Claude-Sonnet-4 +- Model B 下拉选择:同上 +- 并发数输入:1-10,默认3 + +**(3)文献管理表格** +- 显示已上传的PDF列表 +- 显示上传状态:已上传/上传中/上传失败 +- 操作列:查看、删除、重试 +- "[📤 上传PDF]" 按钮 → 打开上传弹窗 + +**(4)开始复筛按钮** +- 当所有PDF上传成功后,按钮变为可用(绿色) +- 点击后跳转到进度监控页面 + +#### 3.1.3 PICOS编辑弹窗 + +**触发**: 点击 "[调整标准]" 按钮 + +**设计**: +``` +┌─────────────────────────────────────────────┐ +│ 📋 编辑PICOS标准 [×] │ +├─────────────────────────────────────────────┤ +│ │ +│ Population (人群) * │ +│ ┌─────────────────────────────────────────┐ │ +│ │ 2型糖尿病成人患者 │ │ +│ └─────────────────────────────────────────┘ │ +│ │ +│ Intervention (干预) * │ +│ ┌─────────────────────────────────────────┐ │ +│ │ SGLT2抑制剂 │ │ +│ └─────────────────────────────────────────┘ │ +│ │ +│ Comparison (对照) │ +│ ┌─────────────────────────────────────────┐ │ +│ │ 安慰剂或其他常规降糖疗法 │ │ +│ └─────────────────────────────────────────┘ │ +│ │ +│ Outcome (结局) * │ +│ ┌─────────────────────────────────────────┐ │ +│ │ 心血管事件、全因死亡、卒中复发 │ │ +│ └─────────────────────────────────────────┘ │ +│ │ +│ Study Design (研究设计) * │ +│ ┌─────────────────────────────────────────┐ │ +│ │ 随机对照试验 (RCT) │ │ +│ └─────────────────────────────────────────┘ │ +│ │ +│ ⚠️ 注意:修改PICOS标准会影响AI筛选结果 │ +│ │ +│ [取消] [保存修改] │ +└─────────────────────────────────────────────┘ +``` + +**字段说明**: +- 所有字段支持多行文本输入 +- P/I/O/S 为必填项(*标记) +- 保存后自动关闭弹窗,刷新PICOS卡片 + +#### 3.1.4 上传PDF弹窗 + +**触发**: 点击 "[📤 上传PDF]" 按钮 + +**设计**: +``` +┌─────────────────────────────────────────────┐ +│ 📤 上传PDF文件 [×] │ +├─────────────────────────────────────────────┤ +│ │ +│ ┌─────────────────────────────────────────┐ │ +│ │ │ │ +│ │ 📁 拖拽文件到此处 │ │ +│ │ 或点击选择文件 │ │ +│ │ │ │ +│ │ • 支持格式:PDF │ │ +│ │ • 单个文件最大:50MB │ │ +│ │ • 支持批量上传(最多20篇) │ │ +│ │ │ │ +│ └─────────────────────────────────────────┘ │ +│ │ +│ 上传列表: │ +│ ┌─────────────────────────────────────────┐ │ +│ │ ✅ 文献A.pdf (2.3MB) │ │ +│ │ ⏳ 文献B.pdf (5.1MB) - 上传中... 67% │ │ +│ │ ❌ 文献C.pdf (120MB) - 文件过大 │ │ +│ └─────────────────────────────────────────┘ │ +│ │ +│ [取消] [开始上传] │ +└─────────────────────────────────────────────┘ +``` + +**功能说明**: +- 使用 Ant Design `Upload.Dragger` 组件 +- 支持拖拽和点击选择 +- 自动验证文件格式和大小 +- 显示实时上传进度 +- 上传完成后自动关闭弹窗,刷新文献列表 + +--- + +### 3.2 任务进度监控页面 (Progress) + +#### 3.2.1 页面结构 + +``` +┌─────────────────────────────────────────────┐ +│ 全文复筛 / 任务进度 │ +├─────────────────────────────────────────────┤ +│ │ +│ 🤖 AI全文复筛进行中... │ +│ │ +│ ████████████░░░░░░░░ 60% │ +│ │ +│ 📊 实时统计 │ +│ ┌─────────────────────────────────────────┐ │ +│ │ 当前进度:3 / 5 篇 │ │ +│ │ ✅ 成功:2篇 │ │ +│ │ ❌ 失败:1篇 │ │ +│ │ ⚠️ 降级模式:0篇 │ │ +│ │ │ │ +│ │ 💰 Token消耗:45,234 │ │ +│ │ 💵 成本:¥0.1523 │ │ +│ │ │ │ +│ │ ⏱️ 已用时:3分25秒 │ │ +│ │ 📈 预计剩余:2分10秒 │ │ +│ └─────────────────────────────────────────┘ │ +│ │ +│ 📝 处理日志 (自动滚动) │ +│ ┌─────────────────────────────────────────┐ │ +│ │ 10:24:30 ✅ PMID123 处理完成 │ │ +│ │ DeepSeek: ✓ Qwen: ✓ │ │ +│ │ Token: 12,345 成本: ¥0.0412 │ │ +│ │ │ │ +│ │ 10:25:15 ⏳ PMID456 正在处理... │ │ +│ │ DeepSeek: 处理中... │ │ +│ │ │ │ +│ │ 10:26:02 ❌ PMID789 处理失败 │ │ +│ │ 错误: PDF提取失败 │ │ +│ └─────────────────────────────────────────┘ │ +│ │ +│ [取消任务] [查看已完成结果] │ +└─────────────────────────────────────────────┘ +``` + +#### 3.2.2 功能说明 + +**(1)进度条** +- 显示整体进度百分比 +- 使用 Ant Design `Progress` 组件 +- 根据 `processedCount / totalCount` 计算 + +**(2)实时统计卡片** +- 当前进度、成功数、失败数、降级数 +- Token消耗和成本统计 +- 已用时间和预计剩余时间(基于平均处理速度) + +**(3)处理日志** +- 实时显示每篇文献的处理状态 +- 自动滚动到最新日志 +- 显示详细的错误信息 + +**(4)操作按钮** +- "取消任务" - 中断当前任务 +- "查看已完成结果" - 跳转到审核工作台(显示部分结果) + +#### 3.2.3 技术要点 + +**轮询机制**: +```typescript +const { data: task, refetch } = useQuery({ + queryKey: ['fulltextTask', taskId], + queryFn: () => api.getTaskProgress(taskId), + refetchInterval: (data) => { + // 任务进行中:每3秒轮询一次 + // 任务完成或失败:停止轮询 + return data?.status === 'processing' ? 3000 : false; + }, +}); + +// 任务完成后自动跳转 +useEffect(() => { + if (task?.status === 'completed') { + setTimeout(() => { + navigate(`/asl/fulltext-screening/workbench/${taskId}`); + }, 2000); // 延迟2秒,让用户看到完成状态 + } +}, [task?.status]); +``` + +--- + +### 3.3 审核工作台页面 (Workbench) + +#### 3.3.1 页面结构 + +``` +┌──────────────────────────────────────────────────────────────┐ +│ 全文复筛 / 审核工作台 │ +├──────────────────────────────────────────────────────────────┤ +│ │ +│ 📋 PICOS标准 (点击展开) ▼ │ +│ ┌────────────────────────────────────────────────────────┐ │ +│ │ P: 2型糖尿病成人患者 | I: SGLT2抑制剂 | ... │ │ +│ └────────────────────────────────────────────────────────┘ │ +│ │ +│ 📊 统计概览 │ +│ ┌────────────────────────────────────────────────────────┐ │ +│ │ 总数: 5 | 一致: 3 | 冲突: 2 | 待定: 0 │ │ +│ └────────────────────────────────────────────────────────┘ │ +│ │ +│ 🔍 筛选: [全部▼] [冲突▼] [一致▼] 🔎 搜索: [____]│ +│ │ +│ ┌────────────────────────────────────────────────────────┐ │ +│ │ 文献 | DS判断(PICS) | Q3判断(PICS) | 冲突 | 决策 | 操作│ │ +│ ├────────────────────────────────────────────────────────┤ │ +│ │ [+] │ │ │ │ │ │ │ +│ │ PMID │ ✓ ✓ ✓ ✓ 纳入 │ ✓ ✓ ✓ ✓ 纳入│ 一致 │纳入 │详情 │ │ +│ │ 123 │ │ │ │ │ │ │ +│ ├────────────────────────────────────────────────────────┤ │ +│ │ [+] │ │ │ │ │ │ │ +│ │ PMID │ ✓ ✓ ✗ ✓ 排除 │ ✓ ✓ ✓ ✓ 纳入│❗冲突│[▼] │详情 │ │ +│ │ 456 │ │ │ │ │ │ │ +│ │ │ ├──────────────────────────────────────────────────│ │ +│ │ └─> │ 💡 冲突原因:对照组(C)判断不一致 │ │ +│ │ │ • DS: C不符合(未提及对照组) │ │ +│ │ │ • Q3: C符合(安慰剂对照) │ │ +│ │ └──────────────────────────────────────────────────│ │ +│ └────────────────────────────────────────────────────────┘ │ +│ │ +│ [完成审核,进入结果页面] │ +└──────────────────────────────────────────────────────────────┘ +``` + +#### 3.3.2 功能模块 + +**(1)PICOS标准折叠面板** +- 默认折叠,节省空间 +- 点击展开显示完整PICOS标准 +- 供审核时参考 + +**(2)统计概览卡片** +- 显示总数、一致数、冲突数、待定数 +- 快速了解整体情况 + +**(3)筛选和搜索** +- 按冲突状态筛选:全部/仅冲突/仅一致 +- 按决策筛选:全部/纳入/排除/待定 +- 搜索:支持PMID、标题关键词 + +**(4)双模型判断表格** +- 显示PICS四维度符合性(✓/✗/?) +- 显示双模型结论(纳入/排除) +- 冲突行自动高亮(红色背景) +- 展开行显示冲突详情 + +**(5)最终决策列** +- 一致文献:自动采用AI决策 +- 冲突文献:显示下拉框,需人工决策 +- 支持三个选项:纳入/排除/待定 + +**(6)操作列** +- "详情" 按钮 → 打开详情抽屉 + +#### 3.3.3 详情抽屉设计 + +**布局**: 右侧滑出(宽度800px) + +``` +┌────────────────────────────────────────┐ +│ 文献详情 - PMID456 [×] │ +├────────────────────────────────────────┤ +│ [AI判断对比] [PDF全文] [12字段详情] │ ← Tab切换 +├────────────────────────────────────────┤ +│ │ +│ 📄 基本信息 │ +│ • 标题:Effect of SGLT2 inhibitors... │ +│ • 作者:Zhang W, Li H, Wang Y │ +│ • 期刊:JAMA 2023;15(3):e124 │ +│ • 年份:2023 │ +│ │ +│ ───────────────────────────────────── │ +│ │ +│ 🤖 AI判断对比 │ +│ │ +│ ┌──────────────┬──────────────┐ │ +│ │ DeepSeek-V3 │ Qwen-Max │ │ +│ ├──────────────┼──────────────┤ │ +│ │ P: ✓ 符合 │ P: ✓ 符合 │ │ +│ │ 成人T2DM患 │ 成人T2DM │ │ +│ │ 者,年龄... │ 患者 │ │ +│ │ │ │ │ +│ │ I: ✓ 符合 │ I: ✓ 符合 │ │ +│ │ SGLT2抑制剂│ 达格列净 │ │ +│ │ 达格列净... │ │ │ +│ │ │ │ │ +│ │ C: ✗ 不符合 │ C: ✓ 符合 │ ← 冲突│ +│ │ 未明确对照 │ 安慰剂对 │ │ +│ │ 组,仅提及 │ 照,双盲 │ │ +│ │ "常规治疗" │ │ │ +│ │ │ │ │ +│ │ S: ✓ 符合 │ S: ✓ 符合 │ │ +│ │ 随机对照试 │ RCT,多 │ │ +│ │ 验,多中心 │ 中心研究 │ │ +│ │ │ │ │ +│ │ 结论:排除 │ 结论:纳入 │ │ +│ └──────────────┴──────────────┘ │ +│ │ +│ ⚠️ 冲突提示:两个模型在对照组(C)判断 │ +│ 上存在分歧,建议查看原文验证 │ +│ │ +│ ───────────────────────────────────── │ +│ │ +│ ✏️ 人工决策 │ +│ 最终决策:[纳入 ▼] │ +│ 决策理由: │ +│ ┌──────────────────────────────────┐ │ +│ │ 虽然DS判断对照组不符合,但查看 │ │ +│ │ 原文后确认为安慰剂对照,符合纳入 │ │ +│ │ 标准。 │ │ +│ └──────────────────────────────────┘ │ +│ │ +│ [取消] [保存决策] │ +└────────────────────────────────────────┘ +``` + +**Tab 2: PDF全文预览** +``` +┌────────────────────────────────────────┐ +│ 文献详情 - PMID456 [×] │ +├────────────────────────────────────────┤ +│ [AI判断对比] [PDF全文] [12字段详情] │ +├────────────────────────────────────────┤ +│ │ +│ 📄 PDF预览 │ +│ ┌────────────────────────────────────┐ │ +│ │ │ │ +│ │ [PDF内容渲染区域] │ │ +│ │ │ │ +│ │ 使用 react-pdf 渲染 │ │ +│ │ │ │ +│ │ 支持: │ │ +│ │ • 翻页(上一页/下一页) │ │ +│ │ • 缩放(放大/缩小/适应) │ │ +│ │ • 跳页(输入页码直接跳转) │ │ +│ │ │ │ +│ └────────────────────────────────────┘ │ +│ │ +│ 页码:3 / 15 [<] [>] [跳转__] │ +│ 缩放:[100% ▼] [适应宽度] [适应高度] │ +│ │ +└────────────────────────────────────────┘ +``` + +**Tab 3: 12字段详情** +``` +┌────────────────────────────────────────┐ +│ 文献详情 - PMID456 [×] │ +├────────────────────────────────────────┤ +│ [AI判断对比] [PDF全文] [12字段详情] │ +├────────────────────────────────────────┤ +│ │ +│ 📋 12字段完整性评估 │ +│ │ +│ ▼ 1. 文献来源 │ +│ 存在性: ✅ 完整 │ +│ 第一作者: Zhang W │ +│ 年份: 2023 │ +│ 期刊: JAMA │ +│ │ +│ ▼ 2. 研究类型 │ +│ 存在性: ✅ 完整 │ +│ 类型: RCT │ +│ │ +│ ▶ 3. 研究设计细节 (点击展开) │ +│ │ +│ ▶ 4. 疾病诊断标准 │ +│ │ +│ ▶ 5. 人群特征 ⭐ (关键字段) │ +│ │ +│ ... (共12个字段) │ +│ │ +└────────────────────────────────────────┘ +``` + +--- + +### 3.4 结果展示页面 (Results) + +#### 3.4.1 页面结构 + +``` +┌─────────────────────────────────────────────┐ +│ 全文复筛 / 结果展示 │ +├─────────────────────────────────────────────┤ +│ │ +│ 📊 总体统计 │ +│ ┌───────────┬───────────┬───────────┐ │ +│ │ 总计复筛 │ 最终纳入 │ 排除 │ │ +│ │ 100 │ 55 │ 45 │ │ +│ └───────────┴───────────┴───────────┘ │ +│ │ +│ 📈 PRISMA流程图统计 │ +│ ┌─────────────────────────────────────────┐ │ +│ │ 排除原因统计: │ │ +│ │ • 排除文献总数: 45篇 │ │ +│ │ • 非随机对照研究(S): 5篇 │ │ +│ │ • 非目标人群(P): 7篇 │ │ +│ │ • 干预/对照不符(I/C): 18篇 │ │ +│ │ • 结局指标不符(O): 9篇 │ │ +│ │ • 其他原因: 6篇 │ │ +│ └─────────────────────────────────────────┘ │ +│ │ +│ 💰 成本统计 │ +│ ┌─────────────────────────────────────────┐ │ +│ │ • DeepSeek-V3: Token 245K, 成本 ¥0.82 │ │ +│ │ • Qwen-Max: Token 198K, 成本 ¥1.35 │ │ +│ │ • 总计: Token 443K, 成本 ¥2.17 │ │ +│ │ • 平均单篇成本: ¥0.0217 │ │ +│ └─────────────────────────────────────────┘ │ +│ │ +│ 📋 文献列表 [导出Excel]│ +│ ┌─────────────────────────────────────────┐ │ +│ │ [最终纳入 (55)] [排除 (45)] ← Tab │ │ +│ │ │ │ +│ │ 🔎 搜索: [________] [筛选▼] │ │ +│ │ │ │ +│ │ PMID | 研究ID | 来源 | 决策 | 方式 │ │ +│ │ 123 | A1 2021│ ... | 纳入 | AI纳入 │ │ +│ │ 456 | B2 2022│ ... | 纳入 | 人工审核 │ │ +│ │ ... │ │ +│ └─────────────────────────────────────────┘ │ +└─────────────────────────────────────────────┘ +``` + +#### 3.4.2 功能说明 + +**(1)总体统计卡片** +- 显示总数、纳入数、排除数 +- 大数字突出显示 +- 绿色(纳入)、红色(排除)配色 + +**(2)PRISMA统计卡片** +- 按排除原因分类统计 +- 符合PRISMA流程图要求 +- 便于撰写系统评价报告 + +**(3)成本统计卡片** +- 双模型Token和成本对比 +- 显示平均单篇成本 +- 便于成本控制和优化 + +**(4)文献列表** +- Tab切换:最终纳入 / 排除 +- 显示文献基本信息 +- 显示决策方式:AI纳入/AI排除/人工审核 +- 支持搜索和筛选 + +**(5)导出Excel按钮** +- 下载4-Sheet Excel报告 +- 包含:纳入文献、排除文献、PRISMA统计、成本统计 + +--- + +## 4. 组件清单 + +### 4.1 页面组件(Page Components) + +| 组件名 | 文件路径 | 功能描述 | 预计工作量 | +|--------|----------|----------|------------| +| `FulltextScreeningSettings` | `pages/FulltextScreeningSettings.tsx` | 设置与启动页面 | 4小时 | +| `FulltextScreeningProgress` | `pages/FulltextScreeningProgress.tsx` | 任务进度监控页面 | 3小时 | +| `FulltextScreeningWorkbench` | `pages/FulltextScreeningWorkbench.tsx` | 审核工作台页面 | 6小时 | +| `FulltextScreeningResults` | `pages/FulltextScreeningResults.tsx` | 结果展示页面 | 3小时 | + +### 4.2 功能组件(Feature Components) + +| 组件名 | 文件路径 | 功能描述 | 预计工作量 | +|--------|----------|----------|------------| +| `PICOSCard` | `components/PICOSCard.tsx` | PICOS标准展示卡片(可折叠) | 1小时 | +| `PICOSEditModal` | `components/PICOSEditModal.tsx` | PICOS编辑弹窗 | 2小时 | +| `PDFUploadModal` | `components/PDFUploadModal.tsx` | PDF上传弹窗 | 2小时 | +| `LiteratureTable` | `components/LiteratureTable.tsx` | 文献管理表格 | 2小时 | +| `ProgressMonitor` | `components/ProgressMonitor.tsx` | 进度监控组件 | 2小时 | +| `DualModelJudgmentTable` | `components/DualModelJudgmentTable.tsx` | 双模型判断表格 | 4小时 | +| `LiteratureDetailDrawer` | `components/LiteratureDetailDrawer.tsx` | 文献详情抽屉 | 4小时 | +| `PDFViewer` | `components/PDFViewer.tsx` | PDF预览组件 | 2小时 | +| `FieldsCollapse` | `components/FieldsCollapse.tsx` | 12字段折叠面板 | 2小时 | +| `PRISMAStatistics` | `components/PRISMAStatistics.tsx` | PRISMA统计卡片 | 1小时 | + +### 4.3 复用组件(Reused Components) + +| 组件名 | 来源 | 功能描述 | +|--------|------|----------| +| `ASLLayout` | 标题摘要初筛 | 左侧导航布局 | +| `JudgmentBadge` | 标题摘要初筛 | PICOS判断标签(✓/✗/?) | +| `ConclusionTag` | 标题摘要初筛 | 决策标签(纳入/排除) | + +### 4.4 Hooks(自定义钩子) + +| Hook名 | 文件路径 | 功能描述 | 预计工作量 | +|--------|----------|----------|------------| +| `useFulltextTask` | `hooks/useFulltextTask.ts` | 管理全文复筛任务状态 | 1小时 | +| `useTaskProgress` | `hooks/useTaskProgress.ts` | 轮询任务进度 | 1小时 | +| `useTaskResults` | `hooks/useTaskResults.ts` | 获取任务结果 | 1小时 | + +--- + +## 5. 开发排期 + +### 5.1 Day 6 - 基础页面(8小时) + +#### 上午(4小时) + +**5.1.1 设置与启动页面基础**(2小时) +- [ ] 创建页面文件和路由 +- [ ] 实现PICOS展示卡片 +- [ ] 实现模型配置表单 +- [ ] 实现文献列表表格(基础版) + +**5.1.2 PICOS编辑和PDF上传弹窗**(2小时) +- [ ] 实现PICOS编辑弹窗 +- [ ] 实现PDF上传弹窗(Ant Design Upload) +- [ ] 集成后端PDF上传API +- [ ] 实时显示上传进度 + +#### 下午(4小时) + +**5.1.3 任务进度监控页面**(4小时) +- [ ] 创建页面文件和路由 +- [ ] 实现进度条和统计卡片 +- [ ] 实现轮询机制(React Query) +- [ ] 实现处理日志滚动显示 +- [ ] 任务完成后自动跳转 + +--- + +### 5.2 Day 7 - 核心功能(10小时) + +#### 上午(5小时) + +**5.2.1 审核工作台页面基础**(3小时) +- [ ] 创建页面文件和路由 +- [ ] 实现PICOS折叠面板 +- [ ] 实现统计概览卡片 +- [ ] 实现筛选和搜索功能 +- [ ] 实现双模型判断表格(基础版) + +**5.2.2 冲突可视化**(2小时) +- [ ] 冲突行高亮显示 +- [ ] 展开行显示冲突详情 +- [ ] 冲突原因文字说明 +- [ ] 最终决策下拉框(含验证) + +#### 下午(5小时) + +**5.2.3 文献详情抽屉 - AI判断对比Tab**(2小时) +- [ ] 创建抽屉组件(Ant Design Drawer) +- [ ] 实现基本信息展示 +- [ ] 实现双模型判断对比(左右分栏) +- [ ] 高亮冲突字段 +- [ ] 人工决策表单(含提交) + +**5.2.4 PDF预览Tab**(2小时) +- [ ] 集成react-pdf库 +- [ ] 实现基础PDF渲染 +- [ ] 实现翻页功能(上一页/下一页/跳页) +- [ ] 实现缩放功能(放大/缩小/适应) +- [ ] 优化加载性能 + +**5.2.5 12字段详情Tab**(1小时) +- [ ] 实现12字段折叠面板(Ant Design Collapse) +- [ ] 显示每个字段的存在性、完整性 +- [ ] 支持展开/折叠单个字段 + +--- + +### 5.3 Day 8 - 结果页面与联调(6小时) + +#### 上午(3小时) + +**5.3.1 结果展示页面**(3小时) +- [ ] 创建页面文件和路由 +- [ ] 实现总体统计卡片 +- [ ] 实现PRISMA统计卡片 +- [ ] 实现成本统计卡片 +- [ ] 实现文献列表(Tab切换) +- [ ] 实现Excel导出功能 + +#### 下午(3小时) + +**5.3.2 前后端联调**(2小时) +- [ ] 测试完整流程(设置→进度→工作台→结果) +- [ ] 测试PDF上传 +- [ ] 测试实时进度轮询 +- [ ] 测试人工决策提交 +- [ ] 测试Excel导出下载 + +**5.3.3 Bug修复和优化**(1小时) +- [ ] 修复发现的Bug +- [ ] 优化UI细节 +- [ ] 优化性能(懒加载、虚拟滚动等) +- [ ] 补充错误处理和提示 + +--- + +## 6. 技术实现 + +### 6.1 技术栈 + +- **框架**: React 18 + TypeScript 5 +- **路由**: React Router DOM v6 +- **状态管理**: @tanstack/react-query (React Query v5) +- **UI组件**: Ant Design v5 +- **PDF预览**: react-pdf v7 +- **文件上传**: Ant Design Upload + axios +- **样式**: TailwindCSS v3 + +### 6.2 关键技术实现 + +#### 6.2.1 PDF上传 + +```typescript +import { Upload, message } from 'antd'; +import type { UploadFile } from 'antd/es/upload/interface'; + +const PDFUploadModal = () => { + const [fileList, setFileList] = useState([]); + + const customRequest = async ({ file, onProgress, onSuccess, onError }: any) => { + try { + const formData = new FormData(); + formData.append('file', file); + + const response = await axios.post( + '/api/v1/asl/literatures/upload-pdf', + formData, + { + onUploadProgress: (e) => { + const percent = Math.round((e.loaded / e.total!) * 100); + onProgress({ percent }); + }, + } + ); + + onSuccess(response.data); + message.success(`${file.name} 上传成功`); + } catch (error) { + onError(error); + message.error(`${file.name} 上传失败`); + } + }; + + return ( + setFileList(fileList)} + beforeUpload={(file) => { + // 验证文件大小(最大50MB) + const isLt50M = file.size / 1024 / 1024 < 50; + if (!isLt50M) { + message.error('文件大小不能超过50MB!'); + } + return isLt50M; + }} + > +

📁

+

拖拽文件到此处,或点击选择文件

+

+ 支持格式:PDF | 单个文件最大:50MB | 支持批量上传(最多20篇) +

+
+ ); +}; +``` + +#### 6.2.2 任务进度轮询 + +```typescript +import { useQuery } from '@tanstack/react-query'; +import { useNavigate } from 'react-router-dom'; + +const useTaskProgress = (taskId: string) => { + const navigate = useNavigate(); + + const { data: task, isLoading } = useQuery({ + queryKey: ['fulltextTask', taskId], + queryFn: async () => { + const res = await axios.get(`/api/v1/asl/fulltext-screening/tasks/${taskId}/progress`); + return res.data.data; + }, + refetchInterval: (data) => { + // 任务进行中:每3秒轮询 + // 任务完成或失败:停止轮询 + return data?.status === 'processing' ? 3000 : false; + }, + refetchOnWindowFocus: false, + }); + + // 任务完成后自动跳转 + useEffect(() => { + if (task?.status === 'completed') { + setTimeout(() => { + navigate(`/asl/fulltext-screening/workbench/${taskId}`); + }, 2000); + } + }, [task?.status, taskId, navigate]); + + return { task, isLoading }; +}; +``` + +#### 6.2.3 PDF预览组件 + +```typescript +import { useState } from 'react'; +import { Document, Page, pdfjs } from 'react-pdf'; +import 'react-pdf/dist/esm/Page/AnnotationLayer.css'; +import 'react-pdf/dist/esm/Page/TextLayer.css'; + +// 配置PDF.js worker +pdfjs.GlobalWorkerOptions.workerSrc = `//cdnjs.cloudflare.com/ajax/libs/pdf.js/${pdfjs.version}/pdf.worker.js`; + +interface PDFViewerProps { + url: string; +} + +const PDFViewer: React.FC = ({ url }) => { + const [numPages, setNumPages] = useState(0); + const [pageNumber, setPageNumber] = useState(1); + const [scale, setScale] = useState(1.0); + + const onDocumentLoadSuccess = ({ numPages }: { numPages: number }) => { + setNumPages(numPages); + setPageNumber(1); + }; + + const changePage = (offset: number) => { + setPageNumber((prev) => Math.min(Math.max(1, prev + offset), numPages)); + }; + + const changeScale = (newScale: number) => { + setScale(Math.min(Math.max(0.5, newScale), 2.0)); + }; + + return ( +
+ 加载中...
} + error={
PDF加载失败
} + > + + + +
+
+ + + 页码:{pageNumber} / {numPages} + + +
+ +
+ + {Math.round(scale * 100)}% + + +
+
+ + ); +}; + +export default PDFViewer; +``` + +#### 6.2.4 双模型判断表格 + +```typescript +interface DualModelJudgmentTableProps { + results: FulltextScreeningResult[]; + onUpdateDecision: (resultId: string, decision: string) => void; + onOpenDetail: (result: FulltextScreeningResult) => void; +} + +const DualModelJudgmentTable: React.FC = ({ + results, + onUpdateDecision, + onOpenDetail, +}) => { + const [expandedKeys, setExpandedKeys] = useState([]); + + const columns: ColumnsType = [ + { + title: '文献', + dataIndex: 'literatureId', + key: 'literatureId', + render: (_, record) => record.literature.pmid, + }, + { + title: 'DS判断(PICS)', + key: 'modelA', + render: (_, record) => { + const { modelAFields, modelAOverall } = record; + return ( +
+ + + + + +
+ ); + }, + }, + { + title: 'Q3判断(PICS)', + key: 'modelB', + render: (_, record) => { + const { modelBFields, modelBOverall } = record; + return ( +
+ + + + + +
+ ); + }, + }, + { + title: '冲突', + key: 'conflict', + render: (_, record) => { + const hasConflict = record.conflictSeverity !== null; + return hasConflict ? ( + 冲突 + ) : ( + 一致 + ); + }, + }, + { + title: '决策', + key: 'decision', + render: (_, record) => { + const hasConflict = record.conflictSeverity !== null; + if (!hasConflict && record.finalDecision) { + return ; + } + return ( + + ); + }, + }, + { + title: '操作', + key: 'action', + render: (_, record) => ( + + ), + }, + ]; + + return ( + { + if (expanded) { + setExpandedKeys([...expandedKeys, record.id]); + } else { + setExpandedKeys(expandedKeys.filter((k) => k !== record.id)); + } + }, + expandedRowRender: (record) => { + if (!record.conflictFields || record.conflictFields.length === 0) { + return null; + } + return ( +
+

💡 冲突详情:

+
    + {record.conflictFields.map((field) => ( +
  • + {field}: Model A vs Model B 判断不一致 +
  • + ))} +
+
+ ); + }, + rowExpandable: (record) => + record.conflictFields && record.conflictFields.length > 0, + }} + rowClassName={(record) => + record.conflictSeverity ? 'bg-red-50' : '' + } + /> + ); +}; +``` + +#### 6.2.5 Excel导出 + +```typescript +const handleExportExcel = async (taskId: string) => { + try { + message.loading({ content: '正在生成Excel...', key: 'export' }); + + const response = await axios.get( + `/api/v1/asl/fulltext-screening/tasks/${taskId}/export`, + { + responseType: 'blob', // 重要:指定响应类型为blob + } + ); + + // 创建下载链接 + const url = window.URL.createObjectURL(new Blob([response.data])); + const link = document.createElement('a'); + link.href = url; + + // 从响应头获取文件名 + const contentDisposition = response.headers['content-disposition']; + const filename = contentDisposition + ? contentDisposition.split('filename=')[1].replace(/"/g, '') + : `全文复筛结果_${taskId}.xlsx`; + + link.setAttribute('download', filename); + document.body.appendChild(link); + link.click(); + + // 清理 + link.remove(); + window.URL.revokeObjectURL(url); + + message.success({ content: '导出成功!', key: 'export' }); + } catch (error) { + message.error({ content: '导出失败', key: 'export' }); + console.error('Export error:', error); + } +}; +``` + +--- + +## 7. 测试计划 + +### 7.1 功能测试 + +**测试用例**: + +| 编号 | 测试项 | 测试步骤 | 预期结果 | +|------|--------|----------|----------| +| T1 | PDF上传 | 上传单个PDF | 上传成功,显示在文献列表 | +| T2 | PDF批量上传 | 上传5个PDF | 全部上传成功 | +| T3 | PDF大小验证 | 上传>50MB的PDF | 提示文件过大,上传失败 | +| T4 | PICOS编辑 | 修改P字段并保存 | PICOS卡片更新 | +| T5 | 创建任务 | 点击"开始全文复筛" | 跳转到进度页面 | +| T6 | 进度轮询 | 停留在进度页面 | 每3秒更新一次进度 | +| T7 | 自动跳转 | 等待任务完成 | 自动跳转到工作台 | +| T8 | 冲突可视化 | 查看工作台冲突行 | 红色高亮,显示冲突详情 | +| T9 | 人工决策 | 修改冲突文献决策 | 保存成功,刷新列表 | +| T10 | PDF预览 | 打开详情抽屉查看PDF | PDF正常渲染,可翻页缩放 | +| T11 | Excel导出 | 点击"导出Excel" | 下载4-Sheet Excel文件 | + +### 7.2 性能测试 + +| 测试项 | 测试条件 | 性能指标 | +|--------|----------|----------| +| 页面加载 | 首次访问 | < 2秒 | +| PDF上传 | 10MB文件 | < 5秒 | +| 进度轮询 | 轮询100次 | 无内存泄漏 | +| PDF渲染 | 15页PDF | < 3秒 | +| 表格渲染 | 100条数据 | < 1秒 | + +### 7.3 兼容性测试 + +| 浏览器 | 版本 | 测试结果 | +|--------|------|----------| +| Chrome | 最新版 | ✅ 通过 | +| Firefox | 最新版 | ✅ 通过 | +| Edge | 最新版 | ✅ 通过 | +| Safari | 最新版 | ⚠️ PDF预览需额外测试 | + +--- + +## 📝 附录 + +### A. API接口清单 + +| 接口 | 方法 | 路径 | 功能 | +|------|------|------|------| +| 上传PDF | POST | `/api/v1/asl/literatures/upload-pdf` | 上传单个PDF文件 | +| 创建任务 | POST | `/api/v1/asl/fulltext-screening/tasks` | 创建全文复筛任务 | +| 获取进度 | GET | `/api/v1/asl/fulltext-screening/tasks/:taskId/progress` | 获取任务进度 | +| 获取结果 | GET | `/api/v1/asl/fulltext-screening/tasks/:taskId/results` | 获取任务结果列表 | +| 更新决策 | PUT | `/api/v1/asl/fulltext-screening/results/:resultId/decision` | 人工更新决策 | +| 导出Excel | GET | `/api/v1/asl/fulltext-screening/tasks/:taskId/export` | 导出Excel报告 | + +### B. 数据结构 + +**FulltextScreeningTask**: +```typescript +interface FulltextScreeningTask { + id: string; + projectId: string; + status: 'pending' | 'processing' | 'completed' | 'failed'; + totalCount: number; + processedCount: number; + successCount: number; + failedCount: number; + degradedCount: number; + totalTokens: number; + totalCost: number; + createdAt: Date; + startedAt: Date | null; + completedAt: Date | null; +} +``` + +**FulltextScreeningResult**: +```typescript +interface FulltextScreeningResult { + id: string; + taskId: string; + literatureId: string; + literature: { + pmid: string; + title: string; + authors: string; + journal: string; + publicationYear: number; + }; + modelAName: string; + modelAStatus: 'success' | 'failed'; + modelAFields: any; // 12字段 + modelAOverall: { + overall_decision: 'include' | 'exclude'; + overall_reasoning: string; + }; + modelBName: string; + modelBStatus: 'success' | 'failed'; + modelBFields: any; + modelBOverall: any; + conflictFields: string[]; + conflictSeverity: 'high' | 'medium' | 'low' | null; + finalDecision: 'include' | 'exclude' | 'pending' | null; + reviewedBy: string | null; + reviewedAt: Date | null; +} +``` + +--- + +**文档维护**: +- 开发过程中如有调整,及时更新本文档 +- 每个页面开发完成后,更新完成状态 +- 遇到技术难点,记录在文档中 + +**相关文档**: +- [全文复筛开发计划](./04-全文复筛开发计划.md) +- [API设计规范](../02-技术设计/02-API设计规范.md) +- [数据库设计](../02-技术设计/01-数据库设计.md) +- [技术债务清单](../06-技术债务/技术债务清单.md) + +--- + +**文档版本历史**: +- v1.0 (2025-11-23) - 初始版本,Day 5完成后创建 + diff --git a/docs/03-业务模块/ASL-AI智能文献/06-技术债务/技术债务清单.md b/docs/03-业务模块/ASL-AI智能文献/06-技术债务/技术债务清单.md index 96b569b0..478a2ec5 100644 --- a/docs/03-业务模块/ASL-AI智能文献/06-技术债务/技术债务清单.md +++ b/docs/03-业务模块/ASL-AI智能文献/06-技术债务/技术债务清单.md @@ -1,9 +1,9 @@ # AI智能文献模块 - 技术债务清单 -> **文档版本:** v1.1 +> **文档版本:** v1.2 > **创建日期:** 2025-11-21 > **维护者:** AI智能文献开发团队 -> **最后更新:** 2025-11-22 +> **最后更新:** 2025-11-23 > **文档目的:** 记录MVP完成后需要优化的技术问题 --- @@ -1065,6 +1065,265 @@ const estimate = estimateCost(literatures); --- +## 🎨 全文复筛 - 前端技术债务 + +> **模块**:全文复筛前端 +> **创建时间**:2025-11-23 +> **状态**:待开发 + +--- + +### 债务11:PDF标注功能 + +**问题描述**: +- MVP版本只支持PDF预览(翻页、缩放) +- 无法在PDF上进行标注、高亮、添加批注 +- 用户希望在审核时标记关键信息 + +**使用场景**: +- 审核工作台查看原文时,标记关键证据 +- 高亮冲突的文本片段 +- 添加个人审核笔记 + +**建议方案**: +- 集成PDF标注库(如 react-pdf-highlighter) +- 支持文本高亮、下划线、批注 +- 标注数据保存到数据库,可导出 + +**优先级**:中 +**预计耗时**:3-4天 +**依赖**:PDF预览功能完成 +**用户价值**:⭐⭐⭐⭐ + +--- + +### 债务12:文献笔记功能 + +**问题描述**: +- 无法为每篇文献添加审核笔记 +- 人工复核时的思考过程无法记录 +- 不便于后续回溯决策依据 + +**使用场景**: +- 记录为什么纳入/排除某篇文献 +- 记录需要进一步核查的问题 +- 团队协作时的沟通记录 + +**建议方案**: +- 在文献详情抽屉添加"笔记"Tab +- 支持富文本编辑器(Markdown) +- 支持@提及团队成员 +- 笔记保存到数据库 + +**优先级**:中 +**预计耗时**:2-3天 +**依赖**:详情抽屉完成 +**用户价值**:⭐⭐⭐⭐ + +--- + +### 债务13:从知识库选择文献 + +**问题描述**: +- MVP版本只支持本地上传PDF +- 无法从已有知识库中选择文献 +- 需要重复上传已存在的PDF + +**使用场景**: +- 用户在个人知识库中已保存大量文献 +- 希望直接选择现有文献进行全文复筛 +- 避免重复上传和存储 + +**建议方案**: +- 在"添加文献"弹窗添加"知识库"Tab +- 显示用户的所有PDF文献列表 +- 支持搜索、筛选、多选 +- 选中后自动关联到当前任务 + +**优先级**:低 +**预计耗时**:2天 +**依赖**:个人知识库模块(PKB) +**用户价值**:⭐⭐⭐ + +--- + +### 债务14:通过PMID/DOI自动获取全文 + +**问题描述**: +- 用户只有PMID或DOI,没有PDF文件 +- 需要手动去PubMed等网站下载PDF +- 增加操作成本和时间 + +**使用场景**: +- 用户有文献的PMID列表 +- 希望系统自动获取全文PDF +- 自动批量下载并关联 + +**建议方案**: +- 在"添加文献"弹窗添加"自动获取"Tab +- 输入PMID/DOI列表(支持批量) +- 调用第三方API(PubMed、Unpaywall、Sci-Hub镜像) +- 自动下载PDF并添加到任务 + +**优先级**:低 +**预计耗时**:3-5天 +**依赖**:第三方PDF获取API +**用户价值**:⭐⭐⭐⭐⭐ +**法律风险**:⚠️ 需评估版权问题 + +--- + +### 债务15:高亮AI引用的原文片段 + +**问题描述**: +- AI判断时引用了原文证据 +- 但在PDF预览中无法自动定位和高亮 +- 用户需要手动查找对应的文本 + +**使用场景**: +- 查看AI判断依据时,希望看到原文位置 +- 点击证据文本,PDF自动跳转并高亮 +- 验证AI提取是否准确 + +**建议方案**: +- 在AI判断对比中,证据文本变为可点击 +- 点击后PDF预览自动跳转到对应页面 +- 高亮匹配的文本片段(需要坐标信息) +- 后端需要返回文本在PDF中的位置坐标 + +**优先级**:中 +**预计耗时**:4-5天 +**依赖**:PDF提取服务返回文本坐标 +**用户价值**:⭐⭐⭐⭐⭐ +**技术难度**:⭐⭐⭐⭐ + +--- + +### 债务16:WebSocket实时推送替代轮询 + +**问题描述**: +- 当前使用轮询机制(每3秒请求一次) +- 增加服务器负载和网络流量 +- 进度更新有延迟(最多3秒) + +**使用场景**: +- 任务进度监控页面 +- 长时间运行的LLM任务 +- 希望实时看到处理日志 + +**建议方案**: +- 后端实现WebSocket服务 +- 前端建立WebSocket连接 +- 任务进度变化时主动推送 +- 降级策略:WebSocket不可用时回退到轮询 + +**优先级**:低 +**预计耗时**:3-4天 +**依赖**:后端WebSocket实现 +**用户价值**:⭐⭐⭐ +**性能提升**:⭐⭐⭐⭐ + +--- + +### 债务17:虚拟滚动优化大列表性能 + +**问题描述**: +- 当文献数量>100篇时,表格渲染变慢 +- 所有行都渲染到DOM,占用大量内存 +- 滚动时可能出现卡顿 + +**使用场景**: +- 大规模全文复筛(200+篇文献) +- 审核工作台和结果页面 +- 需要流畅的滚动体验 + +**建议方案**: +- 使用虚拟滚动库(react-window / react-virtualized) +- 只渲染可见区域的行 +- 优化Ant Design Table性能 +- 添加性能监控 + +**优先级**:低 +**预计耗时**:2天 +**条件触发**:文献数量>100篇 +**用户价值**:⭐⭐⭐ +**性能提升**:⭐⭐⭐⭐⭐ + +--- + +### 债务18:批量操作功能 + +**问题描述**: +- 结果页面只能单个文献操作 +- 无法批量修改决策 +- 无法批量导出选中的文献 + +**使用场景**: +- 批量标记为"纳入"或"排除" +- 批量导出选中文献的PDF +- 批量删除错误上传的文献 + +**建议方案**: +- 表格添加复选框列 +- 添加批量操作工具栏 +- 支持:批量修改决策、批量导出、批量删除 +- 添加操作确认提示 + +**优先级**:低 +**预计耗时**:2天 +**用户价值**:⭐⭐⭐⭐ + +--- + +### 债务19:离线PDF预览支持 + +**问题描述**: +- PDF预览依赖在线CDN加载pdf.js worker +- 网络不好时加载失败 +- 内网环境无法使用 + +**使用场景**: +- 内网部署环境 +- 网络不稳定的用户 +- 需要完全离线使用 + +**建议方案**: +- 将pdf.js worker打包到项目中 +- 支持本地加载和CDN加载两种模式 +- 自动检测网络并选择最优方式 + +**优先级**:低 +**预计耗时**:1天 +**条件触发**:内网部署需求 +**用户价值**:⭐⭐⭐ + +--- + +### 债务20:响应式设计适配移动端 + +**问题描述**: +- 当前设计只考虑桌面端(1920x1080) +- 在平板和手机上显示效果差 +- 表格宽度固定,小屏幕下无法使用 + +**使用场景**: +- 用户希望在平板上审核文献 +- 移动场景下查看任务进度 +- 外出时临时处理审核 + +**建议方案**: +- 使用响应式布局(Tailwind CSS) +- 小屏幕下表格改为卡片视图 +- 优化触摸交互体验 +- 添加移动端导航 + +**优先级**:极低 +**预计耗时**:5-7天 +**条件触发**:用户明确需求 +**用户价值**:⭐⭐ + +--- + ## 📚 相关文档 **标题摘要初筛**: @@ -1074,9 +1333,11 @@ const estimate = estimateCost(literatures); - [今日工作总结](../05-开发记录/2025-11-18-今日工作总结.md) - 边界问题诊断 **全文复筛**: -- [全文复筛开发计划](../04-开发计划/04-全文复筛开发计划.md) - 开发进度和计划 +- [全文复筛开发计划](../04-开发计划/04-全文复筛开发计划.md) - 后端开发进度和计划 +- [全文复筛前端开发计划](../04-开发计划/05-全文复筛前端开发计划.md) - 前端开发详细计划 - [全文复筛质量保障策略](../02-技术设计/08-全文复筛质量保障策略.md) - 质量策略设计 -- [Day 2-3开发记录](../05-开发记录/2025-11-22_Day2-Day3_LLM服务与验证系统开发.md) - 已完成工作 +- [Day 2-3开发记录](../05-开发记录/2025-11-22_Day2-Day3_LLM服务与验证系统开发.md) - LLM服务开发 +- [Day 5开发记录](../05-开发记录/2025-11-23_Day5_全文复筛API开发.md) - 后端API开发 --- @@ -1085,7 +1346,7 @@ const estimate = estimateCost(literatures); - 每次解决技术债务后标记状态 - 定期评估优先级(每月) -**最后更新**:2025-11-22(v1.1) -**本次更新**:新增全文复筛技术债务(10项) -**下次评估**:全文复筛MVP完成后 +**最后更新**:2025-11-23(v1.2) +**本次更新**:新增全文复筛前端技术债务(10项,债务11-20) +**下次评估**:全文复筛前端MVP完成后