feat(aia): Complete AIA V2.0 with universal streaming capabilities
Major Changes: - Add StreamingService with OpenAI Compatible format - Upgrade Chat component V2 with Ant Design X integration - Implement AIA module with 12 intelligent agents - Update API routes to unified /api/v1 prefix - Update system documentation Backend (~1300 lines): - common/streaming: OpenAI Compatible adapter - modules/aia: 12 agents, conversation service, streaming integration - Update route versions (RVW, PKB to v1) Frontend (~3500 lines): - modules/aia: AgentHub + ChatWorkspace (100% prototype restoration) - shared/Chat: AIStreamChat, ThinkingBlock, useAIStream Hook - Update API endpoints to v1 Documentation: - AIA module status guide - Universal capabilities catalog - System overview updates - All module documentation sync Tested: Stream response verified, authentication working Status: AIA V2.0 core completed (85%)
This commit is contained in:
@@ -1,98 +1,72 @@
|
||||
# ASL 妯″潡寮€鍙戦噷绋嬬<E7BB8B>
|
||||
|
||||
> **文档版本:** V3.0
|
||||
> **创建日期:** 2025-11-16
|
||||
> **维护者:** AI智能文献开发团队
|
||||
> **鏂囨。鐗堟湰锛?* V3.0
|
||||
> **鍒涘缓鏃ユ湡锛?* 2025-11-16
|
||||
> **缁存姢鑰咃細** AI鏅鸿兘鏂囩尞寮€鍙戝洟闃?
|
||||
> **鏈€鍚庢洿鏂帮細** 2025-11-16
|
||||
> **⭐ 重要:基于真实架构(Frontend-v2 + Backend增量演进)**
|
||||
> **猸?閲嶈<E996B2>锛氬熀浜庣湡瀹炴灦鏋勶紙Frontend-v2 + Backend澧為噺婕旇繘锛?*
|
||||
|
||||
---
|
||||
|
||||
## 馃搵 鏂囨。姒傝堪
|
||||
|
||||
本文档定义 ASL(AI智能文献)模块的完整开发里程碑,采用 **MVP → V1.0 → V2.0** 三阶段渐进式演进策略。
|
||||
|
||||
**架构前提:**
|
||||
- ✅ Frontend-v2 全新架构(顶部导航 + 模块注册)- Week 2 Day 6-7 已完成
|
||||
- ✅ Backend 增量演进架构(legacy/ + common/ + modules/)- Week 2 Day 8-9 已完成
|
||||
- ✅ 数据库 10个Schema隔离 - Week 1 已完成
|
||||
- 🚧 ASL 模块占位就绪,等待 Week 3 开发
|
||||
|
||||
鏈<EFBFBD>枃妗e畾涔?ASL锛圓I鏅鸿兘鏂囩尞锛夋ā鍧楃殑瀹屾暣寮€鍙戦噷绋嬬<E7BB8B>锛岄噰鐢?**MVP 鈫?V1.0 鈫?V2.0** 涓夐樁娈垫笎杩涘紡婕旇繘绛栫暐銆?
|
||||
**鏋舵瀯鍓嶆彁锛?*
|
||||
- 鉁?Frontend-v2 鍏ㄦ柊鏋舵瀯锛堥《閮ㄥ<E996AE>鑸?+ 妯″潡娉ㄥ唽锛? Week 2 Day 6-7 宸插畬鎴?- 鉁?Backend 澧為噺婕旇繘鏋舵瀯锛坙egacy/ + common/ + modules/锛? Week 2 Day 8-9 宸插畬鎴?- 鉁?鏁版嵁搴?10涓猄chema闅旂<E99785> - Week 1 宸插畬鎴?- 馃毀 ASL 妯″潡鍗犱綅灏辩华锛岀瓑寰?Week 3 寮€鍙?
|
||||
---
|
||||
|
||||
## 🏗️ 当前架构基础(已完成)
|
||||
|
||||
## 馃彈锔?褰撳墠鏋舵瀯鍩虹<E98DA9>锛堝凡瀹屾垚锛?
|
||||
### Frontend-v2 鐪熷疄鏋舵瀯
|
||||
```
|
||||
frontend-v2/src/
|
||||
├── framework/ # ✅ 已实现(Week 2 Day 6-7)
|
||||
│ ├── layout/
|
||||
│ │ ├── MainLayout.tsx # ✅ 主布局(顶部导航)
|
||||
│ │ └── TopNavigation.tsx # ✅ 顶部导航栏(6个模块)
|
||||
│ ├── modules/
|
||||
│ │ ├── moduleRegistry.ts # ✅ 模块注册中心
|
||||
│ │ ├── ErrorBoundary.tsx # ✅ 错误边界
|
||||
│ │ └── types.ts # ✅ 模块类型定义
|
||||
│ ├── router/
|
||||
│ │ └── RouteGuard.tsx # ✅ 路由守卫
|
||||
│ └── permission/
|
||||
│ ├── PermissionContext.tsx # ✅ 权限控制
|
||||
│ └── usePermission.ts # ✅ 权限Hook
|
||||
│
|
||||
└── modules/ # 📦 业务模块
|
||||
鈹溾攢鈹€ framework/ # 鉁?宸插疄鐜帮紙Week 2 Day 6-7锛?鈹? 鈹溾攢鈹€ layout/
|
||||
鈹? 鈹? 鈹溾攢鈹€ MainLayout.tsx # 鉁?涓诲竷灞€锛堥《閮ㄥ<E996AE>鑸<EFBFBD>級
|
||||
鈹? 鈹? 鈹斺攢鈹€ TopNavigation.tsx # 鉁?椤堕儴瀵艰埅鏍忥紙6涓<36>ā鍧楋級
|
||||
鈹? 鈹溾攢鈹€ modules/
|
||||
鈹? 鈹? 鈹溾攢鈹€ moduleRegistry.ts # 鉁?妯″潡娉ㄥ唽涓<E594BD>績
|
||||
鈹? 鈹? 鈹溾攢鈹€ ErrorBoundary.tsx # 鉁?閿欒<E996BF>杈圭晫
|
||||
鈹? 鈹? 鈹斺攢鈹€ types.ts # 鉁?妯″潡绫诲瀷瀹氫箟
|
||||
鈹? 鈹溾攢鈹€ router/
|
||||
鈹? 鈹? 鈹斺攢鈹€ RouteGuard.tsx # 鉁?璺<>敱瀹堝崼
|
||||
鈹? 鈹斺攢鈹€ permission/
|
||||
鈹? 鈹溾攢鈹€ PermissionContext.tsx # 鉁?鏉冮檺鎺у埗
|
||||
鈹? 鈹斺攢鈹€ usePermission.ts # 鉁?鏉冮檺Hook
|
||||
鈹?鈹斺攢鈹€ modules/ # 馃摝 涓氬姟妯″潡
|
||||
鈹溾攢鈹€ asl/ # 馃毀 ASL妯″潡锛堝崰浣嶏紝Week 3寮€鍙戯級
|
||||
│ └── index.tsx # ✅ 占位页面
|
||||
├── aia/ # ✅ AI问答(占位)
|
||||
├── pkb/ # ✅ 知识库(占位)
|
||||
├── dc/ # ✅ 数据清洗(占位)
|
||||
├── ssa/ # ✅ 统计分析(占位)
|
||||
└── st/ # ✅ 统计工具(占位)
|
||||
鈹? 鈹斺攢鈹€ index.tsx # 鉁?鍗犱綅椤甸潰
|
||||
鈹溾攢鈹€ aia/ # 鉁?AI闂<49>瓟锛堝崰浣嶏級
|
||||
鈹溾攢鈹€ pkb/ # 鉁?鐭ヨ瘑搴擄紙鍗犱綅锛? 鈹溾攢鈹€ dc/ # 鉁?鏁版嵁娓呮礂锛堝崰浣嶏級
|
||||
鈹溾攢鈹€ ssa/ # 鉁?缁熻<E7BC81>鍒嗘瀽锛堝崰浣嶏級
|
||||
鈹斺攢鈹€ st/ # 鉁?缁熻<E7BC81>宸ュ叿锛堝崰浣嶏級
|
||||
```
|
||||
|
||||
### Backend 鐪熷疄鏋舵瀯
|
||||
```
|
||||
backend/src/
|
||||
├── legacy/ # ✅ 现有业务(Week 2 Day 8-9完成迁移)
|
||||
│ ├── routes/ # 7个路由文件
|
||||
│ │ ├── projects.ts # AIA: 项目路由
|
||||
│ │ ├── agents.ts # AIA: 智能体路由
|
||||
│ │ ├── conversations.ts # AIA: 对话路由
|
||||
│ │ ├── chatRoutes.ts # AIA: 通用对话
|
||||
│ │ ├── knowledgeBases.ts # PKB: 知识库路由
|
||||
│ │ ├── batchRoutes.ts # PKB: 批处理路由
|
||||
│ │ └── reviewRoutes.ts # RVW: 稿件审查路由
|
||||
│ ├── controllers/ # 控制器
|
||||
│ └── services/ # 服务
|
||||
│
|
||||
├── common/ # ✅ 通用能力层(已实现)
|
||||
│ ├── llm/adapters/ # LLM适配器
|
||||
│ │ ├── DeepSeekAdapter.ts # ✅ DeepSeek-V3
|
||||
│ │ ├── QwenAdapter.ts # ✅ Qwen3-72B
|
||||
│ │ └── LLMFactory.ts # ✅ 工厂类
|
||||
│ ├── rag/
|
||||
│ │ └── DifyClient.ts # ✅ RAG客户端
|
||||
│ ├── document/
|
||||
│ │ └── ExtractionClient.ts # ✅ 文档提取客户端
|
||||
│ ├── middleware/
|
||||
│ │ └── validateProject.ts # ✅ 验证中间件
|
||||
│ └── utils/
|
||||
│ └── jsonParser.ts # ✅ JSON解析工具
|
||||
│
|
||||
└── modules/ # 🌟 新模块开发区
|
||||
鈹溾攢鈹€ legacy/ # 鉁?鐜版湁涓氬姟锛圵eek 2 Day 8-9瀹屾垚杩佺Щ锛?鈹? 鈹溾攢鈹€ routes/ # 7涓<37>矾鐢辨枃浠?鈹? 鈹? 鈹溾攢鈹€ projects.ts # AIA: 椤圭洰璺<E6B4B0>敱
|
||||
鈹? 鈹? 鈹溾攢鈹€ agents.ts # AIA: 鏅鸿兘浣撹矾鐢?鈹? 鈹? 鈹溾攢鈹€ conversations.ts # AIA: 瀵硅瘽璺<E798BD>敱
|
||||
鈹? 鈹? 鈹溾攢鈹€ chatRoutes.ts # AIA: 閫氱敤瀵硅瘽
|
||||
鈹? 鈹? 鈹溾攢鈹€ knowledgeBases.ts # PKB: 鐭ヨ瘑搴撹矾鐢?鈹? 鈹? 鈹溾攢鈹€ batchRoutes.ts # PKB: 鎵瑰<E98EB5>鐞嗚矾鐢?鈹? 鈹? 鈹斺攢鈹€ reviewRoutes.ts # RVW: 绋夸欢瀹℃煡璺<E785A1>敱
|
||||
鈹? 鈹溾攢鈹€ controllers/ # 鎺у埗鍣?鈹? 鈹斺攢鈹€ services/ # 鏈嶅姟
|
||||
鈹?鈹溾攢鈹€ common/ # 鉁?閫氱敤鑳藉姏灞傦紙宸插疄鐜帮級
|
||||
鈹? 鈹溾攢鈹€ llm/adapters/ # LLM閫傞厤鍣?鈹? 鈹? 鈹溾攢鈹€ DeepSeekAdapter.ts # 鉁?DeepSeek-V3
|
||||
鈹? 鈹? 鈹溾攢鈹€ QwenAdapter.ts # 鉁?Qwen3-72B
|
||||
鈹? 鈹? 鈹斺攢鈹€ LLMFactory.ts # 鉁?宸ュ巶绫?鈹? 鈹溾攢鈹€ rag/
|
||||
鈹? 鈹? 鈹斺攢鈹€ DifyClient.ts # 鉁?RAG瀹㈡埛绔?鈹? 鈹溾攢鈹€ document/
|
||||
鈹? 鈹? 鈹斺攢鈹€ ExtractionClient.ts # 鉁?鏂囨。鎻愬彇瀹㈡埛绔?鈹? 鈹溾攢鈹€ middleware/
|
||||
鈹? 鈹? 鈹斺攢鈹€ validateProject.ts # 鉁?楠岃瘉涓<E79889>棿浠?鈹? 鈹斺攢鈹€ utils/
|
||||
鈹? 鈹斺攢鈹€ jsonParser.ts # 鉁?JSON瑙f瀽宸ュ叿
|
||||
鈹?鈹斺攢鈹€ modules/ # 馃専 鏂版ā鍧楀紑鍙戝尯
|
||||
鈹斺攢鈹€ asl/ # 馃毀 ASL妯″潡锛堢┖鐩<E29496>綍锛學eek 3寮€鍙戯級
|
||||
└── (待创建)
|
||||
```
|
||||
鈹斺攢鈹€ 锛堝緟鍒涘缓锛?```
|
||||
|
||||
### Database Schema(已隔离)
|
||||
```
|
||||
### Database Schema锛堝凡闅旂<EFBFBD>锛?```
|
||||
PostgreSQL 15 + Prisma 6.17.0
|
||||
|
||||
✅ platform_schema - 用户表(users)
|
||||
✅ aia_schema - AI问答(projects, conversations, messages等)
|
||||
✅ pkb_schema - 知识库(knowledge_bases, documents, batch_tasks等)
|
||||
鉁?platform_schema - 鐢ㄦ埛琛<EFBFBD>紙users锛?鉁?aia_schema - AI闂<49>瓟锛坧rojects, conversations, messages绛夛級
|
||||
鉁?pkb_schema - 鐭ヨ瘑搴擄紙knowledge_bases, documents, batch_tasks绛夛級
|
||||
馃毀 asl_schema - AI鏅鸿兘鏂囩尞锛圵eek 3 瀹氫箟琛ㄧ粨鏋勶級
|
||||
📋 common_schema - 通用能力层(预留)
|
||||
📋 dc_schema - 数据清洗(预留)
|
||||
馃搵 common_schema - 閫氱敤鑳藉姏灞傦紙棰勭暀锛?馃搵 dc_schema - 鏁版嵁娓呮礂锛堥<E9949B>鐣欙級
|
||||
馃搵 rvw_schema - 绋夸欢瀹℃煡锛堥<E9949B>鐣欙級
|
||||
馃搵 admin_schema - 杩愯惀绠$悊锛堥<E9949B>鐣欙級
|
||||
馃搵 ssa_schema - 缁熻<E7BC81>鍒嗘瀽锛堥<E9949B>鐣欙級
|
||||
@@ -104,20 +78,9 @@ PostgreSQL 15 + Prisma 6.17.0
|
||||
## 馃幆 鎬讳綋鎴樼暐
|
||||
|
||||
```
|
||||
┌──────────────────────────────────────────────────────────────┐
|
||||
│ ASL 三阶段演进路线图 │
|
||||
├──────────────────────────────────────────────────────────────┤
|
||||
│ MVP (4周) V1.0 (6周) V2.0 (8周) │
|
||||
│ ├─ 基础可用 ├─ 高质量 ├─ 医学级 │
|
||||
│ ├─ 快速验证 ├─ 智能优化 ├─ 自动审计 │
|
||||
│ ├─ 成本优先 ├─ 质量提升 ├─ 完整追溯 │
|
||||
│ └─ 人工复核 └─ 规则验证 └─ HITL智能分流 │
|
||||
└──────────────────────────────────────────────────────────────┘
|
||||
|
||||
核心设计原则:
|
||||
1. 架构先行:在已完成的 Frontend-v2 和 Backend 架构基础上开发
|
||||
2. 分步实施:每阶段交付可用功能
|
||||
3. 质量可控:准确率从85% → 90% → 95%
|
||||
鈹屸攢鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹?鈹? ASL 涓夐樁娈垫紨杩涜矾绾垮浘 鈹?鈹溾攢鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹?鈹? MVP (4鍛? V1.0 (6鍛? V2.0 (8鍛? 鈹?鈹? 鈹溾攢 鍩虹<E98DA9>鍙<EFBFBD>敤 鈹溾攢 楂樿川閲? 鈹溾攢 鍖诲<E98D96>绾? 鈹?鈹? 鈹溾攢 蹇<>€熼獙璇? 鈹溾攢 鏅鸿兘浼樺寲 鈹溾攢 鑷<>姩瀹¤<E780B9> 鈹?鈹? 鈹溾攢 鎴愭湰浼樺厛 鈹溾攢 璐ㄩ噺鎻愬崌 鈹溾攢 瀹屾暣杩芥函 鈹?鈹? 鈹斺攢 浜哄伐澶嶆牳 鈹斺攢 瑙勫垯楠岃瘉 鈹斺攢 HITL鏅鸿兘鍒嗘祦 鈹?鈹斺攢鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹?
|
||||
鏍稿績璁捐<EFBFBD>鍘熷垯锛? 1. 鏋舵瀯鍏堣<E98D8F>锛氬湪宸插畬鎴愮殑 Frontend-v2 鍜?Backend 鏋舵瀯鍩虹<E98DA9>涓婂紑鍙? 2. 鍒嗘<E98D92>瀹炴柦锛氭瘡闃舵<E99783>浜や粯鍙<E7B2AF>敤鍔熻兘
|
||||
3. 璐ㄩ噺鍙<E599BA>帶锛氬噯纭<E599AF>巼浠?5% 鈫?90% 鈫?95%
|
||||
4. 鎴愭湰鍙<E6B9B0>帶锛氫紭鍏堜娇鐢―eepSeek+Qwen3锛屽彲鍒囨崲楂樼<E6A582>妯″瀷
|
||||
```
|
||||
|
||||
@@ -125,16 +88,16 @@ PostgreSQL 15 + Prisma 6.17.0
|
||||
|
||||
## 馃搳 涓夐樁娈甸噷绋嬬<E7BB8B>瀵规瘮
|
||||
|
||||
| 维度 | MVP (4周) | V1.0 (6周) | V2.0 (8周) |
|
||||
| 缁村害 | MVP (4鍛? | V1.0 (6鍛? | V2.0 (8鍛? |
|
||||
|------|----------|-----------|-----------|
|
||||
| **浜や粯鑼冨洿** | 鏍囬<E98F8D>鎽樿<E98EBD>鍒濈瓫 | + 鍏ㄦ枃澶嶇瓫 + PDF鎻愬彇 | + 鏁版嵁鎻愬彇 + 璐ㄩ噺瀹¤<E780B9> |
|
||||
| **准确率目标** | ≥ 85% | ≥ 90% | ≥ 95% |
|
||||
| **模型组合** | DeepSeek + Qwen3 | 成本优化策略 | 三模型仲裁 |
|
||||
| **质量控制** | 双模型验证 + JSON Schema | + Few-shot + 规则引擎 | + HITL + 自动审计 |
|
||||
| **可追溯性** | 基本日志 | 完整证据链 | 审计级记录 |
|
||||
| **前端** | 基础工作台(Frontend-v2) | 优化交互 | 完整UI |
|
||||
| **鍑嗙‘鐜囩洰鏍?* | 鈮?85% | 鈮?90% | 鈮?95% |
|
||||
| **妯″瀷缁勫悎** | DeepSeek + Qwen3 | 鎴愭湰浼樺寲绛栫暐 | 涓夋ā鍨嬩徊瑁?|
|
||||
| **璐ㄩ噺鎺у埗** | 鍙屾ā鍨嬮獙璇?+ JSON Schema | + Few-shot + 瑙勫垯寮曟搸 | + HITL + 鑷<EFBFBD>姩瀹¤<EFBFBD> |
|
||||
| **鍙<EFBFBD>拷婧<EFBFBD>€?* | 鍩烘湰鏃ュ織 | 瀹屾暣璇佹嵁閾?| 瀹¤<E780B9>绾ц<E7BBBE>褰?|
|
||||
| **鍓嶇<EFBFBD>** | 鍩虹<EFBFBD>宸ヤ綔鍙帮紙Frontend-v2锛?| 浼樺寲浜や簰 | 瀹屾暣UI |
|
||||
| **鍚庣<E98D9A>** | modules/asl/鏍稿績鍔熻兘 | + PDF鏈嶅姟闆嗘垚 | + 楂樼骇璐ㄩ噺淇濋殰 |
|
||||
| **成本/1000篇** | ¥5 | ¥21 | ¥24 + 仲裁 |
|
||||
| **鎴愭湰/1000绡?* | 楼5 | 楼21 | 楼24 + 浠茶<EFBFBD> |
|
||||
|
||||
---
|
||||
|
||||
@@ -142,28 +105,15 @@ PostgreSQL 15 + Prisma 6.17.0
|
||||
|
||||
### 闃舵<E99783>鐩<EFBFBD>爣
|
||||
|
||||
**交付标准**:
|
||||
- ✅ 标题摘要初筛功能完整可用
|
||||
- ✅ Excel 导入、AI 双模型筛选、人工复核
|
||||
- ✅ 准确率 ≥ 85%
|
||||
- ✅ 成本控制:≤ ¥50/1000 篇
|
||||
- ✅ 前端集成到 Frontend-v2 顶部导航
|
||||
- ✅ 后端 API 注册到 /api/v1/asl/*
|
||||
**浜や粯鏍囧噯**锛?- 鉁?鏍囬<E98F8D>鎽樿<E98EBD>鍒濈瓫鍔熻兘瀹屾暣鍙<E69AA3>敤
|
||||
- 鉁?Excel 瀵煎叆銆丄I 鍙屾ā鍨嬬瓫閫夈€佷汉宸ュ<E5AEB8>鏍?- 鉁?鍑嗙‘鐜?鈮?85%
|
||||
- 鉁?鎴愭湰鎺у埗锛氣墹 楼50/1000 绡?- 鉁?鍓嶇<E98D93>闆嗘垚鍒?Frontend-v2 椤堕儴瀵艰埅
|
||||
- 鉁?鍚庣<E98D9A> API 娉ㄥ唽鍒?/api/v1/asl/*
|
||||
|
||||
### 里程碑划分
|
||||
|
||||
#### **M1.1 - 数据库Schema设计**(Week 1, Day 1)
|
||||
|
||||
**任务**:
|
||||
- [ ] 设计 asl_schema 表结构(4张核心表)
|
||||
- `asl_screening_projects`(筛选项目表)
|
||||
- `asl_literatures`(文献条目表)
|
||||
- `asl_screening_results`(筛选结果表)
|
||||
- `asl_screening_tasks`(筛选任务表)
|
||||
- [ ] 在 `backend/prisma/schema.prisma` 中添加模型定义
|
||||
- 使用 `@@schema("asl_schema")` 指定Schema
|
||||
- 定义外键关系(引用 `platform_schema.users`)
|
||||
- **添加 OSS 相关字段**(支持云原生部署):
|
||||
### 閲岀▼纰戝垝鍒?
|
||||
#### **M1.1 - 鏁版嵁搴揝chema璁捐<E79281>**锛圵eek 1, Day 1锛?
|
||||
**浠诲姟**锛?- [ ] 璁捐<E79281> asl_schema 琛ㄧ粨鏋勶紙4寮犳牳蹇冭〃锛? - `asl_screening_projects`锛堢瓫閫夐」鐩<EFBFBD>〃锛? - `asl_literatures`锛堟枃鐚<EFBFBD>潯鐩<EFBFBD>〃锛? - `asl_screening_results`锛堢瓫閫夌粨鏋滆〃锛? - `asl_screening_tasks`锛堢瓫閫変换鍔¤〃锛?- [ ] 鍦?`backend/prisma/schema.prisma` 涓<>坊鍔犳ā鍨嬪畾涔? - 浣跨敤 `@@schema("asl_schema")` 鎸囧畾Schema
|
||||
- 瀹氫箟澶栭敭鍏崇郴锛堝紩鐢?`platform_schema.users`锛? - **娣诲姞 OSS 鐩稿叧瀛楁<E7809B>**锛堟敮鎸佷簯鍘熺敓閮ㄧ讲锛夛細
|
||||
- `pdfUrl` - PDF璁块棶URL
|
||||
- `pdfOssKey` - OSS瀛樺偍Key
|
||||
- `pdfFileSize` - 鏂囦欢澶у皬
|
||||
@@ -174,170 +124,129 @@ PostgreSQL 15 + Prisma 6.17.0
|
||||
npx prisma generate
|
||||
```
|
||||
|
||||
**交付物**:
|
||||
- ✅ asl_schema 表创建完成
|
||||
- ✅ Prisma Client 生成成功
|
||||
- ✅ 数据库迁移成功
|
||||
- ✅ OSS 字段预留完成
|
||||
**浜や粯鐗?*锛?- 鉁?asl_schema 琛ㄥ垱寤哄畬鎴?- 鉁?Prisma Client 鐢熸垚鎴愬姛
|
||||
- 鉁?鏁版嵁搴撹縼绉绘垚鍔?- 鉁?OSS 瀛楁<E7809B>棰勭暀瀹屾垚
|
||||
|
||||
---
|
||||
|
||||
#### **M1.2 - 后端API搭建**(Week 1, Day 2-3)
|
||||
|
||||
> **⭐ 前置条件(2025-11-17 更新)**:平台基础设施已完成实施 ✅
|
||||
> **完成状态**:8个核心模块,100%测试通过
|
||||
#### **M1.2 - 鍚庣<EFBFBD>API鎼<EFBFBD>缓**锛圵eek 1, Day 2-3锛?
|
||||
> **猸?鍓嶇疆鏉′欢锛?025-11-17 鏇存柊锛?*锛氬钩鍙板熀纭€璁炬柦宸插畬鎴愬疄鏂?鉁?
|
||||
> **瀹屾垚鐘舵€?*锛?涓<>牳蹇冩ā鍧楋紝100%娴嬭瘯閫氳繃
|
||||
> **瀹屾垚鎶ュ憡**锛歔骞冲彴鍩虹<E98DA9>璁炬柦瀹炴柦瀹屾垚鎶ュ憡](../../../08-椤圭洰绠$悊/03-姣忓懆璁″垝/2025-11-17-骞冲彴鍩虹<E98DA9>璁炬柦瀹炴柦瀹屾垚鎶ュ憡.md)
|
||||
> **浣跨敤鎸囧崡**锛歔backend/src/common/README.md](../../../../backend/src/common/README.md)
|
||||
|
||||
**平台已提供的8个核心模块(无需ASL模块实现)**:
|
||||
|
||||
**骞冲彴宸叉彁渚涚殑8涓<EFBFBD>牳蹇冩ā鍧楋紙鏃犻渶ASL妯″潡瀹炵幇锛?*锛?
|
||||
| # | 妯″潡 | 璺<>緞 | 浣跨敤鏂瑰紡 | 璇存槑 |
|
||||
|---|------|------|---------|------|
|
||||
| 1 | **存储服务** | `common/storage/` | `import { storage } from '@/common/storage'` | 文件上传下载(本地/OSS切换) |
|
||||
| 1 | **瀛樺偍鏈嶅姟** | `common/storage/` | `import { storage } from '@/common/storage'` | 鏂囦欢涓婁紶涓嬭浇锛堟湰鍦?OSS鍒囨崲锛?|
|
||||
| 2 | **鏃ュ織绯荤粺** | `common/logging/` | `import { logger } from '@/common/logging'` | 缁撴瀯鍖朖SON鏃ュ織 |
|
||||
| 3 | **缂撳瓨鏈嶅姟** | `common/cache/` | `import { cache } from '@/common/cache'` | 鍐呭瓨/Redis缂撳瓨 |
|
||||
| 4 | **异步任务** | `common/jobs/` | `import { jobQueue } from '@/common/jobs'` | 长时间任务处理 |
|
||||
| 5 | **健康检查** | `common/health/` | `import { registerHealthRoutes } from '@/common/health'` | SAE健康检查 |
|
||||
| 6 | **监控指标** | `common/monitoring/` | `import { Metrics } from '@/common/monitoring'` | 性能监控和告警 |
|
||||
| 4 | **寮傛<EFBFBD>浠诲姟** | `common/jobs/` | `import { jobQueue } from '@/common/jobs'` | 闀挎椂闂翠换鍔″<EFBFBD>鐞?|
|
||||
| 5 | **鍋ュ悍妫€鏌?* | `common/health/` | `import { registerHealthRoutes } from '@/common/health'` | SAE鍋ュ悍妫€鏌?|
|
||||
| 6 | **鐩戞帶鎸囨爣** | `common/monitoring/` | `import { Metrics } from '@/common/monitoring'` | 鎬ц兘鐩戞帶鍜屽憡璀?|
|
||||
| 7 | **鏁版嵁搴撹繛鎺ユ睜** | `config/database.ts` | `import { prisma } from '@/config/database'` | 鍏ㄥ眬Prisma瀹炰緥 |
|
||||
| 8 | **鐜<><E9909C>閰嶇疆** | `config/env.ts` | `import { env } from '@/config/env'` | 缁熶竴閰嶇疆绠$悊 |
|
||||
|
||||
**任务**:
|
||||
- [ ] 创建 `backend/src/modules/asl/` 目录结构
|
||||
**浠诲姟**锛?- [ ] 鍒涘缓 `backend/src/modules/asl/` 鐩<>綍缁撴瀯
|
||||
```
|
||||
modules/asl/
|
||||
鈹溾攢鈹€ routes/
|
||||
│ └── index.ts # 路由注册
|
||||
鈹? 鈹斺攢鈹€ index.ts # 璺<EFBFBD>敱娉ㄥ唽
|
||||
鈹溾攢鈹€ controllers/
|
||||
│ ├── projectController.ts # 项目控制器
|
||||
│ ├── literatureController.ts # 文献控制器
|
||||
│ └── screeningController.ts # 筛选控制器
|
||||
鈹? 鈹溾攢鈹€ projectController.ts # 椤圭洰鎺у埗鍣? 鈹? 鈹溾攢鈹€ literatureController.ts # 鏂囩尞鎺у埗鍣? 鈹? 鈹斺攢鈹€ screeningController.ts # 绛涢€夋帶鍒跺櫒
|
||||
鈹溾攢鈹€ services/
|
||||
│ ├── projectService.ts # 项目业务逻辑
|
||||
│ ├── literatureService.ts # 文献业务逻辑
|
||||
│ └── llmScreeningService.ts # LLM筛选服务
|
||||
├── schemas/
|
||||
│ └── screening.schema.ts # JSON Schema定义
|
||||
鈹? 鈹溾攢鈹€ projectService.ts # 椤圭洰涓氬姟閫昏緫
|
||||
鈹? 鈹溾攢鈹€ literatureService.ts # 鏂囩尞涓氬姟閫昏緫
|
||||
鈹? 鈹斺攢鈹€ llmScreeningService.ts # LLM绛涢€夋湇鍔? 鈹溾攢鈹€ schemas/
|
||||
鈹? 鈹斺攢鈹€ screening.schema.ts # JSON Schema瀹氫箟
|
||||
鈹斺攢鈹€ types/
|
||||
鈹斺攢鈹€ screening.types.ts # TypeScript绫诲瀷
|
||||
```
|
||||
- [ ] 在 `backend/src/index.ts` 中注册ASL路由
|
||||
- [ ] 鍦?`backend/src/index.ts` 涓<EFBFBD>敞鍐孉SL璺<EFBFBD>敱
|
||||
```typescript
|
||||
import { aslRoutes } from './modules/asl/routes/index.js'
|
||||
await app.register(aslRoutes, { prefix: '/api/v1/asl' })
|
||||
```
|
||||
- [ ] 实现核心API(参考 API设计规范文档)
|
||||
- `POST /api/v1/asl/projects` - 创建项目
|
||||
- [ ] 瀹炵幇鏍稿績API锛堝弬鑰?API璁捐<E79281>瑙勮寖鏂囨。锛? - `POST /api/v1/asl/projects` - 鍒涘缓椤圭洰
|
||||
- `POST /api/v1/asl/projects/:id/literatures/import` - 瀵煎叆鏂囩尞
|
||||
- `POST /api/v1/asl/projects/:id/screening/start` - 启动筛选
|
||||
- `GET /api/v1/asl/projects/:id/screening/results` - 获取结果
|
||||
- `POST /api/v1/asl/projects/:id/screening/start` - 鍚<EFBFBD>姩绛涢€? - `GET /api/v1/asl/projects/:id/screening/results` - 鑾峰彇缁撴灉
|
||||
- [ ] **閰嶇疆鐜<E79686><E9909C>鍙橀噺**
|
||||
```bash
|
||||
# .env.development锛堟湰鍦板紑鍙戯級
|
||||
STORAGE_TYPE=local
|
||||
|
||||
# .env.production(生产环境,SAE配置)
|
||||
STORAGE_TYPE=oss
|
||||
# .env.production锛堢敓浜х幆澧冿紝SAE閰嶇疆锛? STORAGE_TYPE=oss
|
||||
OSS_REGION=oss-cn-hangzhou
|
||||
OSS_BUCKET=aiclinical-prod
|
||||
```
|
||||
|
||||
**交付物**:
|
||||
- ✅ ASL后端目录结构完整
|
||||
- ✅ API路由注册成功
|
||||
- ✅ 核心API可调用(Postman测试通过)
|
||||
- ✅ 正常使用平台服务(storage/logger/cache/jobQueue/prisma等8个模块)
|
||||
**浜や粯鐗?*锛?- 鉁?ASL鍚庣<E98D9A>鐩<EFBFBD>綍缁撴瀯瀹屾暣
|
||||
- 鉁?API璺<49>敱娉ㄥ唽鎴愬姛
|
||||
- 鉁?鏍稿績API鍙<49>皟鐢<E79A9F>紙Postman娴嬭瘯閫氳繃锛?- 鉁?姝e父浣跨敤骞冲彴鏈嶅姟锛坰torage/logger/cache/jobQueue/prisma绛?涓<>ā鍧楋級
|
||||
|
||||
---
|
||||
|
||||
#### **M1.3 - LLM筛选核心**(Week 2, Day 1-2)
|
||||
|
||||
**任务**:
|
||||
- [ ] 实现双模型并行调用逻辑
|
||||
#### **M1.3 - LLM绛涢€夋牳蹇?*锛圵eek 2, Day 1-2锛?
|
||||
**浠诲姟**锛?- [ ] 瀹炵幇鍙屾ā鍨嬪苟琛岃皟鐢ㄩ€昏緫
|
||||
- 澶嶇敤 `common/llm/adapters/LLMFactory.ts`
|
||||
- 璋冪敤 DeepSeek-V3 + Qwen3-72B
|
||||
- [ ] 定义JSON Schema(PICO判断结构)
|
||||
- [ ] 设计提示词模板(v1.0.0)
|
||||
- 存放在 `backend/prompts/asl/screening/v1.0.0-basic.txt`
|
||||
- [ ] 实现冲突检测算法
|
||||
- [ ] 实现自动分流规则(置信度 < 0.7 → 人工复核)
|
||||
|
||||
**交付物**:
|
||||
- ✅ 双模型可成功调用
|
||||
- ✅ JSON Schema验证通过率 > 95%
|
||||
- ✅ 冲突检测准确
|
||||
|
||||
- [ ] 瀹氫箟JSON Schema锛圥ICO鍒ゆ柇缁撴瀯锛?- [ ] 璁捐<E79281>鎻愮ず璇嶆ā鏉匡紙v1.0.0锛? - 瀛樻斁鍦?`backend/prompts/asl/screening/v1.0.0-basic.txt`
|
||||
- [ ] 瀹炵幇鍐茬獊妫€娴嬬畻娉?- [ ] 瀹炵幇鑷<E5B987>姩鍒嗘祦瑙勫垯锛堢疆淇″害 < 0.7 鈫?浜哄伐澶嶆牳锛?
|
||||
**浜や粯鐗?*锛?- 鉁?鍙屾ā鍨嬪彲鎴愬姛璋冪敤
|
||||
- 鉁?JSON Schema楠岃瘉閫氳繃鐜?> 95%
|
||||
- 鉁?鍐茬獊妫€娴嬪噯纭?
|
||||
---
|
||||
|
||||
#### **M1.4 - 前端模块开发**(Week 2-3)
|
||||
|
||||
**任务**:
|
||||
- [ ] 更新 `frontend-v2/src/modules/asl/index.tsx`
|
||||
#### **M1.4 - 鍓嶇<EFBFBD>妯″潡寮€鍙?*锛圵eek 2-3锛?
|
||||
**浠诲姟**锛?- [ ] 鏇存柊 `frontend-v2/src/modules/asl/index.tsx`
|
||||
```typescript
|
||||
// 移除占位标记,实现真实模块
|
||||
const ASLModule: ModuleDefinition = {
|
||||
// 绉婚櫎鍗犱綅鏍囪<EFBFBD>锛屽疄鐜扮湡瀹炴ā鍧? const ASLModule: ModuleDefinition = {
|
||||
id: 'literature-platform',
|
||||
name: 'AI鏅鸿兘鏂囩尞',
|
||||
path: '/literature',
|
||||
icon: FileSearchOutlined,
|
||||
component: lazy(() => import('./routes')),
|
||||
placeholder: false, // ← 改为 false
|
||||
placeholder: false, // 鈫?鏀逛负 false
|
||||
requiredVersion: 'advanced',
|
||||
}
|
||||
```
|
||||
- [ ] 创建 `frontend-v2/src/modules/asl/` 子目录
|
||||
```
|
||||
- [ ] 鍒涘缓 `frontend-v2/src/modules/asl/` 瀛愮洰褰? ```
|
||||
asl/
|
||||
鈹溾攢鈹€ index.tsx # 妯″潡瀹氫箟
|
||||
鈹溾攢鈹€ routes.tsx # 璺<>敱閰嶇疆
|
||||
鈹溾攢鈹€ pages/
|
||||
│ ├── ProjectList.tsx # 项目列表
|
||||
│ ├── ScreeningSettings.tsx # 设置与启动
|
||||
│ ├── ScreeningWorkbench.tsx # 审核工作台
|
||||
│ └── ScreeningResults.tsx # 初筛结果
|
||||
鈹? 鈹溾攢鈹€ ProjectList.tsx # 椤圭洰鍒楄〃
|
||||
鈹? 鈹溾攢鈹€ ScreeningSettings.tsx # 璁剧疆涓庡惎鍔? 鈹? 鈹溾攢鈹€ ScreeningWorkbench.tsx # 瀹℃牳宸ヤ綔鍙? 鈹? 鈹斺攢鈹€ ScreeningResults.tsx # 鍒濈瓫缁撴灉
|
||||
鈹溾攢鈹€ components/
|
||||
│ ├── ExcelUploader.tsx # Excel上传
|
||||
│ ├── ScreeningTable.tsx # 筛选表格
|
||||
│ ├── DualModelModal.tsx # 双视图模态框
|
||||
│ └── ResultsExport.tsx # 结果导出
|
||||
鈹? 鈹溾攢鈹€ ExcelUploader.tsx # Excel涓婁紶
|
||||
鈹? 鈹溾攢鈹€ ScreeningTable.tsx # 绛涢€夎〃鏍? 鈹? 鈹溾攢鈹€ DualModelModal.tsx # 鍙岃<E98D99>鍥炬ā鎬佹<E98EAC>
|
||||
鈹? 鈹斺攢鈹€ ResultsExport.tsx # 缁撴灉瀵煎嚭
|
||||
鈹溾攢鈹€ api/
|
||||
│ ├── projectApi.ts # 项目API
|
||||
│ ├── screeningApi.ts # 筛选API
|
||||
│ └── index.ts
|
||||
鈹? 鈹溾攢鈹€ projectApi.ts # 椤圭洰API
|
||||
鈹? 鈹溾攢鈹€ screeningApi.ts # 绛涢€堿PI
|
||||
鈹? 鈹斺攢鈹€ index.ts
|
||||
鈹溾攢鈹€ hooks/
|
||||
│ ├── useScreening.ts # 筛选Hook
|
||||
│ └── useLiterature.ts # 文献Hook
|
||||
鈹? 鈹溾攢鈹€ useScreening.ts # 绛涢€塇ook
|
||||
鈹? 鈹斺攢鈹€ useLiterature.ts # 鏂囩尞Hook
|
||||
鈹斺攢鈹€ types/
|
||||
鈹斺攢鈹€ screening.ts # 绫诲瀷瀹氫箟
|
||||
```
|
||||
- [ ] 实现Excel上传功能(使用 `xlsx` 库)
|
||||
- [ ] 实现审核工作台(表格化布局,参考原型图)
|
||||
- [ ] 实现双视图原文审查模态框
|
||||
- [ ] 实现结果展示和导出
|
||||
|
||||
**交付物**:
|
||||
- ✅ ASL模块在顶部导航显示并可点击
|
||||
- ✅ 前端3个主要页面完整
|
||||
- ✅ 前后端联调成功
|
||||
|
||||
- [ ] 瀹炵幇Excel涓婁紶鍔熻兘锛堜娇鐢?`xlsx` 搴擄級
|
||||
- [ ] 瀹炵幇瀹℃牳宸ヤ綔鍙帮紙琛ㄦ牸鍖栧竷灞€锛屽弬鑰冨師鍨嬪浘锛?- [ ] 瀹炵幇鍙岃<E98D99>鍥惧師鏂囧<E98F82>鏌ユā鎬佹<E98EAC>
|
||||
- [ ] 瀹炵幇缁撴灉灞曠ず鍜屽<EFBFBD>鍑?
|
||||
**浜や粯鐗?*锛?- 鉁?ASL妯″潡鍦ㄩ《閮ㄥ<E996AE>鑸<EFBFBD>樉绀哄苟鍙<E88B9F>偣鍑?- 鉁?鍓嶇<E98D93>3涓<33>富瑕侀〉闈㈠畬鏁?- 鉁?鍓嶅悗绔<E68297>仈璋冩垚鍔?
|
||||
---
|
||||
|
||||
#### **M1.5 - 集成测试与验收**(Week 4)
|
||||
|
||||
**任务**:
|
||||
- [ ] 端到端完整流程测试
|
||||
- 上传 199篇文献 Excel → 筛选 → 复核 → 导出
|
||||
- [ ] 准确率测试(使用金标准数据集)
|
||||
- 目标:≥ 85%
|
||||
#### **M1.5 - 闆嗘垚娴嬭瘯涓庨獙鏀?*锛圵eek 4锛?
|
||||
**浠诲姟**锛?- [ ] 绔<>埌绔<E59F8C>畬鏁存祦绋嬫祴璇? - 涓婁紶 199绡囨枃鐚?Excel 鈫?绛涢€?鈫?澶嶆牳 鈫?瀵煎嚭
|
||||
- [ ] 鍑嗙‘鐜囨祴璇曪紙浣跨敤閲戞爣鍑嗘暟鎹<E69A9F>泦锛? - 鐩<>爣锛氣墺 85%
|
||||
- [ ] 鎬ц兘娴嬭瘯
|
||||
- 100篇文献筛选 ≤ 10分钟
|
||||
- [ ] 修复Bug和优化
|
||||
|
||||
**交付物**:
|
||||
- ✅ 准确率 ≥ 85%
|
||||
- ✅ 双模型一致率 ≥ 80%
|
||||
- ✅ JSON Schema验证通过率 ≥ 95%
|
||||
- ✅ 人工复核队列 ≤ 20%
|
||||
- 100绡囨枃鐚<EFBFBD>瓫閫?鈮?10鍒嗛挓
|
||||
- [ ] 淇<EFBFBD><EFBFBD>Bug鍜屼紭鍖?
|
||||
**浜や粯鐗?*锛?- 鉁?鍑嗙‘鐜?鈮?85%
|
||||
- 鉁?鍙屾ā鍨嬩竴鑷寸巼 鈮?80%
|
||||
- 鉁?JSON Schema楠岃瘉閫氳繃鐜?鈮?95%
|
||||
- 鉁?浜哄伐澶嶆牳闃熷垪 鈮?20%
|
||||
|
||||
---
|
||||
|
||||
@@ -345,72 +254,47 @@ PostgreSQL 15 + Prisma 6.17.0
|
||||
|
||||
### 闃舵<E99783>鐩<EFBFBD>爣
|
||||
|
||||
**交付标准**:
|
||||
- ✅ 新增全文复筛功能
|
||||
- ✅ PDF 提取集成(Nougat + PyMuPDF)
|
||||
- ✅ Unpaywall API 集成(自动下载全文)
|
||||
- ✅ Few-shot 示例库
|
||||
- ✅ 规则引擎验证
|
||||
- ✅ 准确率 ≥ 90%
|
||||
**浜や粯鏍囧噯**锛?- 鉁?鏂板<E98F82>鍏ㄦ枃澶嶇瓫鍔熻兘
|
||||
- 鉁?PDF 鎻愬彇闆嗘垚锛圢ougat + PyMuPDF锛?- 鉁?Unpaywall API 闆嗘垚锛堣嚜鍔ㄤ笅杞藉叏鏂囷級
|
||||
- 鉁?Few-shot 绀轰緥搴?- 鉁?瑙勫垯寮曟搸楠岃瘉
|
||||
- 鉁?鍑嗙‘鐜?鈮?90%
|
||||
|
||||
### 里程碑划分
|
||||
### 閲岀▼纰戝垝鍒?
|
||||
#### **M2.1 - PDF 鎻愬彇鏈嶅姟闆嗘垚**锛圵eek 5锛?
|
||||
**浠诲姟**锛?- [ ] 灏佽<E7818F> `ExtractionClient`锛堝凡鏈?`common/document/ExtractionClient.ts`锛岄渶浼樺寲锛?- [ ] 瀹炵幇鑷<E5B987>姩璇<E5A7A9>█妫€娴嬪拰绛栫暐閫夋嫨
|
||||
- [ ] Python 寰<>湇鍔′紭鍖栵紙`extraction_service/`锛? - 浼樺寲 Nougat 璋冪敤鎬ц兘
|
||||
- 娣诲姞瓒呮椂鍜岄敊璇<E6958A><E79287>鐞?- [ ] 瀹炵幇 PDF 璐ㄩ噺璇勪及閫昏緫
|
||||
|
||||
#### **M2.1 - PDF 提取服务集成**(Week 5)
|
||||
|
||||
**任务**:
|
||||
- [ ] 封装 `ExtractionClient`(已有 `common/document/ExtractionClient.ts`,需优化)
|
||||
- [ ] 实现自动语言检测和策略选择
|
||||
- [ ] Python 微服务优化(`extraction_service/`)
|
||||
- 优化 Nougat 调用性能
|
||||
- 添加超时和错误处理
|
||||
- [ ] 实现 PDF 质量评估逻辑
|
||||
|
||||
**交付物**:
|
||||
- ✅ 可成功提取英文医学PDF(10-30页)
|
||||
- ✅ 提取准确率 > 90%
|
||||
**浜や粯鐗?*锛?- 鉁?鍙<>垚鍔熸彁鍙栬嫳鏂囧尰瀛<E5B0B0>DF锛?0-30椤碉級
|
||||
- 鉁?鎻愬彇鍑嗙‘鐜?> 90%
|
||||
|
||||
---
|
||||
|
||||
#### **M2.2 - Unpaywall API 集成**(Week 5)
|
||||
|
||||
**任务**:
|
||||
- [ ] 创建 `backend/src/common/literature/UnpaywallClient.ts`
|
||||
- [ ] 实现批量查询 DOI 可下载性
|
||||
- [ ] 实现 PDF 下载功能
|
||||
#### **M2.2 - Unpaywall API 闆嗘垚**锛圵eek 5锛?
|
||||
**浠诲姟**锛?- [ ] 鍒涘缓 `backend/src/common/literature/UnpaywallClient.ts`
|
||||
- [ ] 瀹炵幇鎵归噺鏌ヨ<E98F8C> DOI 鍙<>笅杞芥€?- [ ] 瀹炵幇 PDF 涓嬭浇鍔熻兘
|
||||
- [ ] 鏂囦欢瀛樺偍绠$悊
|
||||
|
||||
**交付物**:
|
||||
- ✅ 用户可一键检查 100 篇文献的可下载性
|
||||
- ✅ 可自动下载 OA 全文
|
||||
**浜や粯鐗?*锛?- 鉁?鐢ㄦ埛鍙<E59F9B>竴閿<E7ABB4><E996BF>鏌?100 绡囨枃鐚<E69E83>殑鍙<E6AE91>笅杞芥€?- 鉁?鍙<>嚜鍔ㄤ笅杞?OA 鍏ㄦ枃
|
||||
|
||||
---
|
||||
|
||||
#### **M2.3 - 全文复筛功能**(Week 6-7)
|
||||
|
||||
**任务**:
|
||||
- [ ] 扩展数据库表(`asl_full_text_screening_results`)
|
||||
- [ ] 后端全文复筛API
|
||||
#### **M2.3 - 鍏ㄦ枃澶嶇瓫鍔熻兘**锛圵eek 6-7锛?
|
||||
**浠诲姟**锛?- [ ] 鎵╁睍鏁版嵁搴撹〃锛坄asl_full_text_screening_results`锛?- [ ] 鍚庣<E98D9A>鍏ㄦ枃澶嶇瓫API
|
||||
- [ ] 鍓嶇<E98D93>鍏ㄦ枃瀹℃牳宸ヤ綔鍙帮紙澶嶇敤缁勪欢 + PDF鏌ョ湅鍣<E6B985>級
|
||||
|
||||
**交付物**:
|
||||
- ✅ 用户可对初筛纳入文献进行全文复筛
|
||||
- ✅ 支持 PDF 在线查看和标注
|
||||
|
||||
**浜や粯鐗?*锛?- 鉁?鐢ㄦ埛鍙<E59F9B><E98D99>鍒濈瓫绾冲叆鏂囩尞杩涜<E69DA9>鍏ㄦ枃澶嶇瓫
|
||||
- 鉁?鏀<>寔 PDF 鍦ㄧ嚎鏌ョ湅鍜屾爣娉?
|
||||
---
|
||||
|
||||
#### **M2.4 - 质量增强功能**(Week 8-10)
|
||||
|
||||
**任务**:
|
||||
- [ ] 人工标注 20-30 个 Few-shot 示例
|
||||
#### **M2.4 - 璐ㄩ噺澧炲己鍔熻兘**锛圵eek 8-10锛?
|
||||
**浠诲姟**锛?- [ ] 浜哄伐鏍囨敞 20-30 涓?Few-shot 绀轰緥
|
||||
- [ ] 瀹氫箟楠岃瘉瑙勫垯锛堟牱鏈<E789B1>噺銆丳鍊笺€佸繀濉<E7B980>瓧娈碉級
|
||||
- [ ] 实现成本优化策略(快速初筛 + 高价值复核)
|
||||
- [ ] 完善证据链记录
|
||||
|
||||
**交付物**:
|
||||
- ✅ Few-shot 示例库 ≥ 20 个
|
||||
- ✅ 规则引擎覆盖率 ≥ 80%
|
||||
- ✅ 证据链完整性 100%
|
||||
- ✅ 准确率 ≥ 90%
|
||||
- [ ] 瀹炵幇鎴愭湰浼樺寲绛栫暐锛堝揩閫熷垵绛?+ 楂樹环鍊煎<E98D8A>鏍革級
|
||||
- [ ] 瀹屽杽璇佹嵁閾捐<E996BE>褰?
|
||||
**浜や粯鐗?*锛?- 鉁?Few-shot 绀轰緥搴?鈮?20 涓?- 鉁?瑙勫垯寮曟搸瑕嗙洊鐜?鈮?80%
|
||||
- 鉁?璇佹嵁閾惧畬鏁存€?100%
|
||||
- 鉁?鍑嗙‘鐜?鈮?90%
|
||||
|
||||
---
|
||||
|
||||
@@ -418,82 +302,57 @@ PostgreSQL 15 + Prisma 6.17.0
|
||||
|
||||
### 闃舵<E99783>鐩<EFBFBD>爣
|
||||
|
||||
**交付标准**:
|
||||
- ✅ 新增全文数据提取功能
|
||||
- ✅ 三模型共识仲裁
|
||||
- ✅ HITL 智能分流
|
||||
- ✅ 提示词版本管理
|
||||
- ✅ 自动质量审计
|
||||
- ✅ 准确率 ≥ 95%(医学级)
|
||||
|
||||
### 里程碑划分
|
||||
|
||||
#### **M3.1 - 全文数据提取模块**(Week 11-13)
|
||||
|
||||
**任务**:
|
||||
- [ ] 扩展数据库表(`asl_extraction_results`, `asl_extraction_revisions`)
|
||||
- [ ] 后端分段提取逻辑
|
||||
**浜や粯鏍囧噯**锛?- 鉁?鏂板<E98F82>鍏ㄦ枃鏁版嵁鎻愬彇鍔熻兘
|
||||
- 鉁?涓夋ā鍨嬪叡璇嗕徊瑁?- 鉁?HITL 鏅鸿兘鍒嗘祦
|
||||
- 鉁?鎻愮ず璇嶇増鏈<E5A297><E98F88>鐞?- 鉁?鑷<>姩璐ㄩ噺瀹¤<E780B9>
|
||||
- 鉁?鍑嗙‘鐜?鈮?95%锛堝尰瀛︾骇锛?
|
||||
### 閲岀▼纰戝垝鍒?
|
||||
#### **M3.1 - 鍏ㄦ枃鏁版嵁鎻愬彇妯″潡**锛圵eek 11-13锛?
|
||||
**浠诲姟**锛?- [ ] 鎵╁睍鏁版嵁搴撹〃锛坄asl_extraction_results`, `asl_extraction_revisions`锛?- [ ] 鍚庣<E98D9A>鍒嗘<E98D92>鎻愬彇閫昏緫
|
||||
- [ ] 鍓嶇<E98D93>琛ㄦ牸鍖栨暟鎹<E69A9F><E98EB9>鏌ュ彴锛堟枃鐚<E69E83>楀彉閲忕煩闃碉級
|
||||
|
||||
**交付物**:
|
||||
- ✅ 用户可配置提取变量清单
|
||||
- ✅ 批量提取 50 篇文献的结构化数据
|
||||
- ✅ 提取准确率 ≥ 92%
|
||||
**浜や粯鐗?*锛?- 鉁?鐢ㄦ埛鍙<E59F9B>厤缃<E58EA4>彁鍙栧彉閲忔竻鍗?- 鉁?鎵归噺鎻愬彇 50 绡囨枃鐚<E69E83>殑缁撴瀯鍖栨暟鎹?- 鉁?鎻愬彇鍑嗙‘鐜?鈮?92%
|
||||
|
||||
---
|
||||
|
||||
#### **M3.2 - 医学级质量保障**(Week 14-16)
|
||||
|
||||
**任务**:
|
||||
- [ ] 三模型仲裁(冲突 → 启用 Claude-4.5)
|
||||
- [ ] HITL 智能分流(优先级评分)
|
||||
- [ ] 提示词版本管理(Git + 语义化版本)
|
||||
#### **M3.2 - 鍖诲<EFBFBD>绾ц川閲忎繚闅?*锛圵eek 14-16锛?
|
||||
**浠诲姟**锛?- [ ] 涓夋ā鍨嬩徊瑁侊紙鍐茬獊 鈫?鍚<>敤 Claude-4.5锛?- [ ] HITL 鏅鸿兘鍒嗘祦锛堜紭鍏堢骇璇勫垎锛?- [ ] 鎻愮ず璇嶇増鏈<E5A297><E98F88>鐞嗭紙Git + 璇<>箟鍖栫増鏈<E5A297>級
|
||||
- [ ] 鑷<>姩璐ㄩ噺瀹¤<E780B9>绯荤粺
|
||||
|
||||
**交付物**:
|
||||
- ✅ 三模型仲裁成功率 > 95%
|
||||
- ✅ HITL 分流准确率 > 85%
|
||||
- ✅ 提示词版本管理系统上线
|
||||
- ✅ 自动质量审计每周运行
|
||||
**浜や粯鐗?*锛?- 鉁?涓夋ā鍨嬩徊瑁佹垚鍔熺巼 > 95%
|
||||
- 鉁?HITL 鍒嗘祦鍑嗙‘鐜?> 85%
|
||||
- 鉁?鎻愮ず璇嶇増鏈<E5A297><E98F88>鐞嗙郴缁熶笂绾?- 鉁?鑷<>姩璐ㄩ噺瀹¤<E780B9>姣忓懆杩愯<E69DA9>
|
||||
|
||||
---
|
||||
|
||||
#### **M3.3 - 高级功能与优化**(Week 17-18)
|
||||
|
||||
**任务**:
|
||||
- [ ] Chain of Thought (CoT) 推理
|
||||
- [ ] 动态示例选择(语义相似度)
|
||||
- [ ] 批处理性能优化(Bull + Redis)
|
||||
- [ ] 用户体验优化(实时进度、PDF标注、快捷键)
|
||||
|
||||
**交付物**:
|
||||
- ✅ 系统稳定性测试通过
|
||||
- ✅ 性能测试:1000 篇文献 < 30 分钟
|
||||
- ✅ 用户验收测试通过
|
||||
- ✅ 准确率 ≥ 95%
|
||||
#### **M3.3 - 楂樼骇鍔熻兘涓庝紭鍖?*锛圵eek 17-18锛?
|
||||
**浠诲姟**锛?- [ ] Chain of Thought (CoT) 鎺ㄧ悊
|
||||
- [ ] 鍔ㄦ€佺ず渚嬮€夋嫨锛堣<E9949B>涔夌浉浼煎害锛?- [ ] 鎵瑰<E98EB5>鐞嗘€ц兘浼樺寲锛圔ull + Redis锛?- [ ] 鐢ㄦ埛浣撻獙浼樺寲锛堝疄鏃惰繘搴︺€丳DF鏍囨敞銆佸揩鎹烽敭锛?
|
||||
**浜や粯鐗?*锛?- 鉁?绯荤粺绋冲畾鎬ф祴璇曢€氳繃
|
||||
- 鉁?鎬ц兘娴嬭瘯锛?000 绡囨枃鐚?< 30 鍒嗛挓
|
||||
- 鉁?鐢ㄦ埛楠屾敹娴嬭瘯閫氳繃
|
||||
- 鉁?鍑嗙‘鐜?鈮?95%
|
||||
|
||||
---
|
||||
|
||||
## 📋 交付物检查清单
|
||||
|
||||
## 馃搵 浜や粯鐗╂<E99097>鏌ユ竻鍗?
|
||||
### MVP 闃舵<E99783>
|
||||
|
||||
- [ ] **数据库**
|
||||
- [ ] **鏁版嵁搴?*
|
||||
- [ ] asl_schema 4寮犺〃鍒涘缓
|
||||
- [ ] Prisma 杩佺Щ鎴愬姛
|
||||
|
||||
- [ ] **鍚庣<E98D9A>**
|
||||
- [ ] `modules/asl/` 鐩<>綍缁撴瀯瀹屾暣
|
||||
- [ ] API 路由注册到 `/api/v1/asl/*`
|
||||
- [ ] LLM筛选服务可用
|
||||
|
||||
- [ ] API 璺<EFBFBD>敱娉ㄥ唽鍒?`/api/v1/asl/*`
|
||||
- [ ] LLM绛涢€夋湇鍔″彲鐢?
|
||||
- [ ] **鍓嶇<E98D93>**
|
||||
- [ ] ASL模块注册到 `moduleRegistry.ts`
|
||||
- [ ] ASL妯″潡娉ㄥ唽鍒?`moduleRegistry.ts`
|
||||
- [ ] 椤堕儴瀵艰埅鏄剧ず"AI鏅鸿兘鏂囩尞"
|
||||
- [ ] 3涓<33>富椤甸潰瀹屾暣
|
||||
|
||||
- [ ] **娴嬭瘯**
|
||||
- [ ] 准确率测试 ≥ 85%
|
||||
- [ ] 鍑嗙‘鐜囨祴璇?鈮?85%
|
||||
- [ ] 绔<>埌绔<E59F8C>祴璇曢€氳繃
|
||||
|
||||
### V1.0 闃舵<E99783>
|
||||
@@ -502,21 +361,19 @@ PostgreSQL 15 + Prisma 6.17.0
|
||||
- [ ] PDF 鎻愬彇鏈嶅姟
|
||||
- [ ] Unpaywall API 闆嗘垚
|
||||
- [ ] 鍏ㄦ枃澶嶇瓫
|
||||
- [ ] Few-shot 示例库
|
||||
|
||||
- [ ] Few-shot 绀轰緥搴?
|
||||
- [ ] **娴嬭瘯**
|
||||
- [ ] 准确率 ≥ 90%
|
||||
- [ ] 鍑嗙‘鐜?鈮?90%
|
||||
|
||||
### V2.0 闃舵<E99783>
|
||||
|
||||
- [ ] **鏂板<E98F82>鍔熻兘**
|
||||
- [ ] 鍏ㄦ枃鏁版嵁鎻愬彇
|
||||
- [ ] 三模型仲裁
|
||||
- [ ] HITL 智能分流
|
||||
- [ ] 涓夋ā鍨嬩徊瑁? - [ ] HITL 鏅鸿兘鍒嗘祦
|
||||
- [ ] 鑷<>姩璐ㄩ噺瀹¤<E780B9>
|
||||
|
||||
- [ ] **娴嬭瘯**
|
||||
- [ ] 准确率 ≥ 95%
|
||||
- [ ] 鍑嗙‘鐜?鈮?95%
|
||||
- [ ] 鍖诲<E98D96>涓撳<E6B693>楠岃瘉
|
||||
|
||||
---
|
||||
@@ -527,34 +384,32 @@ PostgreSQL 15 + Prisma 6.17.0
|
||||
|
||||
| 鎸囨爣 | MVP 鐩<>爣 | V1.0 鐩<>爣 | V2.0 鐩<>爣 |
|
||||
|------|---------|----------|----------|
|
||||
| 提取准确率 | ≥ 85% | ≥ 90% | ≥ 95% |
|
||||
| 双模型一致率 | ≥ 80% | ≥ 85% | ≥ 90% |
|
||||
| JSON Schema 验证通过率 | ≥ 95% | ≥ 98% | ≥ 99% |
|
||||
| 人工复核队列占比 | ≤ 20% | ≤ 15% | ≤ 10% |
|
||||
| 鎻愬彇鍑嗙‘鐜?| 鈮?85% | 鈮?90% | 鈮?95% |
|
||||
| 鍙屾ā鍨嬩竴鑷寸巼 | 鈮?80% | 鈮?85% | 鈮?90% |
|
||||
| JSON Schema 楠岃瘉閫氳繃鐜?| 鈮?95% | 鈮?98% | 鈮?99% |
|
||||
| 浜哄伐澶嶆牳闃熷垪鍗犳瘮 | 鈮?20% | 鈮?15% | 鈮?10% |
|
||||
|
||||
### 鎴愭湰鎸囨爣
|
||||
|
||||
| 鍦烘櫙 | MVP | V1.0 | V2.0 |
|
||||
|------|-----|------|------|
|
||||
| 鏍囬<E98F8D>鎽樿<E98EBD>绛涢€夛紙1000绡囷級 | 楼5 | 楼21 | 楼24 |
|
||||
| 全文复筛(200篇) | - | ¥30 | ¥35 |
|
||||
| 数据提取(50篇) | - | ¥60 | ¥80 |
|
||||
| 鍏ㄦ枃澶嶇瓫锛?00绡囷級 | - | 楼30 | 楼35 |
|
||||
| 鏁版嵁鎻愬彇锛?0绡囷級 | - | 楼60 | 楼80 |
|
||||
|
||||
---
|
||||
|
||||
## 馃摎 鐩稿叧鏂囨。
|
||||
|
||||
- [质量保障与可追溯策略](../02-技术设计/06-质量保障与可追溯策略.md)
|
||||
- [文献处理技术选型](../02-技术设计/07-文献处理技术选型.md)
|
||||
- [数据库设计](../02-技术设计/01-数据库设计.md)
|
||||
- [API 设计规范](../02-技术设计/02-API设计规范.md)
|
||||
- [璐ㄩ噺淇濋殰涓庡彲杩芥函绛栫暐](../02-鎶€鏈<E282AC><E98F88>璁?06-璐ㄩ噺淇濋殰涓庡彲杩芥函绛栫暐.md)
|
||||
- [鏂囩尞澶勭悊鎶€鏈<EFBFBD>€夊瀷](../02-鎶€鏈<E282AC><E98F88>璁?07-鏂囩尞澶勭悊鎶€鏈<E282AC>€夊瀷.md)
|
||||
- [鏁版嵁搴撹<EFBFBD>璁<EFBFBD>(../02-鎶€鏈<E282AC><E98F88>璁?01-鏁版嵁搴撹<E690B4>璁?md)
|
||||
- [API 璁捐<EFBFBD>瑙勮寖](../02-鎶€鏈<EFBFBD><EFBFBD>璁?02-API璁捐<E79281>瑙勮寖.md)
|
||||
- [鍓嶅悗绔<EFBFBD>ā鍧楀寲鏋舵瀯璁捐<EFBFBD>-V2](../../../00-绯荤粺鎬讳綋璁捐<E79281>/鍓嶅悗绔<E68297>ā鍧楀寲鏋舵瀯璁捐<E79281>-V2.md)
|
||||
- [Schema隔离架构设计](../../../09-架构实施/01-Schema隔离架构设计(10个).md)
|
||||
- [Schema闅旂<EFBFBD>鏋舵瀯璁捐<EFBFBD>](../../../09-鏋舵瀯瀹炴柦/01-Schema闅旂<EFBFBD>鏋舵瀯璁捐<EFBFBD>锛?0涓<30>級.md)
|
||||
|
||||
---
|
||||
|
||||
**更新日志**:
|
||||
- 2025-11-18: V3.1 更新,补充平台基础设施完成状态(8个核心模块)
|
||||
- 2025-11-16: V3.0 重写,基于真实架构(Frontend-v2 + Backend增量演进 + 10个Schema)
|
||||
- 2025-11-16: V2.0 重写,基于三阶段路线图详细规划里程碑
|
||||
- 2025-10-29: V1.0 创建,初始版本
|
||||
**鏇存柊鏃ュ織**锛?- 2025-11-18: V3.1 鏇存柊锛岃ˉ鍏呭钩鍙板熀纭€璁炬柦瀹屾垚鐘舵€侊紙8涓<38>牳蹇冩ā鍧楋級
|
||||
- 2025-11-16: V3.0 閲嶅啓锛屽熀浜庣湡瀹炴灦鏋勶紙Frontend-v2 + Backend澧為噺婕旇繘 + 10涓猄chema锛?- 2025-11-16: V2.0 閲嶅啓锛屽熀浜庝笁闃舵<E99783>璺<EFBFBD>嚎鍥捐<E98DA5>缁嗚<E7BC81>鍒掗噷绋嬬<E7BB8B>
|
||||
- 2025-10-29: V1.0 鍒涘缓锛屽垵濮嬬増鏈?
|
||||
@@ -1,65 +1,52 @@
|
||||
# 标题摘要初筛模块 - 详细开发计划(MVP阶段)
|
||||
|
||||
> **文档版本:** V3.0
|
||||
> **创建日期:** 2025-11-16
|
||||
> **开发周期:** 4 周
|
||||
> **负责团队:** ASL 开发组
|
||||
# æ ‡é¢˜æ‘˜è¦<EFBFBD>åˆ<EFBFBD>ç›æ¨¡å<EFBFBD>— - 详细开å<E282AC>‘计划(MVP阶段ï¼?
|
||||
> **文档版本�* V3.0
|
||||
> **创建日期�* 2025-11-16
|
||||
> **å¼€å<EFBFBD>‘周期:** 4 å‘?
|
||||
> **负责团队ï¼?* ASL å¼€å<E282AC>‘组
|
||||
> **最å<E282AC>Žæ›´æ–°ï¼š** 2025-11-16
|
||||
> **⭐ 重要:基于真实架构(Frontend-v2 + Backend增量演进 + asl_schema)**
|
||||
> **â?é‡<C3A9>è¦<C3A8>:基于真实架构(Frontend-v2 + Backend增é‡<EFBFBD>演进 + asl_schemaï¼?*
|
||||
|
||||
---
|
||||
|
||||
## 📋 模å<C2A1>—概述
|
||||
|
||||
标题摘要初筛是 ASL 模块的第一个核心功能,也是 MVP 阶段的唯一交付功能。
|
||||
|
||||
æ ‡é¢˜æ‘˜è¦<EFBFBD>åˆ<EFBFBD>ç›æ˜?ASL 模å<C2A1>—çš„ç¬¬ä¸€ä¸ªæ ¸å¿ƒåŠŸèƒ½ï¼Œä¹Ÿæ˜¯ MVP 阶段的唯一交付功能ã€?
|
||||
### 功能范围
|
||||
|
||||
1. **设置与启动视图**:PICO 标准展示、Excel 文献导入、启动筛选任务
|
||||
2. **审核工作台视图**:双模型判断对比、冲突标记、人工复核
|
||||
3. **初筛结果视图**:统计概览、PRISMA 排除总结、结果导出
|
||||
|
||||
1. **设置与å<EFBFBD>¯åŠ¨è§†å›?*:PICO æ ‡å‡†å±•ç¤ºã€<C3A3>Excel 文献导入ã€<C3A3>å<EFBFBD>¯åЍç›é€‰ä»»åŠ?2. **å®¡æ ¸å·¥ä½œå<C593>°è§†å›?*:å<C5A1>Œæ¨¡åž‹åˆ¤æ–对比ã€<C3A3>冲çª<C3A7>æ ‡è®°ã€<C3A3>人工å¤<C3A5>æ ?3. **åˆ<C3A5>ç›ç»“果视图**:统计概览ã€<C3A3>PRISMA 排除总结ã€<C3A3>结果导å‡?
|
||||
### æŠ€æœ¯æ ˆ
|
||||
|
||||
| 层级 | 技术 | 说明 |
|
||||
| 层级 | 技�| 说明 |
|
||||
|------|------|------|
|
||||
| **å‰<C3A5>端** | React 19 + TypeScript + Ant Design 5 + xlsx | Frontend-v2æž¶æž„ |
|
||||
| **å<>Žç«¯** | Node.js + Fastify + TypeScript + Prisma | Backend/modules/asl/ |
|
||||
| **LLM** | DeepSeek-V3 + Qwen3-72B | å¤<C3A5>用 common/llm/adapters/ |
|
||||
| **数据库** | PostgreSQL 15 (asl_schema) | Schema隔离 |
|
||||
| **æ•°æ<EFBFBD>®åº?* | PostgreSQL 15 (asl_schema) | Schema隔离 |
|
||||
|
||||
---
|
||||
|
||||
## 🏗️ 架构前提(已完成)
|
||||
|
||||
### ✅ Frontend-v2 架构(Week 2 Day 6-7 完成)
|
||||
```
|
||||
## ðŸ<EFBFBD>—ï¸?æž¶æž„å‰<C3A5>æ<EFBFBD><C3A6>(已完æˆ<C3A6>ï¼?
|
||||
### âœ?Frontend-v2 架构(Week 2 Day 6-7 完æˆ<C3A6>ï¼?```
|
||||
frontend-v2/src/
|
||||
├── framework/layout/
|
||||
│ ├── MainLayout.tsx # ✅ 顶部导航布局
|
||||
│ └── TopNavigation.tsx # ✅ 6个模块导航
|
||||
├── framework/modules/
|
||||
│ ├── moduleRegistry.ts # ✅ 模块注册中心
|
||||
│ └── types.ts # ✅ ModuleDefinition接口
|
||||
� ├── MainLayout.tsx # �顶部导航布局
|
||||
â”? └── TopNavigation.tsx # âœ?6个模å<C2A1>—导èˆ?├── framework/modules/
|
||||
â”? ├── moduleRegistry.ts # âœ?模å<C2A1>—注册ä¸å¿ƒ
|
||||
â”? └── types.ts # âœ?ModuleDefinition接å<C2A5>£
|
||||
└── modules/asl/
|
||||
└── index.tsx # 🚧 占位页面(待替换)
|
||||
```
|
||||
└── index.tsx # 🚧 å<> ä½<C3A4>页é<C2B5>¢ï¼ˆå¾…替æ<C2BF>¢ï¼?```
|
||||
|
||||
### ✅ Backend 架构(Week 2 Day 8-9 完成)
|
||||
```
|
||||
### âœ?Backend 架构(Week 2 Day 8-9 完æˆ<EFBFBD>ï¼?```
|
||||
backend/src/
|
||||
├── common/llm/adapters/ # ✅ LLMFactory可复用
|
||||
├── common/utils/jsonParser.js # ✅ JSON解析可复用
|
||||
└── modules/
|
||||
├── common/llm/adapters/ # âœ?LLMFactoryå<EFBFBD>¯å¤<EFBFBD>ç”?├── common/utils/jsonParser.js # âœ?JSONè§£æž<C3A6>å<EFBFBD>¯å¤<C3A5>ç”?└── modules/
|
||||
└── asl/ # 🚧 空目录(待创建)
|
||||
```
|
||||
|
||||
### ✅ Database Schema(Week 1 完成)
|
||||
```prisma
|
||||
### âœ?Database Schema(Week 1 完æˆ<EFBFBD>ï¼?```prisma
|
||||
// backend/prisma/schema.prisma
|
||||
datasource db {
|
||||
schemas = [
|
||||
"asl_schema", # ✅ 已预留,待定义表结构
|
||||
"asl_schema", # �已预留,待定义表结构
|
||||
// ...其他9个Schema
|
||||
]
|
||||
}
|
||||
@@ -67,70 +54,58 @@ datasource db {
|
||||
|
||||
---
|
||||
|
||||
## 🌥️ 云原生开发注意事项(2025-11-16 新增)
|
||||
|
||||
> **⭐ 重要更新**:本模块开发需遵循阿里云 Serverless 部署架构要求
|
||||
> **详细规范**:[云原生开发规范](../../../04-开发规范/08-云原生开发规范.md)
|
||||
> **部署指南**:[云原生部署架构指南](../../../09-架构实施/03-云原生部署架构指南.md)
|
||||
|
||||
### 🎯 本地开发 + 云端部署双兼容策略
|
||||
## 🌥ï¸?云原生开å<E282AC>‘注æ„<C3A6>事项(2025-11-16 新增ï¼?
|
||||
> **â?é‡<C3A9>è¦<C3A8>æ›´æ–°**:本模å<C2A1>—å¼€å<E282AC>‘需é<E282AC>µå¾ªé˜¿é‡Œäº?Serverless 部署架构è¦<C3A8>求
|
||||
> **详细规范**:[云原生开å<E282AC>‘规范](../../../04-å¼€å<E282AC>‘è§„èŒ?08-云原生开å<E282AC>‘è§„èŒ?md)
|
||||
> **部署指å<E280A1>—**:[云原生部署架构指å<E280A1>—](../../../09-架构实施/03-云原生部署架构指å<E280A1>?md)
|
||||
|
||||
### 🎯 本地开å<E282AC>?+ 云端部署å<C2B2>Œå…¼å®¹ç–ç•?
|
||||
| 环境 | å˜å‚¨æ–¹å¼<C3A5> | é…<C3A9>ç½® | 说明 |
|
||||
|------|---------|------|------|
|
||||
| **本地开发** | LocalAdapter | `STORAGE_TYPE=local` | 文件存储到 `./uploads/` |
|
||||
| **本地开å<EFBFBD>?* | LocalAdapter | `STORAGE_TYPE=local` | 文件å˜å‚¨åˆ?`./uploads/` |
|
||||
| **生产环境** | OSSAdapter | `STORAGE_TYPE=oss` | 文件å˜å‚¨åˆ°é˜¿é‡Œäº‘ OSS |
|
||||
|
||||
**核心原则**:
|
||||
- ✅ **Excel导入**:内存解析(`xlsx.read(buffer)`),不落盘
|
||||
- ✅ **PDF上传**(V1.0):使用 `StorageFactory`,本地/OSS自动切换
|
||||
- ✅ **异步任务**:LLM筛选任务必须异步处理(> 10秒任务)
|
||||
- ✅ **环境变量**:所有配置从 `.env` 读取
|
||||
- ✅ **数据库连接池**:使用全局 `prisma` 实例,不新建连接
|
||||
|
||||
### ❌ 禁止的做法
|
||||
**æ ¸å¿ƒåŽŸåˆ™**ï¼?- âœ?**Excel导入**:内å˜è§£æž<C3A6>(`xlsx.read(buffer)`),ä¸<C3A4>è<EFBFBD>½ç›?- âœ?**PDFä¸Šä¼ **(V1.0):使用 `StorageFactory`,本åœ?OSS自动切æ<E280A1>¢
|
||||
- âœ?**异æ¥ä»»åŠ¡**:LLMç›é€‰ä»»åŠ¡å¿…é¡»å¼‚æ¥å¤„ç<E2809E>†ï¼ˆ> 10秒任务)
|
||||
- âœ?**环境å<C692>˜é‡<C3A9>**:所有é…<C3A9>置从 `.env` 读å<C2BB>–
|
||||
- âœ?**æ•°æ<C2B0>®åº“è¿žæŽ¥æ± **:使用全局 `prisma` 实例,ä¸<C3A4>新建连接
|
||||
|
||||
### â<>?ç¦<C3A7>æ¢çš„å<E2809E>šæ³?
|
||||
| ç¦<C3A7>æ¢æ“<C3A6>作 | æ£ç¡®å<C2AE>𿳕 | åŽŸå› |
|
||||
|---------|---------|------|
|
||||
| `fs.writeFileSync('./temp.xlsx')` | `xlsx.read(buffer)` 内å˜è§£æž<C3A6> | Serverless容器é‡<C3A9>å<EFBFBD>¯ä¸¢å¤±æ–‡ä»¶ |
|
||||
| `new PrismaClient()` 每次新建连接 | 使用全局 `prisma` 实例 | 避免连接数暴增 |
|
||||
| 硬编码 `apiKey = 'sk-xxx'` | `process.env.LLM_API_KEY` | 配置管理混乱 |
|
||||
| 同步处理1000条文献筛选 | 异步任务 + 进度轮询 | 超过30秒超时限制 |
|
||||
|
||||
### ✅ MVP阶段开发检查清单
|
||||
|
||||
在提交代码前,请确认:
|
||||
| `new PrismaClient()` æ¯<C3A6>次新建连接 | 使用全局 `prisma` 实例 | é<>¿å…<C3A5>连接数暴å¢?|
|
||||
| 硬编ç ?`apiKey = 'sk-xxx'` | `process.env.LLM_API_KEY` | é…<EFBFBD>置管ç<EFBFBD>†æ··ä¹± |
|
||||
| å<EFBFBD>Œæ¥å¤„ç<EFBFBD>†1000æ<EFBFBD>¡æ–‡çŒ®ç›é€?| 异æ¥ä»»åŠ¡ + 进度轮询 | 超过30ç§’è¶…æ—¶é™<C3A9>åˆ?|
|
||||
|
||||
### âœ?MVP阶段开å<E282AC>‘检查清å<E280A6>?
|
||||
在æ<EFBFBD><EFBFBD>交代ç <EFBFBD>å‰<EFBFBD>,请确认ï¼?
|
||||
- [ ] Excel导入是å<C2AF>¦ä½¿ç”¨å†…å˜è§£æž<C3A6>(`xlsx.read(buffer)`)?
|
||||
- [ ] 是å<C2AF>¦ä½¿ç”¨å…¨å±€ `prisma` 实例(`import { prisma } from '@/config/database'`)?
|
||||
- [ ] 是å<C2AF>¦æ‰€æœ‰é…<C3A9>置都从环境å<C692>˜é‡<C3A9>读å<C2BB>–?
|
||||
- [ ] LLMç›é€‰ä»»åŠ¡æ˜¯å<C2AF>¦å¼‚æ¥å¤„ç<E2809E>†ï¼ˆ`POST /screening/start` ç«‹å<E280B9>³è¿”回taskId)?
|
||||
- [ ] 是否预留了 OSS 字段(`pdfUrl`, `pdfOssKey`, `pdfFileSize`)?
|
||||
- [ ] 是å<C2AF>¦é¢„ç•™äº?OSS å—æ®µï¼ˆ`pdfUrl`, `pdfOssKey`, `pdfFileSize`)?
|
||||
- [ ] 是å<C2AF>¦ä½¿ç”¨å˜å‚¨æŠ½è±¡å±‚(`StorageFactory.create()`)?
|
||||
|
||||
**预留字段说明**:
|
||||
- MVP阶段仅做标题摘要筛选,不处理PDF
|
||||
**é¢„ç•™å—æ®µè¯´æ˜Ž**ï¼?- MVP阶段仅å<E280A6>šæ ‡é¢˜æ‘˜è¦<C3A8>ç›é€‰ï¼Œä¸<C3A4>处ç<E2809E>†PDF
|
||||
- V1.0阶段实现全文PDFç›é€‰æ—¶ï¼Œä½¿ç”¨é¢„留的OSSå—æ®µ
|
||||
|
||||
---
|
||||
|
||||
## 📅 四周开发计划
|
||||
|
||||
## 📅 四周开å<E282AC>‘计åˆ?
|
||||
```
|
||||
Week 1: 数据库Schema + 后端API框架 + 存储抽象层
|
||||
Week 2: LLM筛选核心 + 异步批处理逻辑
|
||||
Week 3: 前端模块开发 + 审核工作台(内存解析Excel)
|
||||
Week 4: 结果展示 + 导出 + 集成测试
|
||||
Week 1: æ•°æ<EFBFBD>®åº“Schema + å<>Žç«¯API框架 + å˜å‚¨æŠ½è±¡å±?Week 2: LLMç›é€‰æ ¸å¿?+ å¼‚æ¥æ‰¹å¤„ç<E2809E>†é€»è¾‘
|
||||
Week 3: å‰<C3A5>端模å<C2A1>—å¼€å<E282AC>?+ å®¡æ ¸å·¥ä½œå<C593>°ï¼ˆå†…å˜è§£æž<C3A6>Excelï¼?Week 4: 结果展示 + 导出 + 集æˆ<C3A6>测试
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🗓️ Week 1: 数据库Schema与后端API框架
|
||||
## 🗓ï¸?Week 1: æ•°æ<EFBFBD>®åº“Schema与å<EFBFBD>Žç«¯API框架
|
||||
|
||||
### Day 1: Prisma Schema 设计
|
||||
|
||||
#### 任务1: 设计 asl_schema 表结构
|
||||
|
||||
**在 `backend/prisma/schema.prisma` 中添加:**
|
||||
#### 任务1: 设计 asl_schema 表结�
|
||||
**åœ?`backend/prisma/schema.prisma` 䏿·»åŠ ï¼š**
|
||||
|
||||
```prisma
|
||||
// ==================== ASL ç›é€‰é¡¹ç›®è¡¨ ====================
|
||||
@@ -144,15 +119,12 @@ model AslScreeningProject {
|
||||
// PICOæ ‡å‡†
|
||||
picoCriteria Json @map("pico_criteria") // { population, intervention, comparison, outcome, studyDesign }
|
||||
|
||||
// 筛选标准
|
||||
inclusionCriteria String @map("inclusion_criteria") @db.Text
|
||||
// ç›é€‰æ ‡å‡? inclusionCriteria String @map("inclusion_criteria") @db.Text
|
||||
exclusionCriteria String @map("exclusion_criteria") @db.Text
|
||||
|
||||
// 状态
|
||||
status String @default("draft") // draft, screening, completed
|
||||
// 状� status String @default("draft") // draft, screening, completed
|
||||
|
||||
// 筛选配置
|
||||
screeningConfig Json? @map("screening_config") // { models: ["deepseek", "qwen"], temperature: 0 }
|
||||
// ç›é€‰é…<EFBFBD>ç½? screeningConfig Json? @map("screening_config") // { models: ["deepseek", "qwen"], temperature: 0 }
|
||||
|
||||
// å…³è<C2B3>”
|
||||
literatures AslLiterature[]
|
||||
@@ -168,7 +140,7 @@ model AslScreeningProject {
|
||||
@@index([status])
|
||||
}
|
||||
|
||||
// ==================== ASL 文献条目表 ====================
|
||||
// ==================== ASL 文献æ<EFBFBD>¡ç›®è¡?====================
|
||||
model AslLiterature {
|
||||
id String @id @default(uuid())
|
||||
projectId String @map("project_id")
|
||||
@@ -183,8 +155,7 @@ model AslLiterature {
|
||||
publicationYear Int? @map("publication_year")
|
||||
doi String?
|
||||
|
||||
// 云原生存储字段(V1.0 阶段使用,MVP阶段预留)
|
||||
pdfUrl String? @map("pdf_url") // PDF访问URL
|
||||
// 云原生å˜å‚¨å—段(V1.0 阶段使用,MVP阶段预留ï¼? pdfUrl String? @map("pdf_url") // PDF访问URL
|
||||
pdfOssKey String? @map("pdf_oss_key") // OSSå˜å‚¨Keyï¼ˆç”¨äºŽåˆ é™¤ï¼‰
|
||||
pdfFileSize Int? @map("pdf_file_size") // 文件大å°<C3A5>(å—节)
|
||||
|
||||
@@ -241,23 +212,19 @@ model AslScreeningResult {
|
||||
qwenSEvidence String? @map("qwen_s_evidence") @db.Text
|
||||
qwenReason String? @map("qwen_reason") @db.Text
|
||||
|
||||
// 冲突状态
|
||||
conflictStatus String @default("none") @map("conflict_status") // "none" | "conflict" | "resolved"
|
||||
// 冲çª<EFBFBD>状æ€? conflictStatus String @default("none") @map("conflict_status") // "none" | "conflict" | "resolved"
|
||||
conflictFields Json? @map("conflict_fields") // ["P", "I", "conclusion"]
|
||||
|
||||
// 最终决策
|
||||
finalDecision String? @map("final_decision") // "include" | "exclude" | "pending"
|
||||
// 最终决ç? finalDecision String? @map("final_decision") // "include" | "exclude" | "pending"
|
||||
finalDecisionBy String? @map("final_decision_by") // userId
|
||||
finalDecisionAt DateTime? @map("final_decision_at")
|
||||
exclusionReason String? @map("exclusion_reason") @db.Text
|
||||
|
||||
// AI处理状态
|
||||
aiProcessingStatus String @default("pending") @map("ai_processing_status") // "pending" | "processing" | "completed" | "failed"
|
||||
// AI处ç<EFBFBD>†çжæ€? aiProcessingStatus String @default("pending") @map("ai_processing_status") // "pending" | "processing" | "completed" | "failed"
|
||||
aiProcessedAt DateTime? @map("ai_processed_at")
|
||||
aiErrorMessage String? @map("ai_error_message") @db.Text
|
||||
|
||||
// 可追溯信息
|
||||
promptVersion String @default("v1.0.0") @map("prompt_version")
|
||||
// å<EFBFBD>¯è¿½æº¯ä¿¡æ<EFBFBD>? promptVersion String @default("v1.0.0") @map("prompt_version")
|
||||
rawOutput Json? @map("raw_output") // 原始LLM输出(备份)
|
||||
|
||||
createdAt DateTime @default(now()) @map("created_at")
|
||||
@@ -305,54 +272,48 @@ model AslScreeningTask {
|
||||
@@index([status])
|
||||
}
|
||||
|
||||
// ==================== 用户表关联(添加到User模型)====================
|
||||
// 在 platform_schema 的 User 模型中添加:
|
||||
// ==================== 用户表关è<EFBFBD>”ï¼ˆæ·»åŠ åˆ°User模型ï¼?===================
|
||||
// åœ?platform_schema çš?User æ¨¡åž‹ä¸æ·»åŠ ï¼š
|
||||
// aslProjects AslScreeningProject[] @relation("AslProjects")
|
||||
```
|
||||
|
||||
**执行迁移:**
|
||||
**执行è¿<EFBFBD>ç§»ï¼?*
|
||||
```bash
|
||||
cd backend
|
||||
npx prisma migrate dev --name add_asl_screening_tables
|
||||
npx prisma generate
|
||||
```
|
||||
|
||||
**验收标准**:
|
||||
- ✅ 数据库表创建成功(4张表)
|
||||
- ✅ Prisma Client 生成成功
|
||||
- ✅ 可查询 asl_schema 表
|
||||
|
||||
**éªŒæ”¶æ ‡å‡†**ï¼?- âœ?æ•°æ<C2B0>®åº“表创建æˆ<C3A6>功ï¼?å¼ è¡¨ï¼?- âœ?Prisma Client 生æˆ<C3A6>æˆ<C3A6>功
|
||||
- âœ?å<>¯æŸ¥è¯?asl_schema è¡?
|
||||
---
|
||||
|
||||
### Day 2: å<>Žç«¯ç›®å½•结构创建
|
||||
|
||||
> **⭐ 前置条件(2025-11-17 更新)**:平台基础设施已完成实施 ✅
|
||||
> **完成状态**:8个核心模块,100%测试通过
|
||||
> **â?å‰<C3A5>ç½®æ<C2AE>¡ä»¶ï¼?025-11-17 æ›´æ–°ï¼?*:平å<C2B3>°åŸºç¡€è®¾æ–½å·²å®Œæˆ<C3A6>实æ–?âœ?
|
||||
> **完æˆ<C3A6>状æ€?*ï¼?ä¸ªæ ¸å¿ƒæ¨¡å<C2A1>—,100%测试通过
|
||||
> **完æˆ<C3A6>报告**:[å¹³å<C2B3>°åŸºç¡€è®¾æ–½å®žæ–½å®Œæˆ<C3A6>报告](../../../08-项目管ç<C2A1>†/03-æ¯<C3A6>周计划/2025-11-17-å¹³å<C2B3>°åŸºç¡€è®¾æ–½å®žæ–½å®Œæˆ<C3A6>报告.md)
|
||||
> **使用指å<E280A1>—**:[backend/src/common/README.md](../../../../backend/src/common/README.md)
|
||||
|
||||
#### 平台已提供的8个核心模块(无需ASL模块实现)
|
||||
|
||||
#### å¹³å<EFBFBD>°å·²æ<EFBFBD><EFBFBD>供的8ä¸ªæ ¸å¿ƒæ¨¡å<EFBFBD>—ï¼ˆæ— éœ€ASL模å<EFBFBD>—实现ï¼?
|
||||
**å¹³å<C2B3>°åŸºç¡€è®¾æ–½è·¯å¾„**:`backend/src/common/`
|
||||
|
||||
| # | 模å<C2A1>— | 使用方å¼<C3A5> | 功能说明 |
|
||||
|---|------|---------|---------|
|
||||
| 1 | **存储服务** | `import { storage } from '@/common/storage'` | 文件上传下载(本地/OSS切换) |
|
||||
| 1 | **å˜å‚¨æœ<EFBFBD>务** | `import { storage } from '@/common/storage'` | æ–‡ä»¶ä¸Šä¼ ä¸‹è½½ï¼ˆæœ¬åœ?OSS切æ<E280A1>¢ï¼?|
|
||||
| 2 | **日志系统** | `import { logger } from '@/common/logging'` | 结构化JSON日志 |
|
||||
| 3 | **ç¼“å˜æœ<C3A6>务** | `import { cache } from '@/common/cache'` | 内å˜/Redisç¼“å˜ |
|
||||
| 4 | **异步任务** | `import { jobQueue } from '@/common/jobs'` | 长时间任务处理 |
|
||||
| 5 | **健康检查** | `import { registerHealthRoutes } from '@/common/health'` | SAE健康检查 |
|
||||
| 6 | **监控指标** | `import { Metrics } from '@/common/monitoring'` | 性能监控和告警 |
|
||||
| 4 | **异æ¥ä»»åŠ¡** | `import { jobQueue } from '@/common/jobs'` | 长时间任务处ç<E2809E>?|
|
||||
| 5 | **å<EFBFBD>¥åº·æ£€æŸ?* | `import { registerHealthRoutes } from '@/common/health'` | SAEå<EFBFBD>¥åº·æ£€æŸ?|
|
||||
| 6 | **ç›‘æŽ§æŒ‡æ ‡** | `import { Metrics } from '@/common/monitoring'` | 性能监控和告è?|
|
||||
| 7 | **æ•°æ<C2B0>®åº“è¿žæŽ¥æ± ** | `import { prisma } from '@/config/database'` | 全局Prisma实例 |
|
||||
| 8 | **环境é…<C3A9>ç½®** | `import { env } from '@/config/env'` | 统一é…<C3A9>置管ç<C2A1>† |
|
||||
|
||||
**存储服务使用示例**:
|
||||
```typescript
|
||||
**å˜å‚¨æœ<EFBFBD>务使用示例**ï¼?```typescript
|
||||
// ASL模å<C2A1>—直接使用(一行代ç <C3A7>)
|
||||
import { storage } from '@/common/storage'
|
||||
|
||||
// 上传文件(不关心本地还是OSS)
|
||||
const url = await storage.upload('asl/literature/123.pdf', pdfBuffer)
|
||||
// ä¸Šä¼ æ–‡ä»¶ï¼ˆä¸<EFBFBD>关心本地还是OSSï¼?const url = await storage.upload('asl/literature/123.pdf', pdfBuffer)
|
||||
|
||||
// 下载文件
|
||||
const buffer = await storage.download('asl/literature/123.pdf')
|
||||
@@ -361,26 +322,18 @@ const buffer = await storage.download('asl/literature/123.pdf')
|
||||
await storage.delete('asl/literature/123.pdf')
|
||||
```
|
||||
|
||||
**支持的部署环境**:
|
||||
- ✅ 本地开发:LocalAdapter(文件存储到 `./uploads/`)
|
||||
- ✅ 云端SaaS:OSSAdapter(文件存储到阿里云OSS)
|
||||
- ✅ 私有化部署:LocalAdapter(文件存储到服务器)
|
||||
- ✅ 单机版:LocalAdapter(文件存储到用户本地)
|
||||
|
||||
**环境切换**:修改一个环境变量即可
|
||||
```bash
|
||||
# 本地开发
|
||||
STORAGE_TYPE=local
|
||||
**支æŒ<EFBFBD>的部署环å¢?*ï¼?- âœ?本地开å<E282AC>‘:LocalAdapter(文件å˜å‚¨åˆ° `./uploads/`ï¼?- âœ?云端SaaS:OSSAdapter(文件å˜å‚¨åˆ°é˜¿é‡Œäº‘OSSï¼?- âœ?ç§<C3A7>有化部署:LocalAdapter(文件å˜å‚¨åˆ°æœ<C3A6>务器)
|
||||
- âœ?å<>•机版:LocalAdapter(文件å˜å‚¨åˆ°ç”¨æˆ·æœ¬åœ°ï¼?
|
||||
**环境切æ<E280A1>¢**:修改一个环境å<C692>˜é‡<C3A9>å<EFBFBD>³å<C2B3>?```bash
|
||||
# 本地开å<E282AC>?STORAGE_TYPE=local
|
||||
|
||||
# 生产环境
|
||||
STORAGE_TYPE=oss
|
||||
```
|
||||
|
||||
**核心优势**:
|
||||
- ✅ ASL模块无需关心基础设施实现细节
|
||||
- ✅ 代码零改动切换环境(本地 ↔ 云端)
|
||||
- ✅ 所有业务模块(AIA/PKB/DC等)复用同一套基础设施
|
||||
- ✅ 统一维护、统一升级、统一监控
|
||||
**æ ¸å¿ƒä¼˜åŠ¿**ï¼?- âœ?ASL模å<C2A1>—æ— éœ€å…³å¿ƒåŸºç¡€è®¾æ–½å®žçŽ°ç»†èŠ‚
|
||||
- âœ?代ç <C3A7>零改动切æ<E280A1>¢çŽ¯å¢ƒï¼ˆæœ¬åœ° â†?云端ï¼?- âœ?所有业务模å<C2A1>—(AIA/PKB/DCç‰ï¼‰å¤<C3A5>用å<C2A8>Œä¸€å¥—基础设施
|
||||
- âœ?统一维护ã€<C3A3>统一å<E282AC>‡çº§ã€<C3A3>统一监控
|
||||
|
||||
---
|
||||
|
||||
@@ -402,7 +355,7 @@ touch types/screening.types.ts
|
||||
|
||||
#### 任务2: 创建路由文件
|
||||
|
||||
**`backend/src/modules/asl/routes/index.ts`:**
|
||||
**`backend/src/modules/asl/routes/index.ts`ï¼?*
|
||||
```typescript
|
||||
import { FastifyInstance } from 'fastify'
|
||||
import * as projectController from '../controllers/projectController.js'
|
||||
@@ -413,9 +366,8 @@ import * as screeningController from '../controllers/screeningController.js'
|
||||
* ASL 模å<C2A1>—路由注册
|
||||
*
|
||||
* @description
|
||||
* - 注册到 /api/v1/asl 前缀
|
||||
* - 参考 legacy/routes/ 的风格
|
||||
*
|
||||
* - 注册åˆ?/api/v1/asl å‰<EFBFBD>ç¼€
|
||||
* - å<EFBFBD>‚è€?legacy/routes/ 的风æ ? *
|
||||
* @version Week 3 Day 2
|
||||
*/
|
||||
export async function aslRoutes(fastify: FastifyInstance) {
|
||||
@@ -430,8 +382,7 @@ export async function aslRoutes(fastify: FastifyInstance) {
|
||||
fastify.post('/projects/:projectId/literatures/import', literatureController.importLiteratures)
|
||||
fastify.get('/projects/:projectId/literatures', literatureController.listLiteratures)
|
||||
|
||||
// 筛选管理
|
||||
fastify.post('/projects/:projectId/screening/start', screeningController.startScreening)
|
||||
// ç›é€‰ç®¡ç<EFBFBD>? fastify.post('/projects/:projectId/screening/start', screeningController.startScreening)
|
||||
fastify.get('/projects/:projectId/screening/results', screeningController.getScreeningResults)
|
||||
fastify.put('/screening/results/:resultId', screeningController.updateScreeningResult)
|
||||
fastify.post('/screening/results/batch-update', screeningController.batchUpdateResults)
|
||||
@@ -440,21 +391,19 @@ export async function aslRoutes(fastify: FastifyInstance) {
|
||||
}
|
||||
```
|
||||
|
||||
**验收标准**:
|
||||
- ✅ 目录结构清晰
|
||||
- ✅ 路由文件创建完成
|
||||
- ✅ **可正常使用平台服务**:
|
||||
- ✅ `import { storage } from '@/common/storage'` 可用
|
||||
- ✅ `import { logger } from '@/common/logging'` 可用
|
||||
- ✅ `import { prisma } from '@/config/database'` 可用
|
||||
- ✅ `import { jobQueue } from '@/common/jobs'` 可用
|
||||
- ✅ `import { cache } from '@/common/cache'` 可用
|
||||
**éªŒæ”¶æ ‡å‡†**ï¼?- âœ?目录结构清晰
|
||||
- âœ?路由文件创建完æˆ<C3A6>
|
||||
- âœ?**å<>¯æ£å¸¸ä½¿ç”¨å¹³å<C2B3>°æœ<C3A6>åŠ?*ï¼? - âœ?`import { storage } from '@/common/storage'` å<>¯ç”¨
|
||||
- âœ?`import { logger } from '@/common/logging'` å<>¯ç”¨
|
||||
- âœ?`import { prisma } from '@/config/database'` å<>¯ç”¨
|
||||
- âœ?`import { jobQueue } from '@/common/jobs'` å<>¯ç”¨
|
||||
- âœ?`import { cache } from '@/common/cache'` å<>¯ç”¨
|
||||
|
||||
---
|
||||
|
||||
### Day 3: 在 index.ts 中注册ASL路由
|
||||
### Day 3: åœ?index.ts 䏿³¨å†ŒASL路由
|
||||
|
||||
**`backend/src/index.ts`(修改):**
|
||||
**`backend/src/index.ts`(修改)�*
|
||||
```typescript
|
||||
// ============================================
|
||||
// ã€<C3A3>新架构】ASL 模å<C2A1>— - Week 3 新增
|
||||
@@ -466,22 +415,19 @@ import { aslRoutes } from './modules/asl/routes/index.js';
|
||||
// 注册 ASL 模å<C2A1>—路由
|
||||
await fastify.register(aslRoutes, { prefix: '/api/v1/asl' });
|
||||
|
||||
console.log('✅ ASL 路由已注册到 /api/v1/asl/*');
|
||||
console.log('�ASL 路由已注册到 /api/v1/asl/*');
|
||||
```
|
||||
|
||||
**验收标准**:
|
||||
- ✅ 后端启动成功
|
||||
- ✅ 访问 `http://localhost:3001/api/v1/asl/projects` 返回 200(即使是空列表)
|
||||
**éªŒæ”¶æ ‡å‡†**ï¼?- âœ?å<>Žç«¯å<C2AF>¯åЍæˆ<C3A6>功
|
||||
- âœ?访问 `http://localhost:3001/api/v1/asl/projects` 返回 200(å<CB86>³ä½¿æ˜¯ç©ºåˆ—表)
|
||||
|
||||
---
|
||||
|
||||
## 🗓️ Week 2: LLM筛选核心
|
||||
|
||||
### Day 4-5: LLM筛选服务实现
|
||||
|
||||
## 🗓ï¸?Week 2: LLMç›é€‰æ ¸å¿?
|
||||
### Day 4-5: LLMç›é€‰æœ<C3A6>务实çŽ?
|
||||
#### 任务1: 定义 JSON Schema
|
||||
|
||||
**`backend/src/modules/asl/schemas/screening.schema.ts`:**
|
||||
**`backend/src/modules/asl/schemas/screening.schema.ts`ï¼?*
|
||||
```typescript
|
||||
export const screeningOutputSchema = {
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
@@ -541,12 +487,10 @@ export const screeningOutputSchema = {
|
||||
};
|
||||
```
|
||||
|
||||
#### 任务2: 创建提示词模板
|
||||
|
||||
**`backend/prompts/asl/screening/v1.0.0-basic.txt`:**
|
||||
#### 任务2: 创建æ<C2BA><C3A6>示è¯<C3A8>模æ<C2A1>?
|
||||
**`backend/prompts/asl/screening/v1.0.0-basic.txt`ï¼?*
|
||||
```
|
||||
你是一位医学文献筛选专家。请根据以下 PICO 标准判断这篇文献是否应该纳入系统评价。
|
||||
|
||||
ä½ æ˜¯ä¸€ä½<EFBFBD>åŒ»å¦æ–‡çŒ®ç›é€‰ä¸“å®¶ã€‚è¯·æ ¹æ<EFBFBD>®ä»¥ä¸‹ PICO æ ‡å‡†åˆ¤æ–这篇文献是å<C2AF>¦åº”该纳入系统评价ã€?
|
||||
# PICO æ ‡å‡†
|
||||
- **Population (ç ”ç©¶å¯¹è±¡)**: {{population}}
|
||||
- **Intervention (干预措施)**: {{intervention}}
|
||||
@@ -560,18 +504,16 @@ export const screeningOutputSchema = {
|
||||
# æŽ’é™¤æ ‡å‡†
|
||||
{{exclusionCriteria}}
|
||||
|
||||
# 待筛选文献
|
||||
**标题**: {{title}}
|
||||
# å¾…ç›é€‰æ–‡çŒ?**æ ‡é¢˜**: {{title}}
|
||||
|
||||
**摘è¦<C3A8>**: {{abstract}}
|
||||
|
||||
# 输出è¦<C3A8>求
|
||||
|
||||
请严格按照以下 JSON Schema 输出结果,输出纯JSON(不要包含任何其他文字):
|
||||
|
||||
è¯·ä¸¥æ ¼æŒ‰ç…§ä»¥ä¸?JSON Schema 输出结果,输出纯JSON(ä¸<C3A4>è¦<C3A8>包å<E280A6>«ä»»ä½•å…¶ä»–æ–‡å—)ï¼?
|
||||
{
|
||||
"decision": "include/exclude/uncertain",
|
||||
"reason": "判断理由(10-500字)",
|
||||
"reason": "判æ–ç<EFBFBD>†ç”±ï¼?0-500å—)",
|
||||
"confidence": 0.95,
|
||||
"pico": {
|
||||
"population": "match/partial/mismatch",
|
||||
@@ -589,16 +531,13 @@ export const screeningOutputSchema = {
|
||||
}
|
||||
|
||||
# 注æ„<C3A6>事项
|
||||
1. decision 只能是 "include"(纳入)、"exclude"(排除)或 "uncertain"(不确定)
|
||||
2. reason 必须具体说明判断依据
|
||||
3. confidence 为 0-1 之间的数值
|
||||
4. pico 字段逐项评估匹配程度
|
||||
1. decision å<EFBFBD>ªèƒ½æ˜?"include"(纳入)ã€?exclude"(排除)æˆ?"uncertain"(ä¸<C3A4>确定ï¼?2. reason 必须具体说明判æ–ä¾<C3A4>æ<EFBFBD>®
|
||||
3. confidence ä¸?0-1 之间的数å€?4. pico å—æ®µé€<C3A9>项评估匹é…<C3A9>程度
|
||||
5. evidences å—æ®µæ<C2B5><C3A6>å<EFBFBD>–原文ä¸çš„关键çŸè¯ä½œä¸ºè¯<C3A8>æ<EFBFBD>®
|
||||
```
|
||||
|
||||
#### 任务3: 实现 LLM 筛选服务
|
||||
|
||||
**`backend/src/modules/asl/services/llmScreeningService.ts`:**
|
||||
#### 任务3: 实现 LLM ç›é€‰æœ<C3A6>åŠ?
|
||||
**`backend/src/modules/asl/services/llmScreeningService.ts`ï¼?*
|
||||
```typescript
|
||||
import { LLMFactory } from '../../../common/llm/adapters/LLMFactory.js';
|
||||
import { parseJSON } from '../../../common/utils/jsonParser.js';
|
||||
@@ -615,23 +554,18 @@ const ajv = new Ajv();
|
||||
const validateSchema = ajv.compile(screeningOutputSchema);
|
||||
|
||||
/**
|
||||
* LLM 筛选服务
|
||||
*
|
||||
* LLM ç›é€‰æœ<EFBFBD>åŠ? *
|
||||
* @description
|
||||
* - å¤<C3A5>用 common/llm/adapters/LLMFactory.ts
|
||||
* - 双模型并行调用(DeepSeek + Qwen)
|
||||
* - JSON Schema 验证
|
||||
* - 冲突检测
|
||||
*
|
||||
* - å<EFBFBD>Œæ¨¡åž‹å¹¶è¡Œè°ƒç”¨ï¼ˆDeepSeek + Qwenï¼? * - JSON Schema 验è¯<C3A8>
|
||||
* - 冲çª<EFBFBD>检æµ? *
|
||||
* @version Week 3 Day 4-5
|
||||
*/
|
||||
class LLMScreeningService {
|
||||
/**
|
||||
* 双模型并行筛选
|
||||
*/
|
||||
* å<EFBFBD>Œæ¨¡åž‹å¹¶è¡Œç›é€? */
|
||||
async dualModelScreening(literature: any, protocol: any) {
|
||||
// 构建提示词
|
||||
const prompt = this.buildPrompt(literature, protocol);
|
||||
// 构建æ<EFBFBD><EFBFBD>示è¯? const prompt = this.buildPrompt(literature, protocol);
|
||||
|
||||
// 并行调用两个模型
|
||||
const [resultA, resultB] = await Promise.all([
|
||||
@@ -643,8 +577,7 @@ class LLMScreeningService {
|
||||
const decisionA = await this.parseModelOutput(resultA.content, 'deepseek');
|
||||
const decisionB = await this.parseModelOutput(resultB.content, 'qwen');
|
||||
|
||||
// 一致性判断
|
||||
const { consensus, conflictFields } = this.compareDecisions(decisionA, decisionB);
|
||||
// 一致性判� const { consensus, conflictFields } = this.compareDecisions(decisionA, decisionB);
|
||||
|
||||
// 自动分æµ<C3A6>
|
||||
const needReview = this.shouldReview(consensus, decisionA, decisionB);
|
||||
@@ -660,8 +593,7 @@ class LLMScreeningService {
|
||||
}
|
||||
|
||||
/**
|
||||
* 调用LLM模型(复用common/llm)
|
||||
*/
|
||||
* 调用LLM模型(å¤<EFBFBD>用common/llmï¼? */
|
||||
private async callModel(modelName: string, prompt: string) {
|
||||
const llm = LLMFactory.createLLM(modelName);
|
||||
|
||||
@@ -669,19 +601,16 @@ class LLMScreeningService {
|
||||
messages: [
|
||||
{ role: 'user', content: prompt }
|
||||
],
|
||||
temperature: 0, // 确定性输出
|
||||
max_tokens: 1000
|
||||
temperature: 0, // 确定性输� max_tokens: 1000
|
||||
});
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建提示词
|
||||
*/
|
||||
* 构建æ<EFBFBD><EFBFBD>示è¯? */
|
||||
private buildPrompt(literature: any, protocol: any): string {
|
||||
// 读取提示词模板
|
||||
const templatePath = path.resolve(__dirname, '../../../../prompts/asl/screening/v1.0.0-basic.txt');
|
||||
// 读å<EFBFBD>–æ<EFBFBD><EFBFBD>示è¯<EFBFBD>模æ<EFBFBD>? const templatePath = path.resolve(__dirname, '../../../../prompts/asl/screening/v1.0.0-basic.txt');
|
||||
let template = fs.readFileSync(templatePath, 'utf-8');
|
||||
|
||||
// 替æ<C2BF>¢å<C2A2>˜é‡<C3A9>
|
||||
@@ -702,13 +631,12 @@ class LLMScreeningService {
|
||||
* è§£æž<C3A6>模型输出
|
||||
*/
|
||||
private async parseModelOutput(content: string, modelName: string) {
|
||||
// 使用JSON解析器(复用common/utils)
|
||||
const parsed = parseJSON(content);
|
||||
// 使用JSONè§£æž<EFBFBD>器(å¤<EFBFBD>用common/utilsï¼? const parsed = parseJSON(content);
|
||||
|
||||
// JSON Schema 验è¯<C3A8>
|
||||
const valid = validateSchema(parsed);
|
||||
if (!valid) {
|
||||
console.error('JSON Schema验证失败:', validateSchema.errors);
|
||||
console.error('JSON Schema验è¯<C3A8>失败ï¼?, validateSchema.errors);
|
||||
throw new Error(`模型${modelName}è¾“å‡ºæ ¼å¼<C3A5>ä¸<C3A4>符å<C2A6>ˆSchema`);
|
||||
}
|
||||
|
||||
@@ -724,18 +652,15 @@ class LLMScreeningService {
|
||||
}
|
||||
|
||||
/**
|
||||
* 对比两个模型的决策
|
||||
*/
|
||||
* 对比两个模型的决ç? */
|
||||
private compareDecisions(decisionA: any, decisionB: any) {
|
||||
const conflicts: string[] = [];
|
||||
|
||||
// 比较最终决策
|
||||
if (decisionA.decision !== decisionB.decision) {
|
||||
// 比较最终决ç? if (decisionA.decision !== decisionB.decision) {
|
||||
conflicts.push('decision');
|
||||
}
|
||||
|
||||
// 比较PICO各维度
|
||||
if (decisionA.pico.population !== decisionB.pico.population) conflicts.push('P');
|
||||
// 比较PICOå<EFBFBD>„ç»´åº? if (decisionA.pico.population !== decisionB.pico.population) conflicts.push('P');
|
||||
if (decisionA.pico.intervention !== decisionB.pico.intervention) conflicts.push('I');
|
||||
if (decisionA.pico.comparison !== decisionB.pico.comparison) conflicts.push('C');
|
||||
if (decisionA.pico.outcome !== decisionB.pico.outcome) conflicts.push('O');
|
||||
@@ -749,27 +674,24 @@ class LLMScreeningService {
|
||||
* 自动分æµ<C3A6>规则
|
||||
*/
|
||||
private shouldReview(consensus: string, decisionA: any, decisionB: any): boolean {
|
||||
// 规则1:冲突 → 必须复核
|
||||
// 规则1:冲çª?â†?å¿…é¡»å¤<C3A5>æ ¸
|
||||
if (consensus === 'conflict') {
|
||||
return true;
|
||||
}
|
||||
|
||||
// 规则2:低置信度 → 需要复核
|
||||
const avgConfidence = (decisionA.confidence + decisionB.confidence) / 2;
|
||||
// 规则2:低置信åº?â†?需è¦<C3A8>å¤<C3A5>æ ? const avgConfidence = (decisionA.confidence + decisionB.confidence) / 2;
|
||||
if (avgConfidence < 0.7) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// 规则3:高置信度 + 一致 → 自动通过
|
||||
// 规则3:高置信�+ 一��自动通过
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量筛选
|
||||
*/
|
||||
* 批é‡<EFBFBD>ç›é€? */
|
||||
async batchScreening(literatures: any[], protocol: any, progressCallback?: (progress: number) => void) {
|
||||
const batchSize = 15; // 每批15篇
|
||||
const results = [];
|
||||
const batchSize = 15; // æ¯<EFBFBD>批15ç¯? const results = [];
|
||||
|
||||
for (let i = 0; i < literatures.length; i += batchSize) {
|
||||
const batch = literatures.slice(i, i + batchSize);
|
||||
@@ -781,8 +703,7 @@ class LLMScreeningService {
|
||||
|
||||
results.push(...batchResults);
|
||||
|
||||
// 推送进度
|
||||
const progress = Math.round(((i + batch.length) / literatures.length) * 100);
|
||||
// 推é€<EFBFBD>è¿›åº? const progress = Math.round(((i + batch.length) / literatures.length) * 100);
|
||||
progressCallback?.(progress);
|
||||
}
|
||||
|
||||
@@ -793,20 +714,16 @@ class LLMScreeningService {
|
||||
export const llmScreeningService = new LLMScreeningService();
|
||||
```
|
||||
|
||||
**验收标准**:
|
||||
- ✅ LLM双模型调用成功
|
||||
- ✅ JSON Schema验证通过率 > 95%
|
||||
- ✅ 冲突检测准确
|
||||
|
||||
**éªŒæ”¶æ ‡å‡†**ï¼?- âœ?LLMå<4D>Œæ¨¡åž‹è°ƒç”¨æˆ<C3A6>åŠ?- âœ?JSON Schema验è¯<C3A8>通过çŽ?> 95%
|
||||
- âœ?冲çª<C3A7>检测准ç¡?
|
||||
---
|
||||
|
||||
## 🗓️ Week 3: 前端模块开发
|
||||
|
||||
## 🗓ï¸?Week 3: å‰<EFBFBD>端模å<EFBFBD>—å¼€å<EFBFBD>?
|
||||
### Day 6-7: å‰<C3A5>端模å<C2A1>—结构创建
|
||||
|
||||
#### 任务1: 更新模å<C2A1>—定义
|
||||
|
||||
**`frontend-v2/src/modules/asl/index.tsx`(修改):**
|
||||
**`frontend-v2/src/modules/asl/index.tsx`(修改)�*
|
||||
```typescript
|
||||
import { lazy } from 'react'
|
||||
import { ModuleDefinition } from '@/framework/modules/types'
|
||||
@@ -827,7 +744,7 @@ const ASLModule: ModuleDefinition = {
|
||||
path: '/literature',
|
||||
icon: FileSearchOutlined,
|
||||
component: lazy(() => import('./routes')),
|
||||
placeholder: false, // ✅ 改为 false
|
||||
placeholder: false, // �改为 false
|
||||
requiredVersion: 'advanced',
|
||||
description: 'AI驱动的文献ç›é€‰å’Œåˆ†æž<C3A6>系统',
|
||||
}
|
||||
@@ -850,7 +767,7 @@ touch api/index.ts
|
||||
|
||||
#### 任务3: 实现路由é…<C3A9>ç½®
|
||||
|
||||
**`frontend-v2/src/modules/asl/routes.tsx`:**
|
||||
**`frontend-v2/src/modules/asl/routes.tsx`ï¼?*
|
||||
```typescript
|
||||
import { lazy } from 'react'
|
||||
import { Routes, Route, Navigate } from 'react-router-dom'
|
||||
@@ -865,9 +782,7 @@ const ScreeningResults = lazy(() => import('./pages/ScreeningResults'))
|
||||
*
|
||||
* @description
|
||||
* - /literature - 项目列表
|
||||
* - /literature/project/:id/settings - 设置与启动
|
||||
* - /literature/project/:id/workbench - 审核工作台
|
||||
* - /literature/project/:id/results - 初筛结果
|
||||
* - /literature/project/:id/settings - 设置与å<EFBFBD>¯åŠ? * - /literature/project/:id/workbench - å®¡æ ¸å·¥ä½œå<C593>? * - /literature/project/:id/results - åˆ<C3A5>ç›ç»“æžœ
|
||||
*
|
||||
* @version Week 3 Day 6
|
||||
*/
|
||||
@@ -885,9 +800,7 @@ export default function ASLRoutes() {
|
||||
}
|
||||
```
|
||||
|
||||
**验收标准**:
|
||||
- ✅ 顶部导航显示"AI智能文献"(不再是占位)
|
||||
- ✅ 点击后进入项目列表页(即使是空列表)
|
||||
**éªŒæ”¶æ ‡å‡†**ï¼?- âœ?顶部导航显示"AI智能文献"(ä¸<C3A4>å†<C3A5>是å<C2AF> ä½<C3A4>ï¼?- âœ?点击å<C2BB>Žè¿›å…¥é¡¹ç›®åˆ—表页(å<CB86>³ä½¿æ˜¯ç©ºåˆ—表)
|
||||
|
||||
---
|
||||
|
||||
@@ -895,39 +808,29 @@ export default function ASLRoutes() {
|
||||
|
||||
(由于篇幅é™<EFBFBD>åˆ¶ï¼Œæ ¸å¿ƒå®žçŽ°ä»£ç <EFBFBD>请å<EFBFBD>‚考任务分解文档)
|
||||
|
||||
**验收标准**:
|
||||
- ✅ Excel上传功能正常
|
||||
- ✅ 审核工作台可展示筛选结果
|
||||
- ✅ 双视图模态框可弹出
|
||||
|
||||
**éªŒæ”¶æ ‡å‡†**ï¼?- âœ?Excelä¸Šä¼ åŠŸèƒ½æ£å¸¸
|
||||
- âœ?å®¡æ ¸å·¥ä½œå<C593>°å<C2B0>¯å±•示ç›é€‰ç»“æž?- âœ?å<>Œè§†å›¾æ¨¡æ€<C3A6>框å<E280A0>¯å¼¹å‡?
|
||||
---
|
||||
|
||||
## 🗓️ Week 4: 集成测试与验收
|
||||
|
||||
### Day 11-14: 端到端测试
|
||||
|
||||
(详细测试计划见任务分解文档)
|
||||
|
||||
**验收标准**:
|
||||
- ✅ 完整流程:上传 → 筛选 → 复核 → 导出
|
||||
- ✅ 准确率 ≥ 85%
|
||||
- ✅ 性能达标(100篇 < 10分钟)
|
||||
|
||||
## 🗓ï¸?Week 4: 集æˆ<EFBFBD>测试与验æ”?
|
||||
### Day 11-14: 端到端测�
|
||||
(详细测试计划è§<EFBFBD>任务分解文档ï¼?
|
||||
**éªŒæ”¶æ ‡å‡†**ï¼?- âœ?完整æµ<C3A6>程:上ä¼?â†?ç›é€?â†?å¤<C3A5>æ ¸ â†?导出
|
||||
- �准确��85%
|
||||
- âœ?æ€§èƒ½è¾¾æ ‡ï¼?00ç¯?< 10分钟ï¼?
|
||||
---
|
||||
|
||||
## 📚 相关文档
|
||||
|
||||
- [å¼€å<EFBFBD>‘里程碑](./01-å¼€å<E282AC>‘里程碑.md)
|
||||
- [任务分解(Todo List)](./03-任务分解.md)
|
||||
- [质量保障策略](../02-技术设计/06-质量保障与可追溯策略.md)
|
||||
- [技术选型](../02-技术设计/07-文献处理技术选型.md)
|
||||
- [API设计规范](../02-技术设计/02-API设计规范.md)
|
||||
- [è´¨é‡<EFBFBD>ä¿<EFBFBD>éšœç–ç•¥](../02-技术设è®?06-è´¨é‡<C3A9>ä¿<C3A4>障与å<C5BD>¯è¿½æº¯ç–ç•¥.md)
|
||||
- [技术选型](../02-技术设è®?07-文献处ç<E2809E>†æŠ€æœ¯é€‰åž‹.md)
|
||||
- [API设计规范](../02-技术设�02-API设计规范.md)
|
||||
- [å‰<EFBFBD>å<EFBFBD>Žç«¯æ¨¡å<EFBFBD>—化架构设计-V2](../../../00-系统总体设计/å‰<C3A5>å<EFBFBD>Žç«¯æ¨¡å<C2A1>—化架构设计-V2.md)
|
||||
|
||||
---
|
||||
|
||||
**更新日志**:
|
||||
- 2025-11-18: V3.1 更新,补充平台基础设施完成状态(8个核心模块)
|
||||
- 2025-11-16: V3.0 重写,基于真实架构(Frontend-v2 + Backend + asl_schema)
|
||||
- 2025-11-16: V2.0 重写,详细到每天的任务和代码示例
|
||||
- 2025-10-29: V1.0 创建,初始版本
|
||||
**更新日志**ï¼?- 2025-11-18: V3.1 更新,补充平å<C2B3>°åŸºç¡€è®¾æ–½å®Œæˆ<C3A6>状æ€<C3A6>(8ä¸ªæ ¸å¿ƒæ¨¡å<C2A1>—)
|
||||
- 2025-11-16: V3.0 é‡<C3A9>写,基于真实架构(Frontend-v2 + Backend + asl_schemaï¼?- 2025-11-16: V2.0 é‡<C3A9>写,详细到æ¯<C3A6>天的任务和代ç <C3A7>示例
|
||||
- 2025-10-29: V1.0 创建,åˆ<EFBFBD>始版æœ?
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,80 +1,80 @@
|
||||
# Week 4嚗𡁶<E59A97><F0A181B6>𨅯<EFBFBD>蝷箔<E89DB7>撖澆枂 - 撘<><E69298>𤏸恣<F0A48FB8>𡜐<EFBFBD>鈭穃<E988AD><E7A983><EFBFBD>沲<EFBFBD><E6B2B2><EFBFBD>
|
||||
|
||||
> **文档版本:** v1.0
|
||||
> **创建日期:** 2025-11-21
|
||||
> **计划周期:** 2天(Day 16-17)
|
||||
> **架构原则:** ✅ 云原生优先
|
||||
> **<EFBFBD><EFBFBD>﹝<EFBFBD><EFBFBD>𧋦嚗?* v1.0
|
||||
> **<EFBFBD>𥕦遣<EFBFBD>交<EFBFBD>嚗?* 2025-11-21
|
||||
> **霈∪<EFBFBD><EFBFBD>冽<EFBFBD>嚗?* 2憭抬<E686AD>Day 16-17嚗?
|
||||
> **<EFBFBD>嗆<EFBFBD><EFBFBD>笔<EFBFBD>嚗?* <20>?鈭穃<E988AD><E7A983>煺<EFBFBD><E785BA>?
|
||||
> **<2A><><EFBFBD>擧凒<E693A7>堆<EFBFBD>** 2025-11-21
|
||||
|
||||
---
|
||||
|
||||
## <20><> <20><>﹝霂湔<E99C82>
|
||||
|
||||
本文档是 Week 4 功能开发的详细计划,遵循云原生开发规范,实现筛选结果的统计展示和Excel导出功能。
|
||||
<EFBFBD>祆<EFBFBD>獢<EFBFBD>糓 Week 4 <EFBFBD>蠘<EFBFBD>撘<EFBFBD><EFBFBD>𤑳<EFBFBD>霂衣<EFBFBD>霈∪<EFBFBD>嚗屸<EFBFBD>敺芯<EFBFBD><EFBFBD>毺<EFBFBD>撘<EFBFBD><EFBFBD>𤏸<EFBFBD><EFBFBD><EFBFBD><EFBFBD>摰䂿緵蝑偦<EFBFBD>厩<EFBFBD><EFBFBD>𦦵<EFBFBD>蝏蠘恣撅閧內<EFBFBD>袏xcel撖澆枂<EFBFBD>蠘<EFBFBD><EFBFBD>?
|
||||
|
||||
**核心目标**:
|
||||
- ✅ 统计概览(总数、纳入率、排除率、待复核)
|
||||
- ✅ PRISMA式排除原因统计
|
||||
- ✅ 结果列表Tab切换与查看
|
||||
- ✅ Excel批量导出
|
||||
- ✅ 完整功能闭环(上传→筛选→复核→统计→导出)
|
||||
**<EFBFBD>詨<EFBFBD><EFBFBD>格<EFBFBD>**嚗?
|
||||
- <EFBFBD>?蝏蠘恣璁<E681A3><E79281>嚗<EFBFBD><E59A97>餅㺭<E9A485><E3BAAD>熙<EFBFBD>亦<EFBFBD><E4BAA6><EFBFBD><EFBFBD><EFBFBD>斤<EFBFBD><E696A4><EFBFBD><EFBFBD>憭齿瓲嚗?
|
||||
- <EFBFBD>?PRISMA撘𤩺<EFBFBD><EFBFBD>文<EFBFBD><EFBFBD>删<EFBFBD>霈?
|
||||
- <EFBFBD>?蝏𤘪<E89D8F><F0A498AA>𡑒”Tab<61><62>揢銝擧䰻<E693A7>?
|
||||
- <EFBFBD>?Excel<EFBFBD>寥<EFBFBD>撖澆枂
|
||||
- <EFBFBD>?摰峕㟲<E5B395>蠘<EFBFBD><E8A098>剔㴓嚗<E3B493><E59A97>隡罱<E99AA1>蝑偦<E89D91>争<EFBFBD>憭齿瓲<E9BDBF>垍<EFBFBD>霈﹦<E99C88>撖澆枂嚗?
|
||||
|
||||
**架构原则**:
|
||||
- ✅ **云原生优先**:遵循[云原生开发规范](../../../04-开发规范/08-云原生开发规范.md)
|
||||
- ✅ **复用平台能力**:使用全局`prisma`、`logger`等
|
||||
- ✅ **零文件落盘**:Excel前端生成或OSS存储
|
||||
- ✅ **后端聚合计算**:统计数据后端聚合
|
||||
**<EFBFBD>嗆<EFBFBD><EFBFBD>笔<EFBFBD>**嚗?
|
||||
- <EFBFBD>?**鈭穃<E988AD><E7A983>煺<EFBFBD><E785BA>?*嚗𡁻<E59A97>敺歧鈭穃<E988AD><E7A983>笔<EFBFBD><E7AC94>𤏸<EFBFBD><F0A48FB8><EFBFBD>(../../../04-撘<><E69298>𤏸<EFBFBD><F0A48FB8>?08-鈭穃<E988AD><E7A983>笔<EFBFBD><E7AC94>𤏸<EFBFBD><F0A48FB8>?md)
|
||||
- <EFBFBD>?**憭滨鍂撟喳蝱<E596B3>賢<EFBFBD>**嚗帋蝙<E5B88B>典<EFBFBD>撅<EFBFBD>`prisma`<EFBFBD><EFBFBD>logger`蝑?
|
||||
- <EFBFBD>?**<2A>嗆<EFBFBD>隞嗉氜<E59789>?*嚗鍃xcel<65>滨垢<E6BBA8><E59EA2><EFBFBD><EFBFBD>𤈛SS摮睃<E691AE>
|
||||
- <EFBFBD>?**<2A>𡒊垢<F0A1928A>𡁜<EFBFBD>霈∠<E99C88>**嚗𡁶<E59A97>霈⊥㺭<E28AA5>桀<EFBFBD>蝡航<E89DA1><E888AA>?
|
||||
|
||||
---
|
||||
|
||||
## 🎯 一、功能定位
|
||||
## <EFBFBD>㴓 銝<><E98A9D><EFBFBD><EFBFBD><EFBFBD>賢<EFBFBD>雿?
|
||||
|
||||
### 1.1 "审核工作台" vs "初筛结果" 区别
|
||||
### 1.1 "摰⊥瓲撌乩<EFBFBD><EFBFBD>? vs "<22>萘<EFBFBD>蝏𤘪<E89D8F>" <20>箏<EFBFBD>
|
||||
|
||||
| 维度 | 审核工作台(ScreeningWorkbench) | 初筛结果(ScreeningResults) |
|
||||
| 蝏游漲 | 摰⊥瓲撌乩<E6928C><E4B9A9>堆<EFBFBD>ScreeningWorkbench嚗?| <20>萘<EFBFBD>蝏𤘪<E89D8F>嚗𠄎creeningResults嚗?|
|
||||
|------|--------------------------------|---------------------------|
|
||||
| **定位** | 实时监控、冲突处理、人工复核 | 最终结果展示、统计分析、批量导出 |
|
||||
| **摰帋<EFBFBD>** | 摰墧𧒄<EFBFBD>烐綉<EFBFBD><EFBFBD><EFBFBD>蝒<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>犖撌亙<EFBFBD><EFBFBD>?| <20><>蝏<EFBFBD><E89D8F><EFBFBD>𨅯<EFBFBD>蝷箝<E89DB7><E7AE9D><EFBFBD>霈∪<E99C88><E288AA>僐<EFBFBD><E58390>鸌<EFBFBD>誩紡<E8AAA9>?|
|
||||
| **雿輻鍂<E8BCBB>嗆㦤** | 蝑偦<E89D91>㕑<EFBFBD>銵䔶葉 | 蝑偦<E89D91>匧<EFBFBD><E58CA7>𣂼<EFBFBD> |
|
||||
| **核心功能** | 进度轮询、逐条复核、冲突高亮 | 统计概览、PRISMA总结、批量导出 |
|
||||
| **表格形式** | 双行表格(DS + Qwen对比) | 单行表格(显示最终决策) |
|
||||
| **强调重点** | 工作流 | 结果汇总 |
|
||||
| **<EFBFBD>詨<EFBFBD><EFBFBD>蠘<EFBFBD>** | 餈𥕦漲頧株砭<EFBFBD><EFBFBD><EFBFBD>鞉辺憭齿瓲<EFBFBD><EFBFBD><EFBFBD>蝒<EFBFBD><EFBFBD>鈭?| 蝏蠘恣璁<E681A3><E79281><EFBFBD><EFBFBD>RISMA<4D>餌<EFBFBD><E9A48C><EFBFBD>鸌<EFBFBD>誩紡<E8AAA9>?|
|
||||
| **銵冽聢敶W<EFBFBD>** | <EFBFBD>諹<EFBFBD>銵冽聢嚗㇄S + Qwen撖寞<E69296>嚗?| <20>閗<EFBFBD>銵冽聢嚗<E881A2>遬蝷箸<E89DB7>蝏<EFBFBD><E89D8F>蝑吔<E89D91> |
|
||||
| **撘箄<EFBFBD><EFBFBD>滨<EFBFBD>** | 撌乩<EFBFBD>瘚?| 蝏𤘪<E89D8F>瘙<EFBFBD><E79899>?|
|
||||
|
||||
**比喻**:
|
||||
**瘥𥪜鸘**嚗?
|
||||
```
|
||||
审核工作台 = 生产车间(正在筛选、复核)
|
||||
摰⊥瓲撌乩<EFBFBD><EFBFBD>?= <20>煺漣頧阡𡢿嚗<F0A1A2BF>迤<EFBFBD>函<EFBFBD><E587BD>剹<EFBFBD><E589B9><EFBFBD><EFBFBD>賂<EFBFBD>
|
||||
<EFBFBD>萘<EFBFBD>蝏𤘪<EFBFBD> = <20>𣂼<EFBFBD>隞枏<E99A9E>嚗<EFBFBD>歇摰峕<E691B0><E5B395><EFBFBD><EFBFBD>霈~<E99C88><EFBD9E>紡<EFBFBD>綽<EFBFBD>
|
||||
```
|
||||
|
||||
### 1.2 <20>冽<EFBFBD>瘚<EFBFBD><E7989A>
|
||||
|
||||
```
|
||||
设置与启动 → 审核工作台 → 初筛结果
|
||||
(配置) (实时监控) (结果汇总)
|
||||
↓ ↓ ↓
|
||||
霈曄蔭銝𤾸鍳<EFBFBD>?<3F>?摰⊥瓲撌乩<E6928C><E4B9A9>?<3F>?<3F>萘<EFBFBD>蝏𤘪<E89D8F>
|
||||
(<EFBFBD>滨蔭) (摰墧𧒄<EFBFBD>烐綉) (蝏𤘪<E89D8F>瘙<EFBFBD><E79899>?
|
||||
<EFBFBD>? <EFBFBD>? <EFBFBD>?
|
||||
憛怠<E6869B>PICOS <20>鞉辺憭齿瓲 <20>寥<EFBFBD>撖澆枂
|
||||
銝𠹺<E98A9D>Excel <20>脩<EFBFBD>憭<EFBFBD><E686AD> 蝏蠘恣<E8A098><E681A3><EFBFBD>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🏗️ 二、技术架构(云原生)
|
||||
## <EFBFBD><EFBFBD>儭?鈭䎚<E988AD><E48E9A><EFBFBD><EFBFBD>舀沲<E88880><E6B2B2><EFBFBD>鈭穃<E988AD><E7A983><EFBFBD><EFBFBD>
|
||||
|
||||
### 2.1 <20>詨<EFBFBD><E8A9A8>嗆<EFBFBD><E59786>喟<EFBFBD>
|
||||
|
||||
#### 决策1:数据获取策略 → 后端聚合API ✅
|
||||
#### <EFBFBD>喟<EFBFBD>1嚗𡁏㺭<EFBFBD>株繮<EFBFBD>𣇉<EFBFBD><EFBFBD>?<3F>?<3F>𡒊垢<F0A1928A>𡁜<EFBFBD>API <EFBFBD>?
|
||||
|
||||
**方案A**(不采用):前端获取全量数据,前端计算
|
||||
**<EFBFBD>寞<EFBFBD>A**嚗<><E59A97><EFBFBD><EFBFBD>鍂嚗㚁<E59A97><E39A81>滨垢<E6BBA8>瑕<EFBFBD><E79195>券<EFBFBD><E588B8>唳旿嚗<E697BF><E59A97>蝡航恣蝞?
|
||||
```typescript
|
||||
// ❌ 不符合云原生:前端获取全量数据(可能上千条)
|
||||
// <EFBFBD>?銝滨泵<E6BBA8><E6B3B5><EFBFBD><EFBFBD>毺<EFBFBD>嚗𡁜<E59A97>蝡航繮<E888AA>硋<EFBFBD><E7A18B>𤩺㺭<F0A4A9BA>殷<EFBFBD><E6AEB7>航<EFBFBD>銝𠰴<E98A9D><F0A0B0B4>∴<EFBFBD>
|
||||
const { data } = await aslApi.getScreeningResultsList(projectId, {
|
||||
pageSize: 9999 // <20>瑕<EFBFBD><E79195>券<EFBFBD>
|
||||
});
|
||||
// <20>滨垢霈∠<E99C88>蝏蠘恣...
|
||||
```
|
||||
|
||||
**方案B**(采用):后端聚合API ✅
|
||||
**<EFBFBD>寞<EFBFBD>B**嚗<><E59A97><EFBFBD>剁<EFBFBD>嚗𡁜<E59A97>蝡航<E89DA1><E888AA>㇁PI <EFBFBD>?
|
||||
```typescript
|
||||
// ✅ 符合云原生:后端聚合,减少网络传输
|
||||
// <EFBFBD>?蝚血<E89D9A>鈭穃<E988AD><E7A983><EFBFBD><EFBFBD><EFBFBD>𡒊垢<F0A1928A>𡁜<EFBFBD>嚗<EFBFBD><E59A97>撠𤑳<E692A0>蝏靝<E89D8F>颲?
|
||||
GET /api/v1/asl/projects/:projectId/statistics
|
||||
|
||||
// <20>𡒊垢雿輻鍂Prisma<6D>𡁜<EFBFBD>
|
||||
@@ -85,50 +85,50 @@ const stats = await prisma.aslScreeningResult.groupBy({
|
||||
});
|
||||
```
|
||||
|
||||
**选择理由**:
|
||||
- ✅ 后端聚合,性能好
|
||||
- ✅ 减少网络传输(从MB级降到KB级)
|
||||
- ✅ 可扩展性强(支持更复杂的统计)
|
||||
- ✅ 符合云原生"计算靠近数据"原则
|
||||
**<EFBFBD>㗇𥋘<EFBFBD><EFBFBD>眏**嚗?
|
||||
- <EFBFBD>?<3F>𡒊垢<F0A1928A>𡁜<EFBFBD>嚗峕<E59A97>扯<EFBFBD>憟?
|
||||
- <EFBFBD>?<3F>誩<EFBFBD>蝵𤑳<E89DB5>隡㰘<E99AA1>嚗<EFBFBD><E59A97>MB蝥折<E89DA5><E68A98>袁B蝥改<E89DA5>
|
||||
- <EFBFBD>?<3F>舀<EFBFBD>撅閙<E69285>批撩嚗<E692A9>𣈲<EFBFBD><F0A388B2>凒憭齿<E686AD><E9BDBF><EFBFBD><EFBFBD>霈∴<E99C88>
|
||||
- <EFBFBD>?蝚血<E89D9A>鈭穃<E988AD><E7A983>?霈∠<E99C88><E288A0>㰘<EFBFBD><E3B098>唳旿"<22>笔<EFBFBD>
|
||||
|
||||
---
|
||||
|
||||
#### 决策2:Excel导出策略 → 前端生成(MVP)✅
|
||||
#### <EFBFBD>喟<EFBFBD>2嚗鍃xcel撖澆枂蝑𣇉裦 <20>?<3F>滨垢<E6BBA8><E59EA2><EFBFBD>嚗㇈VP嚗争<E59A97>
|
||||
|
||||
**方案A**(采用MVP):前端生成 ✅
|
||||
**<EFBFBD>寞<EFBFBD>A**嚗<><E59A97><EFBFBD>決VP嚗㚁<E59A97><E39A81>滨垢<E6BBA8><E59EA2><EFBFBD> <20>?
|
||||
```typescript
|
||||
// ✅ 符合云原生:零文件落盘,完全在浏览器内存中
|
||||
// <EFBFBD>?蝚血<E89D9A>鈭穃<E988AD><E7A983><EFBFBD><EFBFBD><EFBFBD>嗆<EFBFBD>隞嗉氜<E59789>矋<EFBFBD>摰<EFBFBD><E691B0><EFBFBD>冽<EFBFBD>閫<EFBFBD>膥<EFBFBD><E886A5><EFBFBD>銝?
|
||||
import * as XLSX from 'xlsx';
|
||||
|
||||
function exportToExcel(results) {
|
||||
const ws = XLSX.utils.json_to_sheet(exportData);
|
||||
const wb = XLSX.utils.book_new();
|
||||
XLSX.utils.book_append_sheet(wb, ws, '筛选结果');
|
||||
XLSX.writeFile(wb, 'screening-results.xlsx'); // 浏览器下载
|
||||
XLSX.utils.book_append_sheet(wb, ws, '蝑偦<EFBFBD>厩<EFBFBD><EFBFBD>?);
|
||||
XLSX.writeFile(wb, 'screening-results.xlsx'); // 瘚讛<EFBFBD><EFBFBD>其<EFBFBD>頧?
|
||||
}
|
||||
```
|
||||
|
||||
**优点**:
|
||||
- ✅ **零文件落盘**(完全在浏览器内存中生成)
|
||||
- ✅ **无需后端存储**(不占用OSS空间)
|
||||
- ✅ **实时生成**(无异步等待)
|
||||
- ✅ **符合云原生原则**(避免Serverless文件操作)
|
||||
- ✅ **成本低**(不消耗后端资源)
|
||||
**隡条<EFBFBD>**嚗?
|
||||
- <EFBFBD>?**<2A>嗆<EFBFBD>隞嗉氜<E59789>?*嚗<><E59A97><EFBFBD>典銁瘚讛<E7989A><E8AE9B>典<EFBFBD>摮䀝葉<E4809D><E89189><EFBFBD>嚗?
|
||||
- <EFBFBD>?**<2A>𣳇<EFBFBD><F0A3B387>𡒊垢摮睃<E691AE>**嚗<><E59A97><EFBFBD>删鍂OSS蝛粹𡢿嚗?
|
||||
- <EFBFBD>?**摰墧𧒄<E5A2A7><F0A79284><EFBFBD>**嚗<><E59A97>撘<EFBFBD>郊蝑匧<E89D91>嚗?
|
||||
- <EFBFBD>?**蝚血<E89D9A>鈭穃<E988AD><E7A983>笔<EFBFBD><E7AC94>?*嚗<><E59A97><EFBFBD>𥒚erverless<EFBFBD><EFBFBD>辣<EFBFBD>滢<EFBFBD>嚗?
|
||||
- <EFBFBD>?**<2A>鞉𧋦雿?*嚗<><E59A97>瘨<EFBFBD><E798A8>堒<EFBFBD>蝡航<E89DA1>皞琜<E79A9E>
|
||||
|
||||
**限制**:
|
||||
- ⚠️ 适用数据量:<5000条
|
||||
- ⚠️ 生成速度:<1000条约2-3秒
|
||||
**<EFBFBD>𣂼<EFBFBD>**嚗?
|
||||
- <EFBFBD>𩤃<EFBFBD> <20><>鍂<EFBFBD>唳旿<E594B3>𧶏<EFBFBD><5000<EFBFBD>?
|
||||
- <EFBFBD>𩤃<EFBFBD> <20><><EFBFBD><EFBFBD>笔漲嚗?1000<EFBFBD>∠漲2-3蝘?
|
||||
- <20>𩤃<EFBFBD> 銝齿𣈲<E9BDBF><F0A388B2><EFBFBD><EFBFBD><EFBFBD>聢撘𧶏<E69298>憭锭heet<65><74>㦛銵剁<E98AB5>
|
||||
|
||||
**方案B**(未来扩展):后端生成 + OSS存储 ⏸️
|
||||
**<EFBFBD>寞<EFBFBD>B**嚗<>𧊋<EFBFBD>交<EFBFBD>撅𤏪<E69285>嚗𡁜<E59A97>蝡舐<E89DA1><E88890>?+ OSS摮睃<E691AE> <20>賂<EFBFBD>
|
||||
```typescript
|
||||
// ⏸️ 技术债务:当数据量>5000条或需要复杂格式时
|
||||
// 1. 后端生成Excel(内存中)
|
||||
// <EFBFBD>賂<EFBFBD> <20><><EFBFBD>臬<EFBFBD>箏𦛚嚗𡁜<E59A97><F0A1819C>唳旿<E594B3>?5000<30>⊥<EFBFBD><E28AA5><EFBFBD>閬<EFBFBD><E996AC><EFBFBD><EFBFBD>聢撘𤩺𧒄
|
||||
// 1. <EFBFBD>𡒊垢<EFBFBD><EFBFBD><EFBFBD>Excel嚗<EFBFBD><EFBFBD>摮䀝葉嚗?
|
||||
import ExcelJS from 'exceljs';
|
||||
const workbook = new ExcelJS.Workbook();
|
||||
// ... <20><><EFBFBD>Excel
|
||||
|
||||
// 2. ⭐ 上传到OSS(使用平台存储服务)
|
||||
// 2. 潃?銝𠹺<E98A9D><F0A0B9BA>記SS嚗<53>蝙<EFBFBD>典像<E585B8>啣<EFBFBD><E595A3>冽<EFBFBD><E586BD>∴<EFBFBD>
|
||||
import { storage } from '@/common/storage';
|
||||
const buffer = await workbook.xlsx.writeBuffer();
|
||||
const url = await storage.upload(`asl/exports/${Date.now()}.xlsx`, buffer);
|
||||
@@ -137,97 +137,97 @@ const url = await storage.upload(`asl/exports/${Date.now()}.xlsx`, buffer);
|
||||
res.send({ success: true, url });
|
||||
```
|
||||
|
||||
**触发条件**:
|
||||
- 单次导出数据量 >5000条
|
||||
- 需要复杂Excel格式(多Sheet、图表等)
|
||||
**閫血<EFBFBD><EFBFBD>∩辣**嚗?
|
||||
- <EFBFBD>閙活撖澆枂<EFBFBD>唳旿<EFBFBD>?>5000<EFBFBD>?
|
||||
- <EFBFBD><EFBFBD>閬<EFBFBD><EFBFBD><EFBFBD><EFBFBD>xcel<EFBFBD>澆<EFBFBD>嚗<EFBFBD><EFBFBD>Sheet<EFBFBD><EFBFBD>㦛銵函<EFBFBD>嚗?
|
||||
- <20>冽<EFBFBD><E586BD>漤<EFBFBD><E6BCA4>滨垢撖澆枂<E6BE86>⊿▼
|
||||
|
||||
**记录位置**:[技术债务清单 - 优先级4](../../06-技术债务/技术债务清单.md)
|
||||
**霈啣<EFBFBD>雿滨蔭**嚗靀<E59A97><E99D80><EFBFBD>臬<EFBFBD>箏𦛚皜<F0A69B9A><E79A9C> - 隡睃<E99AA1>蝥?](../../06-<EFBFBD><EFBFBD><EFBFBD>臬<EFBFBD>箏𦛚/<2F><><EFBFBD>臬<EFBFBD>箏𦛚皜<F0A69B9A><E79A9C>.md)
|
||||
|
||||
---
|
||||
|
||||
### 2.2 云原生架构检查
|
||||
### 2.2 鈭穃<EFBFBD><EFBFBD><EFBFBD>沲<EFBFBD><EFBFBD><EFBFBD><EFBFBD>?
|
||||
|
||||
基于[云原生开发规范](../../../04-开发规范/08-云原生开发规范.md),本开发计划遵循:
|
||||
<EFBFBD>箔<EFBFBD>[鈭穃<E988AD><E7A983>笔<EFBFBD><E7AC94>𤏸<EFBFBD><F0A48FB8><EFBFBD>(../../../04-撘<><E69298>𤏸<EFBFBD><F0A48FB8>?08-鈭穃<E988AD><E7A983>笔<EFBFBD><E7AC94>𤏸<EFBFBD><F0A48FB8>?md)嚗峕𧋦撘<F0A78BA6><E69298>𤏸恣<F0A48FB8>㘾<EFBFBD>敺迎<E695BA>
|
||||
|
||||
| 检查项 | 要求 | 本计划实现 | 状态 |
|
||||
| 璉<EFBFBD><EFBFBD>仿★ | 閬<><E996AC> | <20>祈恣<E7A588>鍦<EFBFBD><E98DA6>?| <20>嗆<EFBFBD>?|
|
||||
|--------|------|-----------|------|
|
||||
| **存储** | 使用`storage.upload()`,不用`fs.writeFile()` | Excel前端生成,零落盘 | ✅ |
|
||||
| **数据库** | 使用全局`prisma`实例 | 统计API使用全局`prisma` | ✅ |
|
||||
| **长任务** | 异步处理,不阻塞请求 | 统计API <500ms,无需异步 | ✅ |
|
||||
| **日志** | 使用`logger`,不用`console.log` | 后端使用`logger.info/error` | ✅ |
|
||||
| **配置** | 使用`process.env` | 无新增配置 | ✅ |
|
||||
| **计算** | 复杂计算后端完成 | 统计聚合后端完成 | ✅ |
|
||||
| **摮睃<EFBFBD>** | 雿輻鍂`storage.upload()`嚗䔶<EFBFBD><EFBFBD>灼fs.writeFile()` | Excel<EFBFBD>滨垢<EFBFBD><EFBFBD><EFBFBD>嚗屸妟<EFBFBD>賜<EFBFBD> | <EFBFBD>?|
|
||||
| **<EFBFBD>唳旿摨?* | 雿輻鍂<E8BCBB>典<EFBFBD>`prisma`摰硺<E691B0> | 蝏蠘恣API雿輻鍂<E8BCBB>典<EFBFBD>`prisma` | <EFBFBD>?|
|
||||
| **<EFBFBD>蹂遙<EFBFBD>?* | 撘<>郊憭<E9838A><E686AD>嚗䔶<E59A97><E494B6>餃<EFBFBD>霂瑟<E99C82> | 蝏蠘恣API <500ms嚗峕<EFBFBD><EFBFBD><EFBFBD>撘<EFBFBD>郊 | <EFBFBD>?|
|
||||
| **<EFBFBD>亙<EFBFBD>** | 雿輻鍂`logger`嚗䔶<EFBFBD><EFBFBD>灼console.log` | <EFBFBD>𡒊垢雿輻鍂`logger.info/error` | <EFBFBD>?|
|
||||
| **<EFBFBD>滨蔭** | 雿輻鍂`process.env` | <EFBFBD>䭾鰵憓鮋<EFBFBD>蝵?| <20>?|
|
||||
| **霈∠<EFBFBD>** | 憭齿<EFBFBD>霈∠<EFBFBD><EFBFBD>𡒊垢摰峕<EFBFBD> | 蝏蠘恣<E8A098>𡁜<EFBFBD><F0A1819C>𡒊垢摰峕<E691B0> | <EFBFBD>?|
|
||||
|
||||
---
|
||||
|
||||
## 📐 三、页面设计
|
||||
## <EFBFBD><EFBFBD> 銝剹<E98A9D><E589B9>△<EFBFBD>Z挽霈?
|
||||
|
||||
### 3.1 <20>港<EFBFBD>撣<EFBFBD><E692A3>
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────┐
|
||||
│ 标题:标题摘要初筛 - 结果 │
|
||||
│ 说明:筛选结果统计、PRISMA流程图、批量操作和导出 │
|
||||
└─────────────────────────────────────────────────────────┘
|
||||
<EFBFBD>𢞖<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?
|
||||
<EFBFBD>? <20><><EFBFBD>嚗𡁏<E59A97>憸䀹<E686B8>閬<EFBFBD><E996AC>蝑?- 蝏𤘪<E89D8F> <EFBFBD>?
|
||||
<EFBFBD>? 霂湔<E99C82>嚗𡁶<E59A97><F0A181B6>厩<EFBFBD><E58EA9>𦦵<EFBFBD>霈~<E99C88><EFBD9E>RISMA瘚<41><E7989A><EFBFBD>整<EFBFBD><E695B4>鸌<EFBFBD>𤩺<EFBFBD>雿𨅯<E99BBF>撖澆枂 <EFBFBD>?
|
||||
<EFBFBD>婙<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?
|
||||
|
||||
┌─────────────────────────────────────────────────────────┐
|
||||
│ 📊 统计概览(4个卡片 + 待复核提示) │
|
||||
│ ┌───────┐ ┌───────┐ ┌───────┐ ┌───────┐ │
|
||||
│ │ 总数 │ │ 已纳入│ │ 已排除│ │ 待复核│ │
|
||||
│ │ 199 │ │ 85 │ │ 90 │ │ 24 │ │
|
||||
│ │ 篇 │ │ 42.7% │ │ 45.2% │ │ 12.1% │ │
|
||||
│ └───────┘ └───────┘ └───────┘ └───────┘ │
|
||||
│ │
|
||||
│ ⚠️ 提示:还有 24 篇文献待复核,请前往"审核工作台"处理 │
|
||||
└─────────────────────────────────────────────────────────┘
|
||||
<EFBFBD>𢞖<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?
|
||||
<EFBFBD>? <20><> 蝏蠘恣璁<E681A3><E79281>嚗?銝芸㨃<E88AB8>?+ 敺<><E695BA><EFBFBD>豢<EFBFBD>蝷綽<E89DB7> <EFBFBD>?
|
||||
<EFBFBD>? <20>𢞖<EFBFBD><F0A29E96><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?<3F>𢞖<EFBFBD><F0A29E96><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?<3F>𢞖<EFBFBD><F0A29E96><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?<3F>𢞖<EFBFBD><F0A29E96><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>? <EFBFBD>?
|
||||
<EFBFBD>? <20>?<3F>餅㺭 <20>?<3F>?撌脩熙<E884A9>乒<EFBFBD> <20>?撌脫<E6928C><E884AB>手<EFBFBD> <20>?敺<><E695BA><EFBFBD>詹<EFBFBD> <EFBFBD>?
|
||||
<EFBFBD>? <20>? 199 <EFBFBD>?<3F>? 85 <EFBFBD>?<3F>? 90 <EFBFBD>?<3F>? 24 <EFBFBD>? <EFBFBD>?
|
||||
<EFBFBD>? <20>? 蝭? <20>?<3F>?42.7% <EFBFBD>?<3F>?45.2% <EFBFBD>?<3F>?12.1% <EFBFBD>? <EFBFBD>?
|
||||
<EFBFBD>? <20>婙<EFBFBD><E5A999><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?<3F>婙<EFBFBD><E5A999><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?<3F>婙<EFBFBD><E5A999><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?<3F>婙<EFBFBD><E5A999><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>? <EFBFBD>?
|
||||
<EFBFBD>? <EFBFBD>?
|
||||
<EFBFBD>? <20>𩤃<EFBFBD> <20>鞟內嚗朞<E59A97><E69C9E>?24 蝭<><E89DAD><EFBFBD>桀<EFBFBD>憭齿瓲嚗諹窈<E8ABB9>滚<EFBFBD>"摰⊥瓲撌乩<E6928C><E4B9A9>?憭<><E686AD> <EFBFBD>?
|
||||
<EFBFBD>婙<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?
|
||||
|
||||
┌─────────────────────────────────────────────────────────┐
|
||||
│ 📈 排除原因统计(柱状图) │
|
||||
│ ┌─────────────────────────────────────────────┐ │
|
||||
│ │ P不匹配(人群) ████████████████ 40篇 (44%) │ │
|
||||
│ │ I不匹配(干预) ████████ 25篇 (28%) │ │
|
||||
│ │ S不匹配(研究设计)████ 15篇 (17%) │ │
|
||||
│ │ 其他原因 ██ 10篇 (11%) │ │
|
||||
│ └─────────────────────────────────────────────┘ │
|
||||
└─────────────────────────────────────────────────────────┘
|
||||
<EFBFBD>𢞖<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?
|
||||
<EFBFBD>? <20><> <20>㘾膄<E398BE>笔<EFBFBD>蝏蠘恣嚗<E681A3><E59A97><EFBFBD>嗅㦛嚗? <EFBFBD>?
|
||||
<EFBFBD>? <20>𢞖<EFBFBD><F0A29E96><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>? <EFBFBD>?
|
||||
<EFBFBD>? <20>?P銝滚龪<E6BB9A>㵪<EFBFBD>鈭箇黎嚗? <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 40蝭?(44%) <EFBFBD>? <EFBFBD>?
|
||||
<EFBFBD>? <20>?I銝滚龪<E6BB9A>㵪<EFBFBD>撟脤<E6929F>嚗? <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 25蝭?(28%) <EFBFBD>? <EFBFBD>?
|
||||
<EFBFBD>? <20>?S銝滚龪<E6BB9A>㵪<EFBFBD><E3B5AA>𠉛弦霈曇恣嚗争<E59A97><E4BA89><EFBFBD><EFBFBD><EFBFBD>?15蝭?(17%) <EFBFBD>? <EFBFBD>?
|
||||
<EFBFBD>? <20>?<3F>嗡<EFBFBD><E597A1>笔<EFBFBD> <EFBFBD><EFBFBD><EFBFBD> 10蝭?(11%) <EFBFBD>? <EFBFBD>?
|
||||
<EFBFBD>? <20>婙<EFBFBD><E5A999><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>? <EFBFBD>?
|
||||
<EFBFBD>婙<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?
|
||||
|
||||
┌─────────────────────────────────────────────────────────┐
|
||||
│ 📋 结果列表(Tabs + 单行表格 + 批量操作) │
|
||||
│ ┌─────────────────────────────────────────────────┐ │
|
||||
│ │ [全部 199] [已纳入 85] [已排除 90] [待复核 24] │ │
|
||||
│ ├─────────────────────────────────────────────────┤ │
|
||||
│ │ [导出全部] [导出当前页] [导出选中项] │ │
|
||||
│ ├─────────────────────────────────────────────────┤ │
|
||||
│ │ ☑ 序号 | 标题 | 最终决策 | 排除原因 | 操作 │ │
|
||||
│ │ ☐ 1 | ... | 已纳入 | - | [查看] │ │
|
||||
│ │ ☐ 2 | ... | 已排除 | P不匹配 | [查看] │ │
|
||||
│ │ ☐ 3 | ... | 待复核 | 冲突 | [复核] │ │
|
||||
│ └─────────────────────────────────────────────────┘ │
|
||||
└─────────────────────────────────────────────────────────┘
|
||||
<EFBFBD>𢞖<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?
|
||||
<EFBFBD>? <20><> 蝏𤘪<E89D8F><F0A498AA>𡑒”嚗㇍abs + <20>閗<EFBFBD>銵冽聢 + <20>寥<EFBFBD><E5AFA5>滢<EFBFBD>嚗? <EFBFBD>?
|
||||
<EFBFBD>? <20>𢞖<EFBFBD><F0A29E96><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>? <EFBFBD>?
|
||||
<EFBFBD>? <20>?[<5B>券<EFBFBD> 199] [撌脩熙<E884A9>?85] [撌脫<E6928C><E884AB>?90] [敺<><E695BA><EFBFBD>?24] <EFBFBD>? <EFBFBD>?
|
||||
<EFBFBD>? <20>鎿<EFBFBD><E98EBF><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>? <EFBFBD>?
|
||||
<EFBFBD>? <20>?[撖澆枂<E6BE86>券<EFBFBD>] [撖澆枂敶枏<E695B6>憿琶 [撖澆枂<E6BE86>劐葉憿鉛 <EFBFBD>? <EFBFBD>?
|
||||
<EFBFBD>? <20>鎿<EFBFBD><E98EBF><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>? <EFBFBD>?
|
||||
<EFBFBD>? <20>?<3F>?摨誩噡 | <20><><EFBFBD> | <20><>蝏<EFBFBD><E89D8F>蝑?| <20>㘾膄<E398BE>笔<EFBFBD> | <20>滢<EFBFBD> <EFBFBD>? <EFBFBD>?
|
||||
<EFBFBD>? <20>?<3F>?1 | ... | 撌脩熙<EFBFBD>? | - | [<EFBFBD>亦<EFBFBD>] <EFBFBD>? <EFBFBD>?
|
||||
<EFBFBD>? <20>?<3F>?2 | ... | 撌脫<EFBFBD><EFBFBD>? | P銝滚龪<E6BB9A>? | [<EFBFBD>亦<EFBFBD>] <EFBFBD>? <EFBFBD>?
|
||||
<EFBFBD>? <20>?<3F>?3 | ... | 敺<EFBFBD><EFBFBD><EFBFBD>? | <EFBFBD>脩<EFBFBD> | [憭齿瓲] <EFBFBD>? <EFBFBD>?
|
||||
<EFBFBD>? <20>婙<EFBFBD><E5A999><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>? <EFBFBD>?
|
||||
<EFBFBD>婙<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?
|
||||
```
|
||||
|
||||
### 3.2 銵冽聢霈曇恣
|
||||
|
||||
**列定义**(单行表格,区别于审核工作台的双行):
|
||||
**<EFBFBD>堒<EFBFBD>銋?*嚗<><E59A97>銵諹”<E8ABB9>潘<EFBFBD><E6BD98>箏<EFBFBD>鈭𤾸恣<F0A4BEB8>詨極雿𨅯蝱<F0A885AF><E89DB1><EFBFBD>銵䕘<E98AB5>嚗?
|
||||
|
||||
| <20>堒<EFBFBD> | 摰賢漲 | 霂湔<E99C82> |
|
||||
|------|------|------|
|
||||
| 选择 | 50px | Checkbox多选 |
|
||||
| <EFBFBD>㗇𥋘 | 50px | Checkbox憭𡁻<EFBFBD>?|
|
||||
| 摨誩噡 | 60px | 銵<>噡 |
|
||||
| <20><>讃<EFBFBD><E8AE83><EFBFBD> | 400px | Tooltip<69>曄內<E69B84>冽<EFBFBD> |
|
||||
| 最终决策 | 100px | Tag显示(纳入/排除/待定) |
|
||||
| <EFBFBD><EFBFBD>蝏<EFBFBD><EFBFBD>蝑?| 100px | Tag<EFBFBD>曄內嚗<EFBFBD>熙<EFBFBD>?<3F>㘾膄/敺<><E695BA>嚗?|
|
||||
| <20>㘾膄<E398BE>笔<EFBFBD> | 150px | <20>曄內<E69B84>瑚<EFBFBD><E7919A>笔<EFBFBD> |
|
||||
| 置信度 | 80px | DeepSeek置信度 |
|
||||
| 蝵桐縑摨?| 80px | DeepSeek蝵桐縑摨?|
|
||||
| <20>滢<EFBFBD> | 100px | <20>亦<EFBFBD>霂行<E99C82><E8A18C>厰僼 |
|
||||
|
||||
**关键区别**:
|
||||
- **审核工作台**:双行表格,显示DS+Qwen对比,强调冲突
|
||||
- **初筛结果**:**单行表格**,显示最终决策,强调结果
|
||||
**<EFBFBD>喲睸<EFBFBD>箏<EFBFBD>**嚗?
|
||||
- **摰⊥瓲撌乩<EFBFBD><EFBFBD>?*嚗𡁜<E59A97>銵諹”<E8ABB9>潘<EFBFBD><E6BD98>曄內DS+Qwen撖寞<E69296>嚗<EFBFBD>撩靚<E692A9><E99D9A>蝒?
|
||||
- **<EFBFBD>萘<EFBFBD>蝏𤘪<EFBFBD>**嚗?*<2A>閗<EFBFBD>銵冽聢**嚗峕遬蝷箸<E89DB7>蝏<EFBFBD><E89D8F>蝑吔<E89D91>撘箄<E69298>蝏𤘪<E89D8F>
|
||||
|
||||
---
|
||||
|
||||
## 🔧 四、后端开发
|
||||
## <EFBFBD>圲 <20>䜘<EFBFBD><E49C98><EFBFBD>蝡臬<E89DA1><E887AC>?
|
||||
|
||||
### 4.1 <20>啣<EFBFBD>蝏蠘恣API
|
||||
|
||||
@@ -238,7 +238,7 @@ GET /api/v1/asl/projects/:projectId/statistics
|
||||
|
||||
#### 霂瑟<E99C82><E7919F><EFBFBD>㺭
|
||||
```
|
||||
无
|
||||
<EFBFBD>?
|
||||
```
|
||||
|
||||
#### <20>滚<EFBFBD><E6BB9A>澆<EFBFBD>
|
||||
@@ -253,9 +253,9 @@ GET /api/v1/asl/projects/:projectId/statistics
|
||||
"conflict": 24,
|
||||
"reviewed": 175,
|
||||
"exclusionReasons": {
|
||||
"P不匹配(人群)": 40,
|
||||
"I不匹配(干预)": 25,
|
||||
"S不匹配(研究设计)": 15,
|
||||
"P銝滚龪<EFBFBD>㵪<EFBFBD>鈭箇黎嚗?: 40,
|
||||
"I銝滚龪<EFBFBD>㵪<EFBFBD>撟脤<EFBFBD>嚗?: 25,
|
||||
"S銝滚龪<EFBFBD>㵪<EFBFBD><EFBFBD>𠉛弦霈曇恣嚗?: 15,
|
||||
"<EFBFBD>嗡<EFBFBD><EFBFBD>笔<EFBFBD>": 10
|
||||
},
|
||||
"includedRate": "42.7",
|
||||
@@ -270,7 +270,7 @@ GET /api/v1/asl/projects/:projectId/statistics
|
||||
// backend/src/modules/asl/controllers/screeningController.ts
|
||||
|
||||
/**
|
||||
* 获取项目筛选统计数据(云原生:后端聚合)
|
||||
* <EFBFBD>瑕<EFBFBD>憿寧𤌍蝑偦<EFBFBD>厩<EFBFBD>霈⊥㺭<EFBFBD>殷<EFBFBD>鈭穃<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>𡒊垢<EFBFBD>𡁜<EFBFBD>嚗?
|
||||
* GET /api/v1/asl/projects/:projectId/statistics
|
||||
*/
|
||||
export async function getProjectStatistics(
|
||||
@@ -290,7 +290,7 @@ export async function getProjectStatistics(
|
||||
return reply.status(404).send({ error: 'Project not found' });
|
||||
}
|
||||
|
||||
// 2. ⭐ 云原生:使用Prisma聚合查询(并行)
|
||||
// 2. 潃?鈭穃<E988AD><E7A983><EFBFBD><EFBFBD>雿輻鍂Prisma<6D>𡁜<EFBFBD><F0A1819C>亥砭嚗<E7A0AD>僎銵䕘<E98AB5>
|
||||
const [
|
||||
total,
|
||||
includedCount,
|
||||
@@ -367,13 +367,13 @@ export async function getProjectStatistics(
|
||||
}
|
||||
|
||||
/**
|
||||
* 辅助函数:从AI判断中提取排除原因
|
||||
* 颲<EFBFBD>𨭌<EFBFBD>賣㺭嚗帋<EFBFBD>AI<EFBFBD>斗鱏銝剜<EFBFBD><EFBFBD>𡝗<EFBFBD><EFBFBD>文<EFBFBD><EFBFBD>?
|
||||
*/
|
||||
function extractAutoReason(result: any): string {
|
||||
if (result.dsPJudgment === 'mismatch') return 'P不匹配(人群)';
|
||||
if (result.dsIJudgment === 'mismatch') return 'I不匹配(干预)';
|
||||
if (result.dsCJudgment === 'mismatch') return 'C不匹配(对照)';
|
||||
if (result.dsSJudgment === 'mismatch') return 'S不匹配(研究设计)';
|
||||
if (result.dsPJudgment === 'mismatch') return 'P銝滚龪<EFBFBD>㵪<EFBFBD>鈭箇黎嚗?;
|
||||
if (result.dsIJudgment === 'mismatch') return 'I銝滚龪<EFBFBD>㵪<EFBFBD>撟脤<EFBFBD>嚗?;
|
||||
if (result.dsCJudgment === 'mismatch') return 'C銝滚龪<EFBFBD>㵪<EFBFBD>撖寧<EFBFBD>嚗?;
|
||||
if (result.dsSJudgment === 'mismatch') return 'S銝滚龪<EFBFBD>㵪<EFBFBD><EFBFBD>𠉛弦霈曇恣嚗?;
|
||||
return '<27>嗡<EFBFBD><E597A1>笔<EFBFBD>';
|
||||
}
|
||||
```
|
||||
@@ -382,7 +382,7 @@ function extractAutoReason(result: any): string {
|
||||
```typescript
|
||||
// backend/src/modules/asl/routes/index.ts
|
||||
|
||||
// 添加到路由注册
|
||||
// 瘛餃<EFBFBD><EFBFBD>啗楝<EFBFBD>望釣<EFBFBD>?
|
||||
fastify.get(
|
||||
'/projects/:projectId/statistics',
|
||||
screeningController.getProjectStatistics
|
||||
@@ -391,9 +391,9 @@ fastify.get(
|
||||
|
||||
---
|
||||
|
||||
## 💻 五、前端开发
|
||||
## <EFBFBD>凃 鈭𢛵<E988AD><F0A29BB5><EFBFBD>蝡臬<E89DA1><E887AC>?
|
||||
|
||||
### 5.1 API客户端
|
||||
### 5.1 API摰X<EFBFBD>蝡?
|
||||
|
||||
```typescript
|
||||
// frontend-v2/src/modules/asl/api/index.ts
|
||||
@@ -440,7 +440,7 @@ import { ScreeningResult } from '../types';
|
||||
/**
|
||||
* 撖澆枂蝑偦<E89D91>厩<EFBFBD><E58EA9>𨅯<EFBFBD>Excel嚗<6C><E59A97><EFBFBD>毺<EFBFBD>嚗𡁜<E59A97>蝡舐<E89DA1><E88890>琜<EFBFBD><E7909C>嗆<EFBFBD>隞嗉氜<E59789>矋<EFBFBD>
|
||||
*
|
||||
* @param results 筛选结果数组
|
||||
* @param results 蝑偦<EFBFBD>厩<EFBFBD><EFBFBD>𨀣㺭蝏?
|
||||
* @param options 撖澆枂<E6BE86>厰★
|
||||
*/
|
||||
export function exportScreeningResults(
|
||||
@@ -455,25 +455,25 @@ export function exportScreeningResults(
|
||||
'摨誩噡': idx + 1,
|
||||
'<27><>讃<EFBFBD><E8AE83><EFBFBD>': r.literature.title,
|
||||
'<27>䁅<EFBFBD>': r.literature.abstract || '',
|
||||
'作者': r.literature.authors || '',
|
||||
'雿𡏭<EFBFBD>?: r.literature.authors || '',
|
||||
'<EFBFBD>笔<EFBFBD>': r.literature.journal || '',
|
||||
'<EFBFBD>𤏸”撟港遢': r.literature.publicationYear || '',
|
||||
'PMID': r.literature.pmid || '',
|
||||
'DOI': r.literature.doi || '',
|
||||
'DeepSeek<EFBFBD>喟<EFBFBD>': r.dsConclusion || '',
|
||||
'DeepSeek置信度': r.dsConfidence ? `${(r.dsConfidence * 100).toFixed(0)}%` : '',
|
||||
'DeepSeek蝵桐縑摨?: r.dsConfidence ? `${(r.dsConfidence * 100).toFixed(0)}%` : '',
|
||||
'DeepSeek<65><6B>眏': r.dsReason || '',
|
||||
'Qwen<65>喟<EFBFBD>': r.qwenConclusion || '',
|
||||
'Qwen置信度': r.qwenConfidence ? `${(r.qwenConfidence * 100).toFixed(0)}%` : '',
|
||||
'Qwen蝵桐縑摨?: r.qwenConfidence ? `${(r.qwenConfidence * 100).toFixed(0)}%` : '',
|
||||
'Qwen<EFBFBD><EFBFBD>眏': r.qwenReason || '',
|
||||
'是否冲突': r.conflictStatus === 'conflict' ? '是' : '否',
|
||||
'最终决策': r.finalDecision || '待定',
|
||||
'<EFBFBD>臬炏<EFBFBD>脩<EFBFBD>': r.conflictStatus === 'conflict' ? '<EFBFBD>? : '<EFBFBD>?,
|
||||
'<EFBFBD><EFBFBD>蝏<EFBFBD><EFBFBD>蝑?: r.finalDecision || '敺<EFBFBD><EFBFBD>',
|
||||
'<27>㘾膄<E398BE>笔<EFBFBD>': r.exclusionReason || '',
|
||||
'复核人': r.finalDecisionBy || '',
|
||||
'憭齿瓲鈭?: r.finalDecisionBy || '',
|
||||
'憭齿瓲<EFBFBD>園𡢿': r.finalDecisionAt ? new Date(r.finalDecisionAt).toLocaleString('zh-CN') : '',
|
||||
}));
|
||||
|
||||
// 2. ⭐ 生成Excel(完全在内存中,零文件落盘)
|
||||
// 2. 潃?<3F><><EFBFBD>Excel嚗<6C><E59A97><EFBFBD>典銁<E585B8><E98A81><EFBFBD>銝哨<E98A9D><E593A8>嗆<EFBFBD>隞嗉氜<E59789>矋<EFBFBD>
|
||||
const ws = XLSX.utils.json_to_sheet(exportData);
|
||||
|
||||
// 霈曄蔭<E69B84>堒捐
|
||||
@@ -481,33 +481,33 @@ export function exportScreeningResults(
|
||||
{ wch: 6 }, // 摨誩噡
|
||||
{ wch: 50 }, // <20><><EFBFBD>
|
||||
{ wch: 60 }, // <20>䁅<EFBFBD>
|
||||
{ wch: 30 }, // 作者
|
||||
{ wch: 30 }, // 雿𡏭<E99BBF>?
|
||||
{ wch: 30 }, // <20>笔<EFBFBD>
|
||||
{ wch: 10 }, // 撟港遢
|
||||
{ wch: 12 }, // PMID
|
||||
{ wch: 25 }, // DOI
|
||||
{ wch: 12 }, // DS<44>喟<EFBFBD>
|
||||
{ wch: 12 }, // DS置信度
|
||||
{ wch: 12 }, // DS蝵桐縑摨?
|
||||
{ wch: 40 }, // DS<44><53>眏
|
||||
{ wch: 12 }, // Qwen<65>喟<EFBFBD>
|
||||
{ wch: 12 }, // Qwen置信度
|
||||
{ wch: 12 }, // Qwen蝵桐縑摨?
|
||||
{ wch: 40 }, // Qwen<65><6E>眏
|
||||
{ wch: 10 }, // <20>脩<EFBFBD>
|
||||
{ wch: 12 }, // 最终决策
|
||||
{ wch: 12 }, // <20><>蝏<EFBFBD><E89D8F>蝑?
|
||||
{ wch: 30 }, // <20>㘾膄<E398BE>笔<EFBFBD>
|
||||
{ wch: 15 }, // 复核人
|
||||
{ wch: 15 }, // 憭齿瓲鈭?
|
||||
{ wch: 20 }, // 憭齿瓲<E9BDBF>園𡢿
|
||||
];
|
||||
|
||||
const wb = XLSX.utils.book_new();
|
||||
XLSX.utils.book_append_sheet(wb, ws, '筛选结果');
|
||||
XLSX.utils.book_append_sheet(wb, ws, '蝑偦<EFBFBD>厩<EFBFBD><EFBFBD>?);
|
||||
|
||||
// 3. 生成文件名
|
||||
// 3. <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>辣<EFBFBD>?
|
||||
const timestamp = new Date().toISOString().slice(0, 10);
|
||||
const filterSuffix = options.filter && options.filter !== 'all' ? `_${options.filter}` : '';
|
||||
const filename = `${options.projectName || '筛选结果'}${filterSuffix}_${timestamp}.xlsx`;
|
||||
const filename = `${options.projectName || '蝑偦<EFBFBD>厩<EFBFBD><EFBFBD>?}${filterSuffix}_${timestamp}.xlsx`;
|
||||
|
||||
// 4. ⭐ 触发浏览器下载(零文件落盘)
|
||||
// 4. 潃?閫血<E996AB>瘚讛<E7989A><E8AE9B>其<EFBFBD>頧踝<E9A0A7><E8B89D>嗆<EFBFBD>隞嗉氜<E59789>矋<EFBFBD>
|
||||
XLSX.writeFile(wb, filename);
|
||||
}
|
||||
```
|
||||
@@ -541,7 +541,7 @@ const ScreeningResults = () => {
|
||||
const page = parseInt(searchParams.get('page') || '1', 10);
|
||||
const pageSize = 20;
|
||||
|
||||
// 1. ⭐ 获取统计数据(云原生:后端聚合)
|
||||
// 1. 潃?<3F>瑕<EFBFBD>蝏蠘恣<E8A098>唳旿嚗<E697BF><E59A97><EFBFBD>毺<EFBFBD>嚗𡁜<E59A97>蝡航<E89DA1><E888AA><EFBFBD><EFBFBD>
|
||||
const { data: statsData, isLoading: statsLoading } = useQuery({
|
||||
queryKey: ['projectStatistics', projectId],
|
||||
queryFn: () => aslApi.getProjectStatistics(projectId!),
|
||||
@@ -562,7 +562,7 @@ const ScreeningResults = () => {
|
||||
enabled: !!projectId,
|
||||
});
|
||||
|
||||
// 3. ⭐ 导出Excel(前端生成,云原生)
|
||||
// 3. 潃?撖澆枂Excel嚗<6C><E59A97>蝡舐<E89DA1><E88890>琜<EFBFBD>鈭穃<E988AD><E7A983><EFBFBD><EFBFBD>
|
||||
const handleExport = async (filter: string = 'all') => {
|
||||
try {
|
||||
message.loading('甇<>銁<EFBFBD><E98A81><EFBFBD>Excel...', 0);
|
||||
@@ -579,7 +579,7 @@ const ScreeningResults = () => {
|
||||
return;
|
||||
}
|
||||
|
||||
// ⭐ 前端生成Excel(零文件落盘)
|
||||
// 潃?<3F>滨垢<E6BBA8><E59EA2><EFBFBD>Excel嚗<6C>妟<EFBFBD><E5A69F>辣<EFBFBD>賜<EFBFBD>嚗?
|
||||
exportScreeningResults(data.items, {
|
||||
filter,
|
||||
projectName: `憿寧𤌍${projectId!.slice(0, 8)}`,
|
||||
@@ -593,7 +593,7 @@ const ScreeningResults = () => {
|
||||
}
|
||||
};
|
||||
|
||||
// 4. 批量导出选中项
|
||||
// 4. <EFBFBD>寥<EFBFBD>撖澆枂<EFBFBD>劐葉憿?
|
||||
const handleExportSelected = () => {
|
||||
if (selectedRowKeys.length === 0) {
|
||||
message.warning('霂瑕<E99C82><E79195>㗇𥋘閬<F0A58B98>紡<EFBFBD>箇<EFBFBD>霈啣<E99C88>');
|
||||
@@ -611,8 +611,8 @@ const ScreeningResults = () => {
|
||||
message.success(`<EFBFBD>𣂼<EFBFBD>撖澆枂 ${selectedResults.length} <EFBFBD>∟扇敶𧄧);
|
||||
};
|
||||
|
||||
// 表格列定义、Tab配置等...
|
||||
// (完整代码见实际实现)
|
||||
// 銵冽聢<EFBFBD>堒<EFBFBD>銋剹<EFBFBD><EFBFBD>ab<EFBFBD>滨蔭蝑?..
|
||||
// 嚗<EFBFBD><EFBFBD><EFBFBD>港誨<EFBFBD><EFBFBD><EFBFBD>摰鮋<EFBFBD>摰䂿緵嚗?
|
||||
};
|
||||
|
||||
export default ScreeningResults;
|
||||
@@ -620,177 +620,177 @@ export default ScreeningResults;
|
||||
|
||||
---
|
||||
|
||||
## 📅 六、开发任务分解
|
||||
## <EFBFBD><EFBFBD> <20>准<EFBFBD><E58786><EFBFBD><EFBFBD>睲遙<E79DB2>∪<EFBFBD>閫?
|
||||
|
||||
### Phase 1:后端统计API(Day 16上午)⏱️ 2小时
|
||||
### Phase 1嚗𡁜<EFBFBD>蝡舐<EFBFBD>霈,PI嚗㇄ay 16銝𠰴<E98A9D>嚗争𪃸儭?2撠𤩺𧒄
|
||||
|
||||
**任务**:
|
||||
1. 在 `screeningController.ts` 中实现 `getProjectStatistics`
|
||||
**隞餃𦛚**嚗?
|
||||
1. <EFBFBD>?`screeningController.ts` 銝剖<EFBFBD><EFBFBD>?`getProjectStatistics`
|
||||
2. 雿輻鍂Prisma<6D>𡁜<EFBFBD><F0A1819C>亥砭嚗<E7A0AD>僎銵峕䰻霂V<E99C82><EFBCB6>吔<EFBFBD>
|
||||
3. 摰䂿緵<E482BF>㘾膄<E398BE>笔<EFBFBD><E7AC94>𣂼<EFBFBD><F0A382BC>餉<EFBFBD> `extractAutoReason`
|
||||
4. 在 `routes/index.ts` 中注册路由
|
||||
4. <EFBFBD>?`routes/index.ts` 銝剜釣<EFBFBD>諹楝<EFBFBD>?
|
||||
5. Postman瘚贝<E7989A>API
|
||||
|
||||
**验收标准**:
|
||||
- ✅ API返回正确统计数据
|
||||
- ✅ 性能良好(<500ms)
|
||||
- ✅ 符合云原生原则(后端聚合)
|
||||
**撉峕𤣰<EFBFBD><EFBFBD><EFBFBD>**嚗?
|
||||
- <EFBFBD>?API餈𥪜<EFBFBD>甇<EFBFBD>&蝏蠘恣<EFBFBD>唳旿
|
||||
- <EFBFBD>?<3F>扯<EFBFBD><E689AF>臬末嚗?500ms嚗?
|
||||
- <EFBFBD>?蝚血<E89D9A>鈭穃<E988AD><E7A983>笔<EFBFBD><E7AC94>辷<EFBFBD><E8BEB7>𡒊垢<F0A1928A>𡁜<EFBFBD>嚗?
|
||||
|
||||
**文件清单**:
|
||||
**<EFBFBD><EFBFBD>辣皜<EFBFBD><EFBFBD>**嚗?
|
||||
- `backend/src/modules/asl/controllers/screeningController.ts`
|
||||
- `backend/src/modules/asl/routes/index.ts`
|
||||
|
||||
---
|
||||
|
||||
### Phase 2:前端API客户端(Day 16上午)⏱️ 30分钟
|
||||
### Phase 2嚗𡁜<EFBFBD>蝡涉PI摰X<EFBFBD>蝡荔<EFBFBD>Day 16銝𠰴<E98A9D>嚗争𪃸儭?30<33><30><EFBFBD>
|
||||
|
||||
**任务**:
|
||||
1. 在 `api/index.ts` 中添加 `getProjectStatistics`
|
||||
2. 在 `types/index.ts` 中添加 `ProjectStatistics` 类型
|
||||
**隞餃𦛚**嚗?
|
||||
1. <EFBFBD>?`api/index.ts` 銝剜溶<EFBFBD>?`getProjectStatistics`
|
||||
2. <EFBFBD>?`types/index.ts` 銝剜溶<EFBFBD>?`ProjectStatistics` 蝐餃<EFBFBD>
|
||||
|
||||
**验收标准**:
|
||||
- ✅ API调用正常
|
||||
- ✅ TypeScript类型正确
|
||||
**撉峕𤣰<EFBFBD><EFBFBD><EFBFBD>**嚗?
|
||||
- <EFBFBD>?API靚<EFBFBD>鍂甇<EFBFBD>虜
|
||||
- <EFBFBD>?TypeScript蝐餃<EFBFBD>甇<EFBFBD>&
|
||||
|
||||
**文件清单**:
|
||||
**<EFBFBD><EFBFBD>辣皜<EFBFBD><EFBFBD>**嚗?
|
||||
- `frontend-v2/src/modules/asl/api/index.ts`
|
||||
- `frontend-v2/src/modules/asl/types/index.ts`
|
||||
|
||||
---
|
||||
|
||||
### Phase 3:统计概览卡片(Day 16上午)⏱️ 1.5小时
|
||||
### Phase 3嚗𡁶<EFBFBD>霈⊥<EFBFBD>閫<EFBFBD>㨃<EFBFBD><EFBFBD><EFBFBD>Day 16銝𠰴<E98A9D>嚗争𪃸儭?1.5撠𤩺𧒄
|
||||
|
||||
**任务**:
|
||||
1. 实现统计卡片组件(4个卡片)
|
||||
2. 实现"待复核"提示Alert
|
||||
3. 实现PRISMA排除统计(柱状图)
|
||||
**隞餃𦛚**嚗?
|
||||
1. 摰䂿緵蝏蠘恣<EFBFBD>∠<EFBFBD>蝏<EFBFBD>辣嚗?銝芸㨃<E88AB8><E3A883><EFBFBD>
|
||||
2. 摰䂿緵"敺<><E695BA><EFBFBD>?<3F>鞟內Alert
|
||||
3. 摰䂿緵PRISMA<EFBFBD>㘾膄蝏蠘恣嚗<EFBFBD><EFBFBD><EFBFBD>嗅㦛嚗?
|
||||
|
||||
**验收标准**:
|
||||
- ✅ 统计数据正确显示
|
||||
- ✅ 排除原因柱状图清晰
|
||||
- ✅ "待复核"提示醒目
|
||||
**撉峕𤣰<EFBFBD><EFBFBD><EFBFBD>**嚗?
|
||||
- <EFBFBD>?蝏蠘恣<E8A098>唳旿甇<E697BF>&<EFBFBD>曄內
|
||||
- <EFBFBD>?<3F>㘾膄<E398BE>笔<EFBFBD><E7AC94>梁𠶖<E6A281>暹<EFBFBD><E69AB9>?
|
||||
- <EFBFBD>?"敺<><E695BA><EFBFBD>?<3F>鞟內<E99E9F>垍𤌍
|
||||
|
||||
**文件清单**:
|
||||
**<EFBFBD><EFBFBD>辣皜<EFBFBD><EFBFBD>**嚗?
|
||||
- `frontend-v2/src/modules/asl/pages/ScreeningResults.tsx`
|
||||
|
||||
---
|
||||
|
||||
### Phase 4:结果列表Tab(Day 16下午)⏱️ 3小时
|
||||
### Phase 4嚗𡁶<EFBFBD><EFBFBD>𨅯<EFBFBD>銵汽ab嚗㇄ay 16銝见<E98A9D>嚗争𪃸儭?3撠𤩺𧒄
|
||||
|
||||
**任务**:
|
||||
1. 实现Tab切换(全部/已纳入/已排除/待复核)
|
||||
**隞餃𦛚**嚗?
|
||||
1. 摰䂿緵Tab<EFBFBD><EFBFBD>揢嚗<EFBFBD><EFBFBD><EFBFBD>?撌脩熙<E884A9>?撌脫<E6928C><E884AB>?敺<><E695BA><EFBFBD>賂<EFBFBD>
|
||||
2. <20>𥕦遣<F0A595A6>閗<EFBFBD>銵冽聢嚗<E881A2>躹<EFBFBD>思<EFBFBD>摰⊥瓲撌乩<E6928C><E4B9A9>堆<EFBFBD>
|
||||
3. 实现Checkbox多选
|
||||
4. 实现详情查看Modal(复用审核工作台的Drawer)
|
||||
3. 摰䂿緵Checkbox憭𡁻<EFBFBD>?
|
||||
4. 摰䂿緵霂行<EFBFBD><EFBFBD>亦<EFBFBD>Modal嚗<EFBFBD><EFBFBD><EFBFBD>典恣<EFBFBD>詨極雿𨅯蝱<EFBFBD><EFBFBD>rawer嚗?
|
||||
|
||||
**验收标准**:
|
||||
- ✅ Tab切换正常
|
||||
- ✅ 表格数据正确
|
||||
- ✅ 可多选行
|
||||
- ✅ 可查看详情
|
||||
**撉峕𤣰<EFBFBD><EFBFBD><EFBFBD>**嚗?
|
||||
- <EFBFBD>?Tab<EFBFBD><EFBFBD>揢甇<EFBFBD>虜
|
||||
- <EFBFBD>?銵冽聢<E586BD>唳旿甇<E697BF>&
|
||||
- <EFBFBD>?<3F>臬<EFBFBD><E887AC>㕑<EFBFBD>
|
||||
- <EFBFBD>?<3F>舀䰻<E88880>贝祕<E8B49D>?
|
||||
|
||||
**文件清单**:
|
||||
**<EFBFBD><EFBFBD>辣皜<EFBFBD><EFBFBD>**嚗?
|
||||
- `frontend-v2/src/modules/asl/pages/ScreeningResults.tsx`
|
||||
|
||||
---
|
||||
|
||||
### Phase 5:Excel导出(Day 17上午)⏱️ 2小时
|
||||
### Phase 5嚗鍃xcel撖澆枂嚗㇄ay 17銝𠰴<E98A9D>嚗争𪃸儭?2撠𤩺𧒄
|
||||
|
||||
**任务**:
|
||||
**隞餃𦛚**嚗?
|
||||
1. <20>𥕦遣 `excelExport.ts` 撌亙<E6928C><E4BA99><EFBFBD>辣
|
||||
2. 实现前端导出逻辑(使用 `xlsx`)
|
||||
3. 添加导出按钮(导出全部/导出当前页/导出选中项)
|
||||
4. 支持过滤导出(全部/仅纳入/仅排除)
|
||||
2. 摰䂿緵<EFBFBD>滨垢撖澆枂<EFBFBD>餉<EFBFBD>嚗<EFBFBD>蝙<EFBFBD>?`xlsx`嚗?
|
||||
3. 瘛餃<EFBFBD>撖澆枂<EFBFBD>厰僼嚗<EFBFBD>紡<EFBFBD>箏<EFBFBD><EFBFBD>?撖澆枂敶枏<E695B6>憿?撖澆枂<E6BE86>劐葉憿對<E686BF>
|
||||
4. <EFBFBD>舀<EFBFBD>餈<EFBFBD>誘撖澆枂嚗<EFBFBD><EFBFBD><EFBFBD>?隞<>熙<EFBFBD>?隞<><E99A9E><EFBFBD>歹<EFBFBD>
|
||||
|
||||
**验收标准**:
|
||||
- ✅ 可导出Excel
|
||||
- ✅ 数据完整
|
||||
- ✅ 零文件落盘(云原生)
|
||||
- ✅ 生成速度<3秒(<1000条)
|
||||
**撉峕𤣰<EFBFBD><EFBFBD><EFBFBD>**嚗?
|
||||
- <EFBFBD>?<3F>臬紡<E887AC>慟xcel
|
||||
- <EFBFBD>?<3F>唳旿摰峕㟲
|
||||
- <EFBFBD>?<3F>嗆<EFBFBD>隞嗉氜<E59789>矋<EFBFBD>鈭穃<E988AD><E7A983><EFBFBD><EFBFBD>
|
||||
- <EFBFBD>?<3F><><EFBFBD><EFBFBD>笔漲<3蝘𡜐<E89D98><1000<EFBFBD>∴<EFBFBD>
|
||||
|
||||
**文件清单**:
|
||||
**<EFBFBD><EFBFBD>辣皜<EFBFBD><EFBFBD>**嚗?
|
||||
- `frontend-v2/src/modules/asl/utils/excelExport.ts`
|
||||
- `frontend-v2/src/modules/asl/pages/ScreeningResults.tsx`
|
||||
|
||||
---
|
||||
|
||||
### Phase 6:集成测试与优化(Day 17下午-Day 18)⏱️ 4小时
|
||||
### Phase 6嚗𡁻<EFBFBD><EFBFBD>鞉<EFBFBD>霂蓥<EFBFBD>隡睃<EFBFBD>嚗㇄ay 17銝见<EFBFBD>-Day 18嚗争𪃸儭?4撠𤩺𧒄
|
||||
|
||||
**任务**:
|
||||
1. 完整流程测试(上传→筛选→复核→查看结果→导出)
|
||||
**隞餃𦛚**嚗?
|
||||
1. 摰峕㟲瘚<EFBFBD><EFBFBD>瘚贝<EFBFBD>嚗<EFBFBD><EFBFBD>隡罱<EFBFBD>蝑偦<EFBFBD>争<EFBFBD>憭齿瓲<EFBFBD>埝䰻<EFBFBD>讠<EFBFBD><EFBFBD>鎿<EFBFBD>撖澆枂嚗?
|
||||
2. 撘<>虜<EFBFBD>箸艶瘚贝<E7989A>嚗<EFBFBD><E59A97><EFBFBD>唳旿<E594B3><E697BF><EFBFBD>蝏𣈯<E89D8F>霂荔<E99C82>
|
||||
3. UI/UX隡睃<E99AA1>嚗<EFBFBD><E59A97>頧賜𠶖<E8B39C><F0A0B696><EFBFBD><EFBFBD><EFBFBD>霂舀<E99C82>蝷綽<E89DB7>
|
||||
4. 性能测试(统计API、Excel导出)
|
||||
5. 云原生规范检查
|
||||
4. <EFBFBD>扯<EFBFBD>瘚贝<EFBFBD>嚗<EFBFBD><EFBFBD>霈,PI<EFBFBD><EFBFBD>xcel撖澆枂嚗?
|
||||
5. 鈭穃<EFBFBD><EFBFBD>蠘<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?
|
||||
|
||||
**验收标准**:
|
||||
- ✅ 流程完整无阻塞
|
||||
- ✅ 异常处理完善
|
||||
- ✅ 性能达标
|
||||
- ✅ 符合云原生规范
|
||||
**撉峕𤣰<EFBFBD><EFBFBD><EFBFBD>**嚗?
|
||||
- <EFBFBD>?瘚<><E7989A>摰峕㟲<E5B395>𣳇獈憛?
|
||||
- <EFBFBD>?撘<>虜憭<E8999C><E686AD>摰<EFBFBD><E691B0>
|
||||
- <EFBFBD>?<3F>扯<EFBFBD>颲暹<E9A2B2>
|
||||
- <EFBFBD>?蝚血<E89D9A>鈭穃<E988AD><E7A983>蠘<EFBFBD><E8A098>?
|
||||
|
||||
---
|
||||
|
||||
## ✅ 七、验收标准
|
||||
## <EFBFBD>?銝<><E98A9D><EFBFBD><EFBFBD><EFBFBD>嗆<EFBFBD><E59786>?
|
||||
|
||||
### 7.1 <20>蠘<EFBFBD>撉峕𤣰
|
||||
|
||||
- [✅] 统计概览卡片正确显示(总数、纳入、排除、待复核)
|
||||
- [✅] 排除原因统计准确(柱状图)
|
||||
- [✅] 待复核提示醒目
|
||||
- [✅] Tab切换正常(全部/已纳入/已排除/待复核)
|
||||
- [<EFBFBD><EFBFBD> 蝏蠘恣璁<E681A3><E79281><EFBFBD>∠<EFBFBD>甇<EFBFBD>&<EFBFBD>曄內嚗<E585A7><E59A97>餅㺭<E9A485><E3BAAD>熙<EFBFBD>乓<EFBFBD><E4B993><EFBFBD><EFBFBD>扎<EFBFBD><E6898E><EFBFBD>憭齿瓲嚗?
|
||||
- [<EFBFBD><EFBFBD> <20>㘾膄<E398BE>笔<EFBFBD>蝏蠘恣<E8A098><E681A3>&嚗<EFBC86><E59A97><EFBFBD>嗅㦛嚗?
|
||||
- [<EFBFBD><EFBFBD> 敺<><E695BA><EFBFBD>豢<EFBFBD>蝷粹<E89DB7><E7B2B9>?
|
||||
- [<EFBFBD><EFBFBD> Tab<EFBFBD><EFBFBD>揢甇<EFBFBD>虜嚗<EFBFBD><EFBFBD><EFBFBD>?撌脩熙<E884A9>?撌脫<E6928C><E884AB>?敺<><E695BA><EFBFBD>賂<EFBFBD>
|
||||
- [<5B><> 銵冽聢<E586BD>唳旿甇<E697BF>&嚗<EFBC86><E59A97>銵諹”<E8ABB9>潘<EFBFBD>
|
||||
- [✅] Checkbox多选正常
|
||||
- [✅] 可查看详情
|
||||
- [✅] 可导出Excel(全部/选中)
|
||||
- [<EFBFBD><EFBFBD> Checkbox憭𡁻<EFBFBD>㗇迤撣?
|
||||
- [<EFBFBD><EFBFBD> <20>舀䰻<E88880>贝祕<E8B49D>?
|
||||
- [<EFBFBD><EFBFBD> <20>臬紡<E887AC>慟xcel嚗<6C><E59A97><EFBFBD>?<3F>劐葉嚗?
|
||||
- [<5B><> Excel<65>唳旿摰峕㟲
|
||||
|
||||
### 7.2 <20>扯<EFBFBD>撉峕𤣰
|
||||
|
||||
- [<5B><> 蝏蠘恣API<50>滚<EFBFBD><E6BB9A>園𡢿 <500ms
|
||||
- [✅] Excel导出(<1000条)<3秒
|
||||
- [<EFBFBD><EFBFBD> Excel撖澆枂嚗?1000<30>∴<EFBFBD><3蝘?
|
||||
- [<5B><> 銵冽聢<E586BD><E881A2>△<EFBFBD>㰘蝸甇<E89DB8>虜
|
||||
|
||||
### 7.3 云原生验收
|
||||
### 7.3 鈭穃<EFBFBD><EFBFBD>罸<EFBFBD><EFBFBD>?
|
||||
|
||||
基于[云原生开发规范检查清单](../../../04-开发规范/08-云原生开发规范.md):
|
||||
<EFBFBD>箔<EFBFBD>[鈭穃<EFBFBD><EFBFBD>笔<EFBFBD><EFBFBD>𤏸<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>交<EFBFBD><EFBFBD>騟(../../../04-撘<><E69298>𤏸<EFBFBD><F0A48FB8>?08-鈭穃<E988AD><E7A983>笔<EFBFBD><E7AC94>𤏸<EFBFBD><F0A48FB8>?md)嚗?
|
||||
|
||||
**后端API**:
|
||||
- [✅] 使用全局 `prisma` 实例(不new PrismaClient)
|
||||
**<EFBFBD>𡒊垢API**嚗?
|
||||
- [<5B><> 雿輻鍂<E8BCBB>典<EFBFBD> `prisma` 摰硺<E691B0>嚗<EFBFBD><E59A97>new PrismaClient嚗?
|
||||
- [<5B><> 蝏蠘恣雿輻鍂Prisma<6D>𡁜<EFBFBD><F0A1819C>亥砭嚗<E7A0AD><E59A97><EFBFBD>亙<EFBFBD><E4BA99>𤩺㺭<F0A4A9BA>殷<EFBFBD>
|
||||
- [✅] 无本地文件存储(无fs.writeFile)
|
||||
- [✅] 使用 `logger` 记录日志(不用console.log)
|
||||
- [<5B><> <20>䭾𧋦<E4ADBE>唳<EFBFBD>隞嗅<E99A9E><E59785>剁<EFBFBD><E58981>霡s.writeFile嚗?
|
||||
- [<5B><> 雿輻鍂 `logger` 霈啣<E99C88><E595A3>亙<EFBFBD>嚗<EFBFBD><E59A97><EFBFBD>牢onsole.log嚗?
|
||||
- [<5B><> 蝏煺<E89D8F><E785BA>躰秤憭<E7A7A4><E686AD>
|
||||
|
||||
**前端实现**:
|
||||
- [✅] Excel前端生成(零文件落盘)
|
||||
- [✅] 使用 `xlsx` 库(成熟稳定)
|
||||
- [✅] 友好的用户提示
|
||||
**<EFBFBD>滨垢摰䂿緵**嚗?
|
||||
- [<5B><> Excel<65>滨垢<E6BBA8><E59EA2><EFBFBD>嚗<EFBFBD>妟<EFBFBD><E5A69F>辣<EFBFBD>賜<EFBFBD>嚗?
|
||||
- [<5B><> 雿輻鍂 `xlsx` 摨橒<E691A8><E6A992>鞟<EFBFBD>蝔喳<E89D94>嚗?
|
||||
- [<5B><> <20>见末<E8A781><E69CAB>鍂<EFBFBD>瑟<EFBFBD>蝷?
|
||||
|
||||
---
|
||||
|
||||
## 📊 八、时间估算
|
||||
## <EFBFBD><EFBFBD> <20>怒<EFBFBD><E68092>𧒄<EFBFBD>港摯蝞?
|
||||
|
||||
| 阶段 | 任务 | 预计耗时 | 负责人 |
|
||||
| <EFBFBD>嗆挾 | 隞餃𦛚 | 憸<>恣<EFBFBD>埈𧒄 | 韐蠘提鈭?|
|
||||
|------|------|---------|--------|
|
||||
| Phase 1 | 后端统计API | 2小时 | 后端开发 |
|
||||
| Phase 2 | 前端API客户端 | 0.5小时 | 前端开发 |
|
||||
| Phase 3 | 统计概览 | 1.5小时 | 前端开发 |
|
||||
| Phase 4 | 结果列表Tab | 3小时 | 前端开发 |
|
||||
| Phase 5 | Excel导出 | 2小时 | 前端开发 |
|
||||
| Phase 6 | 集成测试 | 4小时 | 全栈开发 |
|
||||
| **总计** | | **13小时** | **约2天** |
|
||||
| Phase 1 | <EFBFBD>𡒊垢蝏蠘恣API | 2撠𤩺𧒄 | <20>𡒊垢撘<E59EA2><E69298>?|
|
||||
| Phase 2 | <EFBFBD>滨垢API摰X<EFBFBD>蝡?| 0.5撠𤩺𧒄 | <20>滨垢撘<E59EA2><E69298>?|
|
||||
| Phase 3 | 蝏蠘恣璁<EFBFBD><EFBFBD> | 1.5撠𤩺𧒄 | <20>滨垢撘<E59EA2><E69298>?|
|
||||
| Phase 4 | 蝏𤘪<EFBFBD><EFBFBD>𡑒”Tab | 3撠𤩺𧒄 | <20>滨垢撘<E59EA2><E69298>?|
|
||||
| Phase 5 | Excel撖澆枂 | 2撠𤩺𧒄 | <20>滨垢撘<E59EA2><E69298>?|
|
||||
| Phase 6 | <EFBFBD><EFBFBD><EFBFBD>瘚贝<EFBFBD> | 4撠𤩺𧒄 | <20>冽<EFBFBD>撘<EFBFBD><E69298>?|
|
||||
| **<EFBFBD>餉恣** | | **13撠𤩺𧒄** | **蝥?憭?* |
|
||||
|
||||
---
|
||||
|
||||
## 🔗 九、相关文档
|
||||
## <EFBFBD><EFBFBD> 銋腈<E98A8B><E88588>㮾<EFBFBD>單<EFBFBD>獢?
|
||||
|
||||
- [云原生开发规范](../../../04-开发规范/08-云原生开发规范.md) - 必读
|
||||
- [鈭穃<E988AD><E7A983>笔<EFBFBD><E7AC94>𤏸<EFBFBD><F0A48FB8><EFBFBD>(../../../04-撘<><E69298>𤏸<EFBFBD><F0A48FB8>?08-鈭穃<E988AD><E7A983>笔<EFBFBD><E7AC94>𤏸<EFBFBD><F0A48FB8>?md) - 敹<EFBFBD>粉
|
||||
- [隞餃𦛚<E9A483><F0A69B9A>圾](./03-隞餃𦛚<E9A483><F0A69B9A>圾.md) - Week 4隞餃𦛚皜<F0A69B9A><E79A9C>
|
||||
- [模块当前状态](../00-模块当前状态与开发指南.md) - 模块真实状态
|
||||
- [璅∪<EFBFBD>敶枏<EFBFBD><EFBFBD>嗆<EFBFBD><EFBFBD>(../00-璅∪<E79285>敶枏<E695B6><E69E8F>嗆<EFBFBD><E59786><EFBFBD>撘<EFBFBD><E69298>烐<EFBFBD><E78390>?md) - 璅∪<EFBFBD><EFBFBD>笔<EFBFBD><EFBFBD>嗆<EFBFBD>?
|
||||
- [<EFBFBD><EFBFBD><EFBFBD>臬<EFBFBD>箏𦛚皜<EFBFBD><EFBFBD>](../06-<2D><><EFBFBD>臬<EFBFBD>箏𦛚/<2F><><EFBFBD>臬<EFBFBD>箏𦛚皜<F0A69B9A><E79A9C>.md) - Excel<65>𡒊垢撖澆枂<E6BE86>寞<EFBFBD>
|
||||
- [数据库设计](../02-技术设计/01-数据库设计.md) - 数据表结构
|
||||
- [API设计规范](../02-技术设计/02-API设计规范.md) - API规范
|
||||
- [<EFBFBD>唳旿摨栞挽霈((../02-<2D><><EFBFBD>航挽霈?01-<2D>唳旿摨栞挽霈?md) - <EFBFBD>唳旿銵函<EFBFBD><EFBFBD>?
|
||||
- [API霈曇恣閫<EFBFBD><EFBFBD>](../02-<EFBFBD><EFBFBD><EFBFBD>航挽霈?02-API霈曇恣閫<E681A3><E996AB>.md) - API閫<EFBFBD><EFBFBD>
|
||||
|
||||
---
|
||||
|
||||
@@ -798,45 +798,45 @@ export default ScreeningResults;
|
||||
|
||||
### <20>箏𦛚1嚗鍃xcel<65>𡒊垢撖澆枂隡睃<E99AA1>
|
||||
|
||||
**触发条件**:
|
||||
- 单次导出数据量 >5000条
|
||||
- 需要复杂Excel格式(多Sheet、图表等)
|
||||
**閫血<EFBFBD><EFBFBD>∩辣**嚗?
|
||||
- <EFBFBD>閙活撖澆枂<EFBFBD>唳旿<EFBFBD>?>5000<EFBFBD>?
|
||||
- <EFBFBD><EFBFBD>閬<EFBFBD><EFBFBD><EFBFBD><EFBFBD>xcel<EFBFBD>澆<EFBFBD>嚗<EFBFBD><EFBFBD>Sheet<EFBFBD><EFBFBD>㦛銵函<EFBFBD>嚗?
|
||||
- <20>冽<EFBFBD><E586BD>漤<EFBFBD><E6BCA4>滨垢撖澆枂<E6BE86>⊿▼
|
||||
|
||||
**解决方案**:
|
||||
- 后端生成Excel(使用 `ExcelJS`)
|
||||
- 上传到OSS(使用 `storage.upload()`)
|
||||
**閫<EFBFBD><EFBFBD><EFBFBD>寞<EFBFBD>**嚗?
|
||||
- <EFBFBD>𡒊垢<EFBFBD><EFBFBD><EFBFBD>Excel嚗<EFBFBD>蝙<EFBFBD>?`ExcelJS`嚗?
|
||||
- 銝𠹺<EFBFBD><EFBFBD>記SS嚗<EFBFBD>蝙<EFBFBD>?`storage.upload()`嚗?
|
||||
- 餈𥪜<E9A488>銝贝蝸URL
|
||||
|
||||
**记录位置**:[技术债务清单 - 优先级4](../06-技术债务/技术债务清单.md)
|
||||
**霈啣<EFBFBD>雿滨蔭**嚗靀<E59A97><E99D80><EFBFBD>臬<EFBFBD>箏𦛚皜<F0A69B9A><E79A9C> - 隡睃<E99AA1>蝥?](../06-<EFBFBD><EFBFBD><EFBFBD>臬<EFBFBD>箏𦛚/<2F><><EFBFBD>臬<EFBFBD>箏𦛚皜<F0A69B9A><E79A9C>.md)
|
||||
|
||||
**预计耗时**:1-2天
|
||||
**憸<EFBFBD>恣<EFBFBD>埈𧒄**嚗?-2憭?
|
||||
|
||||
---
|
||||
|
||||
## 💡 十一、开发建议
|
||||
## <EFBFBD>働 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>穃遣霈?
|
||||
|
||||
### 对开发人员
|
||||
### 撖孵<EFBFBD><EFBFBD>睲犖<EFBFBD>?
|
||||
|
||||
1. **先阅读云原生规范**:[云原生开发规范](../../../04-开发规范/08-云原生开发规范.md)
|
||||
1. **<EFBFBD><EFBFBD><EFBFBD>霂颱<EFBFBD><EFBFBD>毺<EFBFBD>閫<EFBFBD><EFBFBD>**嚗靀鈭穃<E988AD><E7A983>笔<EFBFBD><E7AC94>𤏸<EFBFBD><F0A48FB8><EFBFBD>(../../../04-撘<><E69298>𤏸<EFBFBD><F0A48FB8>?08-鈭穃<E988AD><E7A983>笔<EFBFBD><E7AC94>𤏸<EFBFBD><F0A48FB8>?md)
|
||||
2. **憭滨鍂撟喳蝱<E596B3>賢<EFBFBD>**嚗帋蝙<E5B88B>典<EFBFBD>撅<EFBFBD>`prisma`<EFBFBD><EFBFBD>logger`
|
||||
3. **<EFBFBD>踹<EFBFBD><EFBFBD><EFBFBD>辣<EFBFBD>賜<EFBFBD>**嚗鍃xcel<65>滨垢<E6BBA8><E59EA2><EFBFBD>
|
||||
4. **后端聚合计算**:统计数据后端完成
|
||||
4. **<EFBFBD>𡒊垢<EFBFBD>𡁜<EFBFBD>霈∠<EFBFBD>**嚗𡁶<E59A97>霈⊥㺭<E28AA5>桀<EFBFBD>蝡臬<E89DA1><E887AC>?
|
||||
5. **<EFBFBD>扯<EFBFBD>隡睃<EFBFBD>**嚗䥪risma<6D>𡁜<EFBFBD><F0A1819C>亥砭雿輻鍂撟嗉<E6929F>
|
||||
|
||||
### 撖農I<E8BEB2>拇<EFBFBD>
|
||||
|
||||
1. **优先云原生**:所有设计优先考虑云原生架构
|
||||
2. **参考现有代码**:复用审核工作台的组件
|
||||
3. **注意区别**:初筛结果是单行表格,审核工作台是双行表格
|
||||
4. **测试充分**:完整流程测试
|
||||
1. **隡睃<EFBFBD>鈭穃<EFBFBD><EFBFBD>?*嚗𡁏<E59A97><F0A1818F>㕑挽霈∩<E99C88><E288A9><EFBFBD><EFBFBD><EFBFBD><EFBFBD>鈭穃<E988AD><E7A983><EFBFBD>沲<EFBFBD>?
|
||||
2. **<EFBFBD><EFBFBD><EFBFBD><EFBFBD>緵<EFBFBD>劐誨<EFBFBD>?*嚗𡁜<E59A97><F0A1819C>典恣<E585B8>詨極雿𨅯蝱<F0A885AF><E89DB1><EFBFBD>隞?
|
||||
3. **瘜冽<EFBFBD><EFBFBD>箏<EFBFBD>**嚗𡁜<E59A97>蝑𤤿<E89D91><F0A4A4BF>𨀣糓<F0A880A3>閗<EFBFBD>銵冽聢嚗<E881A2>恣<EFBFBD>詨極雿𨅯蝱<F0A885AF>臬<EFBFBD>銵諹”<E8ABB9>?
|
||||
4. **瘚贝<EFBFBD><EFBFBD><EFBFBD><EFBFBD>**嚗𡁜<E59A97><F0A1819C>湔<EFBFBD>蝔𧢲<E89D94>霂?
|
||||
|
||||
---
|
||||
|
||||
**文档维护者**:AI智能文献开发团队
|
||||
**最后更新**:2025-11-21
|
||||
**文档状态**:✅ 已确认,可开始开发
|
||||
**开始时间**:待定
|
||||
**<EFBFBD><EFBFBD>﹝蝏湔擪<EFBFBD>?*嚗鋫I<E98BAB>箄<EFBFBD><E7AE84><EFBFBD>讃撘<E8AE83><E69298>穃𣪧<E7A983>?
|
||||
**<EFBFBD><EFBFBD><EFBFBD>擧凒<EFBFBD>?*嚗?025-11-21
|
||||
**<EFBFBD><EFBFBD>﹝<EFBFBD>嗆<EFBFBD>?*嚗尠<E59A97> 撌脩&霈歹<E99C88><E6ADB9>臬<EFBFBD>憪见<E686AA><E8A781>?
|
||||
**撘<EFBFBD>憪𧢲𧒄<EFBFBD>?*嚗𡁜<E59A97>摰?
|
||||
|
||||
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,27 +1,27 @@
|
||||
# 全文复筛开发计划 - 更新说明
|
||||
# <EFBFBD>冽<EFBFBD>憭滨<EFBFBD>撘<EFBFBD><EFBFBD>𤏸恣<EFBFBD>?- <20>湔鰵霂湔<E99C82>
|
||||
|
||||
> **更新日期**:2025-11-22
|
||||
> **<EFBFBD>湔鰵<EFBFBD>交<EFBFBD>**嚗?025-11-22
|
||||
> **<2A><>𧋦**嚗间1.1
|
||||
> **更新原因**:基于质量保障策略讨论,优化技术方案
|
||||
> **<EFBFBD>湔鰵<EFBFBD>笔<EFBFBD>**嚗𡁜抅鈭舘捶<E88898>譍<EFBFBD><E8AD8D>𦦵<EFBFBD><F0A6A6B5>亥悄霈綽<E99C88>隡睃<E99AA1><E79D83><EFBFBD><EFBFBD>舀䲮獢?
|
||||
|
||||
---
|
||||
|
||||
## <20><> <20>詨<EFBFBD><E8A9A8>䀹凒<E480B9>餌<EFBFBD>
|
||||
|
||||
### 1️⃣ **提取策略:全文一次性 + Prompt工程优化**
|
||||
### 1儭謿<EFBFBD> **<2A>𣂼<EFBFBD>蝑𣇉裦嚗𡁜<E59A97><F0A1819C><EFBFBD><EFBFBD>甈⊥<E79488>?+ Prompt撌亦<EFBFBD>隡睃<EFBFBD>**
|
||||
|
||||
**<EFBFBD>喟<EFBFBD>**嚗𡁻<E59A97><F0A181BB>典<EFBFBD><E585B8><EFBFBD><EFBFBD>甈⊥<E79488>扯<EFBFBD><E689AF>亦<EFBFBD><E4BAA6>伐<EFBFBD><E4BC90>屸<EFBFBD><E5B1B8><EFBFBD>挾<EFBFBD>𣂼<EFBFBD>
|
||||
|
||||
**理由**:
|
||||
- ✅ 实现复杂度低(2周 vs 3周)
|
||||
- ✅ 快速验证可行性
|
||||
- ✅ Nougat结构化已降低大模型负担
|
||||
- ✅ 先进的Prompt工程可以减轻Lost in the Middle
|
||||
**<EFBFBD><EFBFBD>眏**嚗?
|
||||
- <EFBFBD>?摰䂿緵憭齿<E686AD>摨虫<E691A8>嚗?<3F>?vs 3<EFBFBD>剁<EFBFBD>
|
||||
- <EFBFBD>?敹恍<E695B9>罸<EFBFBD>霂<EFBFBD>虾銵峕<E98AB5>?
|
||||
- <EFBFBD>?Nougat蝏𤘪<EFBFBD><EFBFBD>硋歇<EFBFBD>滢<EFBFBD>憭扳芋<EFBFBD>贝<EFBFBD><EFBFBD>?
|
||||
- <EFBFBD>?<3F><><EFBFBD><EFBFBD><EFBFBD>rompt撌亦<E6928C><E4BAA6>臭誑<E887AD>讛蝠Lost in the Middle
|
||||
|
||||
**核心优化**:
|
||||
1. **Nougat优先**:英文论文用Nougat提取(结构化Markdown)
|
||||
2. **Section-Aware Prompting**:引导LLM逐章节处理
|
||||
3. **Few-shot案例库**:特别强调"信息在中间位置"的案例
|
||||
**<EFBFBD>詨<EFBFBD>隡睃<EFBFBD>**嚗?
|
||||
1. **Nougat隡睃<EFBFBD>**嚗朞㘚<E69C9E><E3989A>捏<EFBFBD><E68D8F>鍂Nougat<61>𣂼<EFBFBD>嚗<EFBFBD><E59A97><EFBFBD><EFBFBD><EFBFBD>Markdown嚗?
|
||||
2. **Section-Aware Prompting**嚗𡁜<E59A97>撖嘴LM<4C>鞟<EFBFBD><E99E9F><EFBFBD><EFBFBD><EFBFBD>?
|
||||
3. **Few-shot獢<EFBFBD><EFBFBD>摨?*嚗𡁶鸌<F0A181B6>怠撩靚?靽⊥<E99DBD><E28AA5>其葉<E585B6>港<EFBFBD>蝵?<3F><><EFBFBD>靘?
|
||||
4. **JSON Schema蝥行<E89DA5>**嚗𡁜撩<F0A1819C>嗉<EFBFBD><E59789>桅曎 + 憭<><E686AD><EFBFBD>亙<EFBFBD> + <20>芣<EFBFBD>撉諹<E69289>
|
||||
|
||||
---
|
||||
@@ -30,104 +30,104 @@
|
||||
|
||||
**<EFBFBD>䀹凒**嚗帋<E59A97> GPT-4o + Claude-4.5 <20>嫣蛹 DeepSeek-V3 + Qwen3-Max
|
||||
|
||||
**理由**:
|
||||
- ✅ 成本友好:¥0.06/篇 vs ¥0.10/篇(节省40%)
|
||||
- ✅ 通用能力层已支持
|
||||
- ✅ 中文文献友好
|
||||
- ✅ MVP阶段优先验证可行性,而非追求极致准确率
|
||||
**<EFBFBD><EFBFBD>眏**嚗?
|
||||
- <EFBFBD>?<3F>鞉𧋦<E99E89>见末嚗块?.06/蝭?vs 瞼0.10/蝭<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>40%嚗?
|
||||
- <EFBFBD>?<3F>𡁶鍂<F0A181B6>賢<EFBFBD>撅<EFBFBD>歇<EFBFBD>舀<EFBFBD>
|
||||
- <EFBFBD>?銝剜<E98A9D><E5899C><EFBFBD>讃<EFBFBD>见末
|
||||
- <EFBFBD>?MVP<EFBFBD>嗆挾隡睃<EFBFBD>撉諹<EFBFBD><EFBFBD>航<EFBFBD><EFBFBD>改<EFBFBD><EFBFBD>屸<EFBFBD>餈賣<EFBFBD><EFBFBD><EFBFBD>稲<EFBFBD><EFBFBD>&<EFBFBD>?
|
||||
|
||||
---
|
||||
|
||||
### 3儭謿<E584AD> **韐券<E99F90>靽嗪<E99DBD>嚗鋴ochrane<6E><65><EFBFBD> + <20>餃郎<E9A483>餉<EFBFBD>撉諹<E69289>**
|
||||
|
||||
**新增服务**:
|
||||
1. **MedicalLogicValidator**(医学逻辑验证)
|
||||
**<EFBFBD>啣<EFBFBD><EFBFBD>滚𦛚**嚗?
|
||||
1. **MedicalLogicValidator**嚗<>龫摮阡<E691AE>餉<EFBFBD>撉諹<E69289>嚗?
|
||||
- RCT敹<54>◆<EFBFBD>厰<EFBFBD><E58EB0>箏<EFBFBD>
|
||||
- <20>𣬚𤩅<F0A3AC9A>𠉛弦敹<E5BCA6>◆霂湔<E99C82><E6B994>脫<EFBFBD>
|
||||
- 样本量与基线数据一致性
|
||||
- 等...共5条规则
|
||||
- <EFBFBD>瑟𧋦<EFBFBD>譍<EFBFBD><EFBFBD>箇瑪<EFBFBD>唳旿銝<EFBFBD><EFBFBD>湔<EFBFBD>?
|
||||
- 蝑?..<2E>?<3F>∟<EFBFBD><E2889F>?
|
||||
|
||||
2. **EvidenceChainValidator**(证据链验证)
|
||||
2. **EvidenceChainValidator**嚗<><E59A97><EFBFBD>桅曎撉諹<E69289>嚗?
|
||||
- 撘箏<E69298><E7AE8F><EFBFBD><EFBFBD>撘閧鍂嚗<E98D82>竉50摮梹<E691AE>
|
||||
- 雿滨蔭靽⊥<E99DBD>嚗<EFBFBD><E59A97><EFBFBD><EFBFBD><EFBFBD><EFBFBD>挾<EFBFBD>踝<EFBFBD>
|
||||
- 憭<><E686AD><EFBFBD>亙<EFBFBD>撉諹<E69289>
|
||||
|
||||
3. **ConflictDetectionService**嚗<><E59A97>撘綽<E69298>
|
||||
- 基于Cochrane标准的严重程度分级
|
||||
- <EFBFBD>箔<EFBFBD>Cochrane<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>艇<EFBFBD>滨<EFBFBD>摨血<EFBFBD>蝥?
|
||||
- <20>喲睸摮埈挾<E59F88>寞<EFBFBD>憭<EFBFBD><E686AD>
|
||||
|
||||
---
|
||||
|
||||
### 4儭謿<E584AD> **Prompt璅⊥踎嚗𡁶<E59A97><F0A181B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>**
|
||||
|
||||
**新目录结构**:
|
||||
**<EFBFBD>啁𤌍敶閧<EFBFBD><EFBFBD>?*嚗?
|
||||
```
|
||||
prompts/
|
||||
├── system_prompt.md # System Prompt(Section-Aware)
|
||||
<EFBFBD>鎿<EFBFBD><EFBFBD><EFBFBD> system_prompt.md # System Prompt嚗𠄎ection-Aware嚗?
|
||||
<EFBFBD>鎿<EFBFBD><EFBFBD><EFBFBD> user_prompt_template.md # User Prompt璅⊥踎
|
||||
├── cochrane_standards/ # Cochrane标准描述(分字段)
|
||||
│ ├── 随机化方法.md
|
||||
│ ├── 盲法.md
|
||||
│ ├── 结果完整性.md
|
||||
│ └── ...(共12个)
|
||||
└── few_shot_examples/ # Few-shot医学案例库
|
||||
<EFBFBD>鎿<EFBFBD><EFBFBD><EFBFBD> cochrane_standards/ # Cochrane<EFBFBD><EFBFBD><EFBFBD><EFBFBD>讛膩嚗<EFBFBD><EFBFBD>摮埈挾嚗?
|
||||
<EFBFBD>? <20>鎿<EFBFBD><E98EBF><EFBFBD> <20>𤩺㦤<F0A4A9BA>𡝗䲮瘜?md
|
||||
<EFBFBD>? <20>鎿<EFBFBD><E98EBF><EFBFBD> <20>脫<EFBFBD>.md
|
||||
<EFBFBD>? <20>鎿<EFBFBD><E98EBF><EFBFBD> 蝏𤘪<E89D8F>摰峕㟲<E5B395>?md
|
||||
<EFBFBD>? <20>婙<EFBFBD><E5A999><EFBFBD> ...嚗<><E59A97>12銝迎<E98A9D>
|
||||
<EFBFBD>婙<EFBFBD><EFBFBD><EFBFBD> few_shot_examples/ # Few-shot<EFBFBD>餃郎獢<EFBFBD><EFBFBD>摨?
|
||||
<20>鎿<EFBFBD><E98EBF><EFBFBD> 擃䁅捶<E48185>嗬CT.md
|
||||
<20>鎿<EFBFBD><E98EBF><EFBFBD> 韐券<E99F90>銝滩雲獢<E99BB2><E78DA2>.md
|
||||
└── 信息在中间位置案例.md # ← 特别重要
|
||||
<EFBFBD>婙<EFBFBD><EFBFBD><EFBFBD> 靽⊥<E99DBD><E28AA5>其葉<E585B6>港<EFBFBD>蝵格<E89DB5>靘?md # <EFBFBD>?<3F>孵<EFBFBD><E5ADB5>滩<EFBFBD>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 5️⃣ **开发周期:2周 + MVP验证3天**
|
||||
### 5儭謿<EFBFBD> **撘<><E69298>穃𪂹<E7A983><F0AA82B9><EFBFBD>2<EFBFBD>?+ MVP撉諹<E69289>3憭?*
|
||||
|
||||
**调整**:
|
||||
**靚<EFBFBD>㟲**嚗?
|
||||
- Week 1-2嚗𡁜<E59A97><F0A1819C>𡢅<EFBFBD>靽脲<E99DBD>2<EFBFBD>剁<EFBFBD>
|
||||
- Week 3嚗㇄ay 11-13嚗㚁<E59A97>MVP撉諹<E69289> + <20>∩辣<E288A9><E8BEA3>漣<EFBFBD>喟<EFBFBD>
|
||||
|
||||
**MVP验证关键**:
|
||||
- 测试10-15篇人工标注论文
|
||||
- 评估准确率(目标≥85%)
|
||||
**MVP撉諹<EFBFBD><EFBFBD>喲睸**嚗?
|
||||
- 瘚贝<EFBFBD>10-15蝭<EFBFBD>犖撌交<EFBFBD>瘜刻捏<EFBFBD>?
|
||||
- 霂<EFBFBD>摯<EFBFBD><EFBFBD>&<EFBFBD><EFBFBD><EFBFBD><EFBFBD>格<EFBFBD><EFBFBD>?5%嚗?
|
||||
- 憒<><E68692><80%嚗<><E59A97>蝥找蛹瘛瑕<E7989B>蝑𣇉裦嚗<E8A3A6><E59A97><EFBFBD>桀<EFBFBD>畾萄<E795BE>畾菜<E795BE><E88F9C>吔<EFBFBD>
|
||||
|
||||
---
|
||||
|
||||
### 6️⃣ **数据库设计增强**
|
||||
### 6儭謿<EFBFBD> **<2A>唳旿摨栞挽霈∪<E99C88>撘?*
|
||||
|
||||
**新增字段**:
|
||||
- `promptVersion`:Prompt版本号
|
||||
- `extractionMethod`:'nougat' | 'pymupdf'
|
||||
- `structuredFormat`:是否为结构化格式
|
||||
**<EFBFBD>啣<EFBFBD>摮埈挾**嚗?
|
||||
- `promptVersion`嚗䥪rompt<EFBFBD><EFBFBD>𧋦<EFBFBD>?
|
||||
- `extractionMethod`嚗?nougat' | 'pymupdf'
|
||||
- `structuredFormat`嚗𡁏糓<EFBFBD>虫蛹蝏𤘪<EFBFBD><EFBFBD>𡝗聢撘?
|
||||
- `processingLog`嚗𡁜<EFBFBD><EFBFBD><EFBFBD>𠯫敹梹<EFBFBD>撉諹<EFBFBD><EFBFBD>鞟<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
- `logicValidation`嚗𡁜龫摮阡<EFBFBD>餉<EFBFBD>撉諹<EFBFBD>蝏𤘪<EFBFBD>
|
||||
- `evidenceComplete`嚗朞<EFBFBD><EFBFBD>桅曎<EFBFBD>臬炏摰峕㟲
|
||||
- `conflictSeverity`:冲突严重程度
|
||||
- `conflictSeverity`嚗𡁜<EFBFBD>蝒<EFBFBD>艇<EFBFBD>滨<EFBFBD>摨?
|
||||
- `reviewPriority`嚗𡁜<EFBFBD><EFBFBD>訾<EFBFBD><EFBFBD><EFBFBD>漣
|
||||
|
||||
---
|
||||
|
||||
## 🎯 关键技术要点
|
||||
## <EFBFBD>㴓 <20>喲睸<E596B2><E79DB8><EFBFBD>航<EFBFBD><E888AA>?
|
||||
|
||||
### Prompt撌亦<E6928C><E4BAA6>詨<EFBFBD>蝑𣇉裦
|
||||
|
||||
#### 1. Section-Aware Prompting
|
||||
|
||||
```markdown
|
||||
⚠️ 重要:本文是完整全文(约20,000字),请按章节逐步处理。
|
||||
<EFBFBD>𩤃<EFBFBD> <20>滩<EFBFBD>嚗𡁏𧋦<F0A1818F><F0A78BA6>糓摰峕㟲<E5B395>冽<EFBFBD>嚗<EFBFBD>漲20,000摮梹<E691AE>嚗諹窈<E8ABB9>厩<EFBFBD><E58EA9><EFBFBD><EFBFBD>鞉郊憭<E9838A><E686AD><EFBFBD>?
|
||||
|
||||
## 处理流程(必须遵守):
|
||||
## 憭<EFBFBD><EFBFBD>瘚<EFBFBD><EFBFBD>嚗<EFBFBD><EFBFBD>憿駁<EFBFBD>摰<EFBFBD><EFBFBD>嚗?
|
||||
|
||||
### Step 1: 蝡㰘<E89DA1>摰帋<E691B0>
|
||||
快速浏览全文,识别关键章节(Abstract、Methods、Results...)
|
||||
敹恍<EFBFBD><EFBFBD><EFBFBD>閫<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>霂<EFBFBD><EFBFBD><EFBFBD>喲睸蝡㰘<EFBFBD>嚗㇁bstract<EFBFBD><EFBFBD>ethods<EFBFBD><EFBFBD>esults...嚗?
|
||||
|
||||
### Step 2: 分字段提取
|
||||
对于每个字段:
|
||||
### Step 2: <EFBFBD><EFBFBD><EFBFBD>畾菜<EFBFBD><EFBFBD>?
|
||||
撖嫣<EFBFBD>瘥譍葵摮埈挾嚗?
|
||||
1. <20><>釣憸<E987A3><E686B8>雿滨蔭
|
||||
2. 定位到章节
|
||||
2. 摰帋<EFBFBD><EFBFBD>啁<EFBFBD><EFBFBD>?
|
||||
3. **<EFBFBD>鞉挾隞𠉛<EFBFBD><EFBFBD><EFBFBD>粉**嚗<><E59A97>閬<EFBFBD>歲餈<E6ADB2>葉<EFBFBD>湛<EFBFBD>
|
||||
4. <20>𣂼<EFBFBD>靽⊥<E99DBD>
|
||||
5. 记录引用和位置
|
||||
5. 霈啣<EFBFBD>撘閧鍂<EFBFBD>䔶<EFBFBD>蝵?
|
||||
|
||||
⚠️ 特别注意:
|
||||
<EFBFBD>𩤃<EFBFBD> <20>孵<EFBFBD>瘜冽<E7989C>嚗?
|
||||
- Methods<64>朙esults<74>其葉<E585B6>港<EFBFBD>蝵殷<E89DB5><E6AEB7><EFBFBD>摰寞<E691B0><E5AF9E>埈<EFBFBD>
|
||||
- 餈嗘<E9A488>蝡㰘<E89DA1>敺<EFBFBD>鵭嚗諹窈<E8ABB9><E7AA88>挾<EFBFBD><E68CBE>粉
|
||||
|
||||
@@ -141,15 +141,15 @@ prompts/
|
||||
### 獢<><E78DA2>1嚗帋縑<E5B88B>臬銁Methods銝剝𡢿畾菔氜嚗<E6B09C><E59A97><EFBFBD>埈<EFBFBD>嚗争<E59A97>
|
||||
|
||||
<EFBFBD>冽<EFBFBD>19,500摮梹<E691AE>
|
||||
- Methods(4,000字)
|
||||
- 第1段:研究设计概述
|
||||
- 第2段:入排标准
|
||||
- **第3段:随机化方法** ← 关键!在中间
|
||||
- 第4段:盲法
|
||||
- Methods嚗?,000摮梹<EFBFBD>
|
||||
- 蝚?畾蛛<E795BE><E89B9B>𠉛弦霈曇恣璁<E681A3>膩
|
||||
- 蝚?畾蛛<E795BE><E89B9B>交<EFBFBD><E4BAA4><EFBFBD><EFBFBD>
|
||||
- **蝚?畾蛛<E795BE><E89B9B>𤩺㦤<F0A4A9BA>𡝗䲮瘜?* <20>?<3F>喲睸嚗<E79DB8>銁銝剝𡢿
|
||||
- 蝚?畾蛛<E795BE><E89B9B>脫<EFBFBD>
|
||||
- ...
|
||||
|
||||
甇<EFBFBD>&<EFBFBD>𡁏<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>鞉挾<EFBFBD><EFBFBD>粉嚗䔶<EFBFBD>頝唾<EFBFBD>
|
||||
错误示例❌:只看开头和结尾,跳过中间
|
||||
<EFBFBD>躰秤蝷箔<EFBFBD><EFBFBD>䕘<EFBFBD><EFBFBD>芰<EFBFBD>撘<EFBFBD>憭游<EFBFBD>蝏枏偏嚗諹歲餈<EFBFBD>葉<EFBFBD>?
|
||||
```
|
||||
|
||||
#### 3. JSON Schema撘箏<E69298>蝥行<E89DA5>
|
||||
@@ -159,15 +159,15 @@ prompts/
|
||||
"processing_log": {
|
||||
"sections_reviewed": ["Abstract", "Methods", "Results", "Tables"],
|
||||
"paragraphs_read_per_section": {
|
||||
"Methods": 7, // 必须≥3
|
||||
"Results": 5 // 必须≥3
|
||||
"Methods": 7, // 敹<EFBFBD>◆<EFBFBD>?
|
||||
"Results": 5 // 敹<EFBFBD>◆<EFBFBD>?
|
||||
},
|
||||
"middle_sections_attention": true // 敹<>◆<EFBFBD>單釣銝剝𡢿
|
||||
},
|
||||
|
||||
"verification": {
|
||||
"keywords_searched": ["randomization", "blinding", "ITT"],
|
||||
"reread_count": 2, // 至少重读1次
|
||||
"reread_count": 2, // <EFBFBD>喳<EFBFBD><EFBFBD>滩粉1甈?
|
||||
"found_missed_info": false
|
||||
}
|
||||
}
|
||||
@@ -179,30 +179,30 @@ prompts/
|
||||
|
||||
| <20><><EFBFBD> | <20>格<EFBFBD> | 撉諹<E69289><E8ABB9>寞<EFBFBD> |
|
||||
|------|------|----------|
|
||||
| **准确率(MVP)** | ≥ 85% | 人工标注10-15篇测试 |
|
||||
| **Methods章节准确率** | ≥ 83% | 分章节评估 |
|
||||
| **Results章节准确率** | ≥ 83% | 分章节评估 |
|
||||
| **证据链完整性** | 100% | 自动检查 |
|
||||
| **医学逻辑验证** | 100% | 规则引擎检查 |
|
||||
| **成本** | ≤ ¥0.06/篇 | 实际消耗统计 |
|
||||
| **处理时间** | ≤ 3分钟/篇 | 性能测试 |
|
||||
| **<EFBFBD><EFBFBD>&<EFBFBD><EFBFBD><EFBFBD>MVP嚗?* | <EFBFBD>?85% | 鈭箏極<EFBFBD><EFBFBD>釣10-15蝭<35><E89DAD>霂?|
|
||||
| **Methods蝡㰘<EFBFBD><EFBFBD><EFBFBD>&<EFBFBD>?* | <EFBFBD>?83% | <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>隡?|
|
||||
| **Results蝡㰘<EFBFBD><EFBFBD><EFBFBD>&<EFBFBD>?* | <EFBFBD>?83% | <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>隡?|
|
||||
| **霂<EFBFBD>旿<EFBFBD>曉<EFBFBD><EFBFBD>湔<EFBFBD>?* | 100% | <EFBFBD>芸𢆡璉<EFBFBD><EFBFBD>?|
|
||||
| **<EFBFBD>餃郎<EFBFBD>餉<EFBFBD>撉諹<EFBFBD>** | 100% | 閫<EFBFBD><EFBFBD>撘閙<EFBFBD>璉<EFBFBD><EFBFBD>?|
|
||||
| **<EFBFBD>鞉𧋦** | <EFBFBD>?瞼0.06/蝭?| 摰鮋<E691B0>瘨<EFBFBD><E798A8>㛖<EFBFBD>霈?|
|
||||
| **憭<EFBFBD><EFBFBD><EFBFBD>園𡢿** | <EFBFBD>?3<><33><EFBFBD>/蝭?| <20>扯<EFBFBD>瘚贝<E7989A> |
|
||||
|
||||
---
|
||||
|
||||
## <20><> <20>∩辣<E288A9><E8BEA3>漣頝臬<E9A09D>
|
||||
|
||||
如果MVP准确率<80%,升级为**混合策略**:
|
||||
憒<EFBFBD><EFBFBD>MVP<EFBFBD><EFBFBD>&<EFBFBD>?80%嚗<><E59A97>蝥找蛹**瘛瑕<E7989B>蝑𣇉裦**嚗?
|
||||
|
||||
```
|
||||
关键字段(3个)→ 分段提取
|
||||
- 随机化方法(Methods)
|
||||
- 盲法(Methods)
|
||||
- 结果完整性(Results + Figures)
|
||||
<EFBFBD>喲睸摮埈挾嚗?銝迎<E98A9D><E8BF8E>?<3F><>挾<EFBFBD>𣂼<EFBFBD>
|
||||
- <EFBFBD>𤩺㦤<EFBFBD>𡝗䲮瘜𤏪<EFBFBD>Methods嚗?
|
||||
- <EFBFBD>脫<EFBFBD>嚗㇈ethods嚗?
|
||||
- 蝏𤘪<EFBFBD>摰峕㟲<EFBFBD>改<EFBFBD>Results + Figures嚗?
|
||||
|
||||
其他字段(9个)→ 保持全文提取
|
||||
<EFBFBD>嗡<EFBFBD>摮埈挾嚗?銝迎<E98A9D><E8BF8E>?靽脲<E99DBD><E884B2>冽<EFBFBD><E586BD>𣂼<EFBFBD>
|
||||
- <20>𠉛弦霈曇恣<E69B87><E681A3><EFBFBD>蝛嗡犖蝢扎<E89DA2><E6898E>僕憸<E58395>綳<EFBFBD>賜<EFBFBD>
|
||||
|
||||
开发增量:+1周
|
||||
撘<EFBFBD><EFBFBD>穃<EFBFBD><EFBFBD>𧶏<EFBFBD>+1<>?
|
||||
憸<EFBFBD><EFBFBD><EFBFBD><EFBFBD>&<EFBFBD><EFBFBD><EFBFBD>90%+
|
||||
```
|
||||
|
||||
@@ -210,15 +210,15 @@ prompts/
|
||||
|
||||
## <20><> <20>詨<EFBFBD><E8A9A8><EFBFBD>﹝
|
||||
|
||||
- [全文复筛质量保障策略](../02-技术设计/08-全文复筛质量保障策略.md)
|
||||
- [标题摘要初筛质量保障策略](../02-技术设计/06-质量保障与可追溯策略.md)
|
||||
- [数据库设计](../02-技术设计/01-数据库设计.md)
|
||||
- [API设计规范](../02-技术设计/02-API设计规范.md)
|
||||
- [<EFBFBD>冽<EFBFBD>憭滨<EFBFBD>韐券<EFBFBD>靽嗪<EFBFBD>蝑𣇉裦](../02-<2D><><EFBFBD>航挽霈?08-<2D>冽<EFBFBD>憭滨<E686AD>韐券<E99F90>靽嗪<E99DBD>蝑𣇉裦.md)
|
||||
- [<EFBFBD><EFBFBD><EFBFBD><EFBFBD>䁅<EFBFBD><EFBFBD>萘<EFBFBD>韐券<EFBFBD>靽嗪<EFBFBD>蝑𣇉裦](../02-<2D><><EFBFBD>航挽霈?06-韐券<E99F90>靽嗪<E99DBD>銝𤾸虾餈賣滲蝑𣇉裦.md)
|
||||
- [<EFBFBD>唳旿摨栞挽霈((../02-<2D><><EFBFBD>航挽霈?01-<2D>唳旿摨栞挽霈?md)
|
||||
- [API霈曇恣閫<EFBFBD><EFBFBD>](../02-<EFBFBD><EFBFBD><EFBFBD>航挽霈?02-API霈曇恣閫<E681A3><E996AB>.md)
|
||||
|
||||
---
|
||||
|
||||
**更新日志**:
|
||||
- 2025-11-22: V1.1 - 基于质量保障讨论,确定全文一次性+Prompt优化策略
|
||||
**<EFBFBD>湔鰵<EFBFBD>亙<EFBFBD>**嚗?
|
||||
- 2025-11-22: V1.1 - <EFBFBD>箔<EFBFBD>韐券<EFBFBD>靽嗪<EFBFBD>霈刻捏嚗𣬚&摰𡁜<EFBFBD><EFBFBD><EFBFBD><EFBFBD>甈⊥<EFBFBD>?Prompt隡睃<E99AA1>蝑𣇉裦
|
||||
- 2025-11-22: V1.0 - <20>嘥<EFBFBD><E598A5><EFBFBD>𧋦
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user