feat(admin): Add user management and upgrade to module permission system
Features - User Management (Phase 4.1): - Database: Add user_modules table for fine-grained module permissions - Database: Add 4 user permissions (view/create/edit/delete) to role_permissions - Backend: UserService (780 lines) - CRUD with tenant isolation - Backend: UserController + UserRoutes (648 lines) - 13 API endpoints - Backend: Batch import users from Excel - Frontend: UserListPage (412 lines) - list/filter/search/pagination - Frontend: UserFormPage (341 lines) - create/edit with module config - Frontend: UserDetailPage (393 lines) - details/tenant/module management - Frontend: 3 modal components (592 lines) - import/assign/configure - API: GET/POST/PUT/DELETE /api/admin/users/* endpoints Architecture Upgrade - Module Permission System: - Backend: Add getUserModules() method in auth.service - Backend: Login API returns modules array in user object - Frontend: AuthContext adds hasModule() method - Frontend: Navigation filters modules based on user.modules - Frontend: RouteGuard checks requiredModule instead of requiredVersion - Frontend: Remove deprecated version-based permission system - UX: Only show accessible modules in navigation (clean UI) - UX: Smart redirect after login (avoid 403 for regular users) Fixes: - Fix UTF-8 encoding corruption in ~100 docs files - Fix pageSize type conversion in userService (String to Number) - Fix authUser undefined error in TopNavigation - Fix login redirect logic with role-based access check - Update Git commit guidelines v1.2 with UTF-8 safety rules Database Changes: - CREATE TABLE user_modules (user_id, tenant_id, module_code, is_enabled) - ADD UNIQUE CONSTRAINT (user_id, tenant_id, module_code) - INSERT 4 permissions + role assignments - UPDATE PUBLIC tenant with 8 module subscriptions Technical: - Backend: 5 new files (~2400 lines) - Frontend: 10 new files (~2500 lines) - Docs: 1 development record + 2 status updates + 1 guideline update - Total: ~4900 lines of code Status: User management 100% complete, module permission system operational
This commit is contained in:
@@ -1,57 +1,62 @@
|
||||
# RVW稿件审查模块迁移计划(v2.1 - 稳定迁移版)
|
||||
|
||||
> **鏂囨。鐗堟湰锛?* v2.1
|
||||
> **鍒涘缓鏃ユ湡锛?* 2026-01-07
|
||||
> **文档版本:** v2.1
|
||||
> **创建日期:** 2026-01-07
|
||||
> **最后更新:** 2026-01-07
|
||||
> **缁存姢鑰咃細** 寮€鍙戝洟闃?
|
||||
> **鏂囨。鐩<EFBFBD>殑锛?* 灏嗙ǹ浠跺<E6B5A0>鏌ュ姛鑳戒粠鏃ф灦鏋勫畨鍏ㄨ縼绉诲埌鏂版灦鏋勶紝鍚屾椂鏁村悎MVP鏍稿績闇€姹?
|
||||
> **维护者:** 开发团队
|
||||
> **文档目的:** 将稿件审查功能从旧架构安全迁移到新架构,同时整合MVP核心需求
|
||||
|
||||
---
|
||||
|
||||
## 📋 项目概述
|
||||
|
||||
### 1. 背景
|
||||
|
||||
绋夸欢瀹℃煡鍔熻兘鏄?025-10-30锛圖ay 30锛夌嫭绔嬪紑鍙戠殑鍔熻兘妯″潡锛岀洰鍓嶄綅浜?`backend/src/legacy/` 鍜?`frontend/` 鐩<EFBFBD>綍涓<EFBFBD>€傜幇闇€瑕侊細
|
||||
稿件审查功能是2025-10-30(Day 30)独立开发的功能模块,目前位于 `backend/src/legacy/` 和 `frontend/` 目录中。现需要:
|
||||
|
||||
1. **鏋舵瀯杩佺Щ**锛氳縼绉诲埌鏍囧噯鐨勬ā鍧楃洰褰曠粨鏋勶紙`modules/rvw`锛?2. **鍔熻兘鍗囩骇**锛氭暣鍚堛€婃櫤鑳芥湡鍒婂<E98D92>绋跨郴缁烳VP浜у搧闇€姹傛枃妗c€嬬殑鏍稿績鍔熻兘
|
||||
1. **架构迁移**:迁移到标准的模块目录结构(`modules/rvw`)
|
||||
2. **功能升级**:整合《智能期刊审稿系统MVP产品需求文档》的核心功能
|
||||
|
||||
### 2. 迁移原则
|
||||
|
||||
| 原则 | 说明 |
|
||||
|------|------|
|
||||
| **稳定优先** | 每个Phase完成后必须通过测试验证 |
|
||||
| **瀹夊叏鍙<EFBFBD>潬** | 鏁版嵁搴撹縼绉诲墠蹇呴』澶囦唤锛屾敮鎸佸洖婊?|
|
||||
| **安全可靠** | 数据库迁移前必须备份,支持回滚 |
|
||||
| **阶段验证** | 每个Phase有明确的验收标准 |
|
||||
| **鍚戝悗鍏煎<EFBFBD>** | 淇濈暀鏃<EFBFBD>PI杩囨浮鏈燂紝涓嶅奖鍝嶇幇鏈夊姛鑳?|
|
||||
| **娓愯繘寮?* | 鍏堟牳蹇冨悗鎵╁睍锛屽厛鍚庣<E98D9A>鍚庡墠绔?|
|
||||
| **向后兼容** | 保留旧API过渡期,不影响现有功能 |
|
||||
| **渐进式** | 先核心后扩展,先后端后前端 |
|
||||
|
||||
### 3. 功能范围
|
||||
|
||||
| 鍔熻兘 | 鏈<><E98F88>寮€鍙?| 鏁版嵁搴撴敮鎾?| 璇存槑 |
|
||||
| 功能 | 本次开发 | 数据库支撑 | 说明 |
|
||||
|------|:--------:|:----------:|------|
|
||||
| **鏍稿績AI璇勪及** | 鉁?| 鉁?| 绋跨害瑙勮寖鎬?鏂规硶瀛?|
|
||||
| **鎵归噺涓婁紶** | 鉁?| 鉁?| 澶氭枃浠朵笂浼?|
|
||||
| **瀹$ǹ宸ヤ綔鍙?* | 鉁?| 鉁?| 瀹借〃甯冨眬+绛涢€?|
|
||||
| **鏅鸿兘浣撻€夋嫨** | 鉁?| 鉁?| 鍙<>€?涓<>垨2涓?|
|
||||
| **鎵归噺鎿嶄綔** | 鉁?| 鉁?| 鎵归噺杩愯<E69DA9>瀹℃煡 |
|
||||
| **鐘舵€佺瓫閫?* | 鉁?| 鉁?| 鍏ㄩ儴/寰呭<E5AFB0>鐞?宸插畬鎴?|
|
||||
| PDF鎶ュ憡瀵煎嚭 | 鉁?| 鉁?| 浼樺寲鐜版湁鍔熻兘 |
|
||||
| PICO鍗$墖 | 鈴革笍 | 鉁?| **鏆備笉寮€鍙戯紝鏁版嵁搴撻<EFBFBD>鐣?* |
|
||||
| 绯荤粺璁剧疆 | 鈴革笍 | 鉁?| **鏆備笉寮€鍙戯紝鏁版嵁搴撻<EFBFBD>鐣?* |
|
||||
| 鍘嗗彶褰掓。 | 鈴革笍 | 鉁?| **鏆備笉寮€鍙戯紝鏁版嵁搴撻<EFBFBD>鐣?* |
|
||||
| 鐧诲綍椤甸潰 | 鈴革笍 | - | 鏆備笉寮€鍙?|
|
||||
| **核心AI评估** | ✅ | ✅ | 稿约规范性+方法学 |
|
||||
| **批量上传** | ✅ | ✅ | 多文件上传 |
|
||||
| **审稿工作台** | ✅ | ✅ | 宽表布局+筛选 |
|
||||
| **智能体选择** | ✅ | ✅ | 可选1个或2个 |
|
||||
| **批量操作** | ✅ | ✅ | 批量运行审查 |
|
||||
| **状态筛选** | ✅ | ✅ | 全部/待处理/已完成 |
|
||||
| PDF报告导出 | ✅ | ✅ | 优化现有功能 |
|
||||
| PICO卡片 | ⏸️ | ✅ | **暂不开发,数据库预留** |
|
||||
| 系统设置 | ⏸️ | ✅ | **暂不开发,数据库预留** |
|
||||
| 历史归档 | ⏸️ | ✅ | **暂不开发,数据库预留** |
|
||||
| 登录页面 | ⏸️ | - | 暂不开发 |
|
||||
|
||||
### 4. 智能体选择说明
|
||||
|
||||
鐢ㄦ埛鍙<EFBFBD>互鐏垫椿閫夋嫨杩愯<EFBFBD>鐨勬櫤鑳戒綋锛?
|
||||
用户可以灵活选择运行的智能体:
|
||||
|
||||
```
|
||||
閫夐」 A: 鍙<EFBFBD>€夋嫨銆岀ǹ绾﹁<EFBFBD>鑼冩€ф櫤鑳戒綋銆? 鈫?鍙<>繍琛岃<E7909B>鑼冩€ц瘎浼?閫夐」 B: 鍙<>€夋嫨銆屾柟娉曞<E5A889>缁熻<E7BC81>鏅鸿兘浣撱€? 鈫?鍙<>繍琛屾柟娉曞<E5A889>璇勪及
|
||||
閫夐」 C: 鍚屾椂閫夋嫨涓や釜鏅鸿兘浣? 鈫?鍚屾椂杩愯<E69DA9>涓ら」璇勪及锛堥粯璁わ級
|
||||
选项 A: 只选择「稿约规范性智能体」 → 只运行规范性评估
|
||||
选项 B: 只选择「方法学统计智能体」 → 只运行方法学评估
|
||||
选项 C: 同时选择两个智能体 → 同时运行两项评估(默认)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 馃搳 鏁版嵁搴撹<E690B4>璁★紙瀹屾暣鐗堬紝鏀<E7B49D>拺鏈<E68BBA>潵鎵╁睍锛?
|
||||
## 📊 数据库设计(完整版,支撑未来扩展)
|
||||
|
||||
### 1. 期刊配置表(预留,暂不使用)
|
||||
|
||||
```prisma
|
||||
@@ -79,16 +84,20 @@ model JournalConfig {
|
||||
model ReviewTask {
|
||||
id String @id @default(uuid())
|
||||
userId String @map("user_id")
|
||||
journalId String? @map("journal_id") // 棰勭暀锛氭湡鍒婂叧鑱?
|
||||
journalId String? @map("journal_id") // 预留:期刊关联
|
||||
|
||||
// 文件信息
|
||||
fileName String @map("file_name")
|
||||
fileSize Int @map("file_size")
|
||||
filePath String? @map("file_path")
|
||||
extractedText String @map("extracted_text")
|
||||
wordCount Int? @map("word_count")
|
||||
authorName String? @map("author_name") // 棰勭暀锛氫綔鑰呮彁鍙?
|
||||
// 鐘舵€佺<E282AC>鐞? status String @default("pending")
|
||||
// 鉁?鏅鸿兘浣撻€夋嫨锛氬彲閫?涓<>垨2涓? selectedAgents String[] @default(["editorial", "methodology"]) @map("selected_agents")
|
||||
authorName String? @map("author_name") // 预留:作者提取
|
||||
|
||||
// 状态管理
|
||||
status String @default("pending")
|
||||
// ✅ 智能体选择:可选1个或2个
|
||||
selectedAgents String[] @default(["editorial", "methodology"]) @map("selected_agents")
|
||||
|
||||
// 评估结果
|
||||
editorialReview Json? @map("editorial_review")
|
||||
@@ -102,13 +111,15 @@ model ReviewTask {
|
||||
// 预留:PICO提取(暂不使用)
|
||||
picoExtract Json? @map("pico_extract")
|
||||
|
||||
// 鍏冩暟鎹? modelUsed String? @map("model_used")
|
||||
// 元数据
|
||||
modelUsed String? @map("model_used")
|
||||
startedAt DateTime? @map("started_at")
|
||||
completedAt DateTime? @map("completed_at")
|
||||
durationSeconds Int? @map("duration_seconds")
|
||||
errorMessage String? @map("error_message")
|
||||
|
||||
// 棰勭暀锛氬綊妗e姛鑳斤紙鏆備笉浣跨敤锛? isArchived Boolean @default(false) @map("is_archived")
|
||||
// 预留:归档功能(暂不使用)
|
||||
isArchived Boolean @default(false) @map("is_archived")
|
||||
archivedAt DateTime? @map("archived_at")
|
||||
|
||||
createdAt DateTime @default(now()) @map("created_at")
|
||||
@@ -130,26 +141,29 @@ model ReviewTask {
|
||||
|
||||
### 3. 字段说明
|
||||
|
||||
| 瀛楁<EFBFBD> | 鏈<><E98F88>浣跨敤 | 棰勭暀鐢ㄩ€?|
|
||||
| 字段 | 本次使用 | 预留用途 |
|
||||
|------|:--------:|---------|
|
||||
| `journalId` | 鉂?| 绯荤粺璁剧疆锛氭湡鍒婂叧鑱?|
|
||||
| `authorName` | 鉂?| 鑷<>姩鎻愬彇浣滆€呭悕 |
|
||||
| `selectedAgents` | 鉁?| 鐢ㄦ埛閫夋嫨鐨勬櫤鑳戒綋 |
|
||||
| `editorialScore` | 鉁?| 鍒楄〃鏄剧ず瑙勮寖鎬у垎鏁?|
|
||||
| `methodologyStatus` | 鉁?| 鍒楄〃鏄剧ず鏂规硶瀛︾姸鎬?|
|
||||
| `picoExtract` | 鉂?| PICO鍗$墖鏁版嵁 |
|
||||
| `isArchived` | 鉂?| 鍘嗗彶褰掓。鍔熻兘 |
|
||||
| `archivedAt` | 鉂?| 褰掓。鏃堕棿 |
|
||||
| `journalId` | ❌ | 系统设置:期刊关联 |
|
||||
| `authorName` | ❌ | 自动提取作者名 |
|
||||
| `selectedAgents` | ✅ | 用户选择的智能体 |
|
||||
| `editorialScore` | ✅ | 列表显示规范性分数 |
|
||||
| `methodologyStatus` | ✅ | 列表显示方法学状态 |
|
||||
| `picoExtract` | ❌ | PICO卡片数据 |
|
||||
| `isArchived` | ❌ | 历史归档功能 |
|
||||
| `archivedAt` | ❌ | 归档时间 |
|
||||
|
||||
---
|
||||
|
||||
## 📋 安全迁移策略
|
||||
|
||||
### 1. 杩佺Щ鍓嶅噯澶?
|
||||
```bash
|
||||
# 1. 澶囦唤鏁版嵁搴?pg_dump -h localhost -U postgres -d airesearch -F c -f backup_before_rvw_migration.dump
|
||||
### 1. 迁移前准备
|
||||
|
||||
# 2. 璁板綍褰撳墠鏁版嵁閲?SELECT COUNT(*) FROM public.review_tasks;
|
||||
```bash
|
||||
# 1. 备份数据库
|
||||
pg_dump -h localhost -U postgres -d airesearch -F c -f backup_before_rvw_migration.dump
|
||||
|
||||
# 2. 记录当前数据量
|
||||
SELECT COUNT(*) FROM public.review_tasks;
|
||||
|
||||
# 3. 导出关键数据(可选)
|
||||
COPY public.review_tasks TO '/tmp/review_tasks_backup.csv' WITH CSV HEADER;
|
||||
@@ -166,49 +180,55 @@ ALTER TABLE review_schema.review_tasks SET SCHEMA public;
|
||||
DROP SCHEMA review_schema;
|
||||
```
|
||||
|
||||
### 3. 闃舵<EFBFBD>鎬ч獙璇?
|
||||
姣忎釜Phase瀹屾垚鍚庡繀椤婚€氳繃浠ヤ笅楠岃瘉锛?
|
||||
### 3. 阶段性验证
|
||||
|
||||
每个Phase完成后必须通过以下验证:
|
||||
|
||||
| Phase | 验证内容 | 验收标准 |
|
||||
|-------|---------|---------|
|
||||
| Phase 1 | 后端API测试 | 所有API返回正确,日志无ERROR |
|
||||
| Phase 2 | 鏁版嵁搴撹縼绉?| 鏁版嵁瀹屾暣锛屾煡璇㈡<E79287>甯革紝绱㈠紩鏈夋晥 |
|
||||
| Phase 2 | 数据库迁移 | 数据完整,查询正常,索引有效 |
|
||||
| Phase 3 | 前端功能测试 | 核心流程通顺,无白屏/报错 |
|
||||
| Phase 4 | 闆嗘垚娴嬭瘯 | 绔<>埌绔<E59F8C>祦绋嬫<E7BB8B>甯?|
|
||||
| Phase 4 | 集成测试 | 端到端流程正常 |
|
||||
| Phase 5 | 验收测试 | 符合MVP验收标准 |
|
||||
|
||||
---
|
||||
|
||||
## 馃搵 寮€鍙戜换鍔℃竻鍗?
|
||||
## 📋 开发任务清单
|
||||
|
||||
### Phase 1:后端模块迁移(2天)
|
||||
|
||||
#### Day 1 涓婂崍锛氬垱寤烘ā鍧楃粨鏋?+ 澶嶇敤鏍稿績浠g爜
|
||||
#### Day 1 上午:创建模块结构 + 复用核心代码
|
||||
|
||||
**1.1 创建目录结构**
|
||||
|
||||
```
|
||||
backend/src/modules/rvw/
|
||||
├── routes/
|
||||
鈹? 鈹斺攢鈹€ index.ts # 璺<EFBFBD>敱瀹氫箟
|
||||
│ └── index.ts # 路由定义
|
||||
├── controllers/
|
||||
鈹? 鈹斺攢鈹€ reviewController.ts # 鎺у埗鍣?鈹溾攢鈹€ services/
|
||||
鈹? 鈹溾攢鈹€ reviewService.ts # 涓绘湇鍔★紙澶嶇敤+鎵╁睍锛?鈹? 鈹溾攢鈹€ editorialService.ts # 绋跨害璇勪及锛堝<E9949B>鐢<EFBFBD>級
|
||||
鈹? 鈹斺攢鈹€ methodologyService.ts # 鏂规硶瀛﹁瘎浼帮紙澶嶇敤锛?鈹溾攢鈹€ types/
|
||||
鈹? 鈹斺攢鈹€ index.ts # 绫诲瀷瀹氫箟
|
||||
│ └── reviewController.ts # 控制器
|
||||
├── services/
|
||||
│ ├── reviewService.ts # 主服务(复用+扩展)
|
||||
│ ├── editorialService.ts # 稿约评估(复用)
|
||||
│ └── methodologyService.ts # 方法学评估(复用)
|
||||
├── types/
|
||||
│ └── index.ts # 类型定义
|
||||
├── prompts/
|
||||
鈹? 鈹溾攢鈹€ editorial_system.txt # 绋跨害Prompt
|
||||
鈹? 鈹斺攢鈹€ methodology_system.txt # 鏂规硶瀛<EFBFBD>rompt
|
||||
│ ├── editorial_system.txt # 稿约Prompt
|
||||
│ └── methodology_system.txt # 方法学Prompt
|
||||
└── index.ts # 模块入口
|
||||
```
|
||||
|
||||
- [ ] **1.1.1** 创建目录结构
|
||||
- [ ] **1.1.2** 澶嶅埗 `reviewEditorialStandards()` 鈫?`editorialService.ts`
|
||||
- [ ] **1.1.3** 澶嶅埗 `reviewMethodology()` 鈫?`methodologyService.ts`
|
||||
- [ ] **1.1.4** 澶嶅埗 `parseJSONFromLLMResponse()` 鈫?`utils.ts`
|
||||
- [ ] **1.1.2** 复制 `reviewEditorialStandards()` → `editorialService.ts`
|
||||
- [ ] **1.1.3** 复制 `reviewMethodology()` → `methodologyService.ts`
|
||||
- [ ] **1.1.4** 复制 `parseJSONFromLLMResponse()` → `utils.ts`
|
||||
- [ ] **1.1.5** 复制 Prompt 文件到模块内
|
||||
|
||||
**1.2 浜戝師鐢熸敼閫?*
|
||||
**1.2 云原生改造**
|
||||
|
||||
- [ ] **1.2.1** 鏇挎崲 `console.log` 鈫?`logger`
|
||||
- [ ] **1.2.1** 替换 `console.log` → `logger`
|
||||
- [ ] **1.2.2** 移除 Mock用户ID,集成JWT认证
|
||||
- [ ] **1.2.3** 使用 `process.env` 配置
|
||||
|
||||
@@ -222,7 +242,8 @@ export type AgentType = 'editorial' | 'methodology';
|
||||
|
||||
export interface RunReviewParams {
|
||||
taskId: string;
|
||||
agents: AgentType[]; // 鍙<EFBFBD>€?涓<>垨2涓?}
|
||||
agents: AgentType[]; // 可选1个或2个
|
||||
}
|
||||
|
||||
// services/reviewService.ts
|
||||
async function runReview(params: RunReviewParams) {
|
||||
@@ -233,7 +254,8 @@ async function runReview(params: RunReviewParams) {
|
||||
throw new Error('请至少选择一个智能体');
|
||||
}
|
||||
|
||||
// 鏇存柊浠诲姟鐘舵€? await prisma.reviewTask.update({
|
||||
// 更新任务状态
|
||||
await prisma.reviewTask.update({
|
||||
where: { id: taskId },
|
||||
data: {
|
||||
status: 'reviewing',
|
||||
@@ -279,7 +301,8 @@ function calculateOverallScore(editorial: any, methodology: any, agents: AgentTy
|
||||
// 两个都选:40% + 60%
|
||||
return editorial.overall_score * 0.4 + methodology.overall_score * 0.6;
|
||||
} else if (agents.includes('editorial') && editorial) {
|
||||
// 鍙<EFBFBD>€夎<EFBFBD>鑼冩€? return editorial.overall_score;
|
||||
// 只选规范性
|
||||
return editorial.overall_score;
|
||||
} else if (agents.includes('methodology') && methodology) {
|
||||
// 只选方法学
|
||||
return methodology.overall_score;
|
||||
@@ -291,8 +314,9 @@ function calculateOverallScore(editorial: any, methodology: any, agents: AgentTy
|
||||
- [ ] **1.3.1** 实现智能体选择类型定义
|
||||
- [ ] **1.3.2** 实现 `runReview()` 函数
|
||||
- [ ] **1.3.3** 实现综合分数计算逻辑
|
||||
- [ ] **1.3.4** 瀹炵幇鏂规硶瀛︾姸鎬佸垽鏂<EFBFBD>紙pass/warn/fail锛?
|
||||
#### Day 2 涓婂崍锛氭壒閲忔搷浣?+ API鎵╁睍
|
||||
- [ ] **1.3.4** 实现方法学状态判断(pass/warn/fail)
|
||||
|
||||
#### Day 2 上午:批量操作 + API扩展
|
||||
|
||||
**1.4 批量运行实现**
|
||||
|
||||
@@ -301,7 +325,8 @@ function calculateOverallScore(editorial: any, methodology: any, agents: AgentTy
|
||||
async function batchRunReview(params: BatchRunParams) {
|
||||
const { taskIds, agents } = params;
|
||||
|
||||
// 闄愬埗骞跺彂鏁? const MAX_CONCURRENT = 5;
|
||||
// 限制并发数
|
||||
const MAX_CONCURRENT = 5;
|
||||
const results = [];
|
||||
|
||||
for (let i = 0; i < taskIds.length; i += MAX_CONCURRENT) {
|
||||
@@ -317,8 +342,9 @@ async function batchRunReview(params: BatchRunParams) {
|
||||
```
|
||||
|
||||
- [ ] **1.4.1** 实现批量运行接口
|
||||
- [ ] **1.4.2** 瀹炵幇骞跺彂鎺у埗锛堟渶澶?涓<>級
|
||||
- [ ] **1.4.3** 瀹炵幇閿欒<EFBFBD>澶勭悊锛堝崟涓<EFBFBD>け璐ヤ笉褰卞搷鍏朵粬锛?
|
||||
- [ ] **1.4.2** 实现并发控制(最多5个)
|
||||
- [ ] **1.4.3** 实现错误处理(单个失败不影响其他)
|
||||
|
||||
**1.5 API路由定义**
|
||||
|
||||
```typescript
|
||||
@@ -338,52 +364,58 @@ export default async function rvwRoutes(fastify: FastifyInstance) {
|
||||
```
|
||||
|
||||
- [ ] **1.5.1** 实现路由定义
|
||||
- [ ] **1.5.2** 瀹炵幇鎺у埗鍣ㄦ柟娉?- [ ] **1.5.3** 娣诲姞璇锋眰楠岃瘉
|
||||
- [ ] **1.5.2** 实现控制器方法
|
||||
- [ ] **1.5.3** 添加请求验证
|
||||
|
||||
#### Day 2 涓嬪崍锛氭敞鍐岃矾鐢?+ Phase 1 楠岃瘉
|
||||
#### Day 2 下午:注册路由 + Phase 1 验证
|
||||
|
||||
**1.6 娉ㄥ唽鏂拌矾鐢?*
|
||||
**1.6 注册新路由**
|
||||
|
||||
```typescript
|
||||
// backend/src/index.ts
|
||||
import rvwRoutes from './modules/rvw/routes/index.js';
|
||||
|
||||
// 娉ㄥ唽鏂拌矾鐢憋紙v2锛?await fastify.register(rvwRoutes, { prefix: '/api/v1/rvw' });
|
||||
logger.info('鉁?RVW绋夸欢瀹℃煡璺<E785A1>敱宸叉敞鍐? /api/v1/rvw');
|
||||
// 注册新路由(v2)
|
||||
await fastify.register(rvwRoutes, { prefix: '/api/v2/rvw' });
|
||||
logger.info('✅ RVW稿件审查路由已注册: /api/v2/rvw');
|
||||
|
||||
// 淇濈暀鏃ц矾鐢憋紙鍏煎<EFBFBD>锛?await fastify.register(reviewRoutes, { prefix: '/api/v1' });
|
||||
logger.info('鉁?Legacy瀹$ǹ璺<C7B9>敱淇濈暀: /api/v1/review');
|
||||
// 保留旧路由(兼容)
|
||||
await fastify.register(reviewRoutes, { prefix: '/api/v1' });
|
||||
logger.info('✅ Legacy审稿路由保留: /api/v1/review');
|
||||
```
|
||||
|
||||
- [ ] **1.6.1** 娉ㄥ唽鏂拌矾鐢?- [ ] **1.6.2** 淇濈暀鏃ц矾鐢卞吋瀹?
|
||||
- [ ] **1.6.1** 注册新路由
|
||||
- [ ] **1.6.2** 保留旧路由兼容
|
||||
|
||||
**1.7 Phase 1 验证测试**
|
||||
|
||||
```http
|
||||
### 1. 创建任务
|
||||
POST {{baseUrl}}/api/v1/rvw/tasks
|
||||
POST {{baseUrl}}/api/v2/rvw/tasks
|
||||
Content-Type: multipart/form-data
|
||||
|
||||
# file: test.docx
|
||||
|
||||
### 2. 运行审查(只选规范性)
|
||||
POST {{baseUrl}}/api/v1/rvw/tasks/{{taskId}}/run
|
||||
POST {{baseUrl}}/api/v2/rvw/tasks/{{taskId}}/run
|
||||
Content-Type: application/json
|
||||
|
||||
{ "agents": ["editorial"] }
|
||||
|
||||
### 3. 杩愯<EFBFBD>瀹℃煡锛堝彧閫夋柟娉曞<EFBFBD>锛?POST {{baseUrl}}/api/v1/rvw/tasks/{{taskId}}/run
|
||||
### 3. 运行审查(只选方法学)
|
||||
POST {{baseUrl}}/api/v2/rvw/tasks/{{taskId}}/run
|
||||
Content-Type: application/json
|
||||
|
||||
{ "agents": ["methodology"] }
|
||||
|
||||
### 4. 运行审查(两个都选)
|
||||
POST {{baseUrl}}/api/v1/rvw/tasks/{{taskId}}/run
|
||||
POST {{baseUrl}}/api/v2/rvw/tasks/{{taskId}}/run
|
||||
Content-Type: application/json
|
||||
|
||||
{ "agents": ["editorial", "methodology"] }
|
||||
|
||||
### 5. 批量运行
|
||||
POST {{baseUrl}}/api/v1/rvw/tasks/batch/run
|
||||
POST {{baseUrl}}/api/v2/rvw/tasks/batch/run
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
@@ -392,22 +424,22 @@ Content-Type: application/json
|
||||
}
|
||||
|
||||
### 6. 获取任务列表
|
||||
GET {{baseUrl}}/api/v1/rvw/tasks?status=pending&limit=10
|
||||
GET {{baseUrl}}/api/v2/rvw/tasks?status=pending&limit=10
|
||||
|
||||
### 7. 获取报告
|
||||
GET {{baseUrl}}/api/v1/rvw/tasks/{{taskId}}/report
|
||||
GET {{baseUrl}}/api/v2/rvw/tasks/{{taskId}}/report
|
||||
```
|
||||
|
||||
**Phase 1 楠屾敹鏍囧噯锛?*
|
||||
**Phase 1 验收标准:**
|
||||
|
||||
| 娴嬭瘯椤?| 棰勬湡缁撴灉 | 閫氳繃 |
|
||||
| 测试项 | 预期结果 | 通过 |
|
||||
|--------|---------|:----:|
|
||||
| 鍒涘缓浠诲姟 | 杩斿洖taskId锛岀姸鎬乸ending | 猬?|
|
||||
| 鍙<EFBFBD>€夎<EFBFBD>鑼冩€?| 鍙<>湁editorialReview鏈夊€?| 猬?|
|
||||
| 鍙<EFBFBD>€夋柟娉曞<EFBFBD> | 鍙<>湁methodologyReview鏈夊€?| 猬?|
|
||||
| 涓や釜閮介€?| 涓や釜Review閮芥湁鍊?| 猬?|
|
||||
| 鎵归噺杩愯<EFBFBD> | 澶氫釜浠诲姟閮藉畬鎴?| 猬?|
|
||||
| 鏃<EFBFBD>PI鍏煎<EFBFBD> | `/api/v1/review/*` 姝e父 | 猬?|
|
||||
| 创建任务 | 返回taskId,状态pending | ⬜ |
|
||||
| 只选规范性 | 只有editorialReview有值 | ⬜ |
|
||||
| 只选方法学 | 只有methodologyReview有值 | ⬜ |
|
||||
| 两个都选 | 两个Review都有值 | ⬜ |
|
||||
| 批量运行 | 多个任务都完成 | ⬜ |
|
||||
| 旧API兼容 | `/api/v1/review/*` 正常 | ⬜ |
|
||||
|
||||
- [ ] **1.7.1** 编写测试用例
|
||||
- [ ] **1.7.2** 执行测试
|
||||
@@ -416,11 +448,12 @@ GET {{baseUrl}}/api/v1/rvw/tasks/{{taskId}}/report
|
||||
|
||||
---
|
||||
|
||||
### Phase 2锛氭暟鎹<EFBFBD>簱Schema杩佺Щ锛?.5澶╋級
|
||||
### Phase 2:数据库Schema迁移(0.5天)
|
||||
|
||||
#### 迁移前:备份
|
||||
|
||||
- [ ] **2.1** 澶囦唤鏁版嵁搴? ```bash
|
||||
- [ ] **2.1** 备份数据库
|
||||
```bash
|
||||
pg_dump -h localhost -U postgres -d airesearch -F c -f backup_phase2.dump
|
||||
```
|
||||
|
||||
@@ -436,7 +469,8 @@ GET {{baseUrl}}/api/v1/rvw/tasks/{{taskId}}/report
|
||||
-- 1. 创建新Schema
|
||||
CREATE SCHEMA IF NOT EXISTS review_schema;
|
||||
|
||||
-- 2. 鍒涘缓鏈熷垔閰嶇疆琛<EFBFBD>紙棰勭暀锛? CREATE TABLE review_schema.journal_configs (
|
||||
-- 2. 创建期刊配置表(预留)
|
||||
CREATE TABLE review_schema.journal_configs (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
name VARCHAR(255) NOT NULL,
|
||||
logo_url TEXT,
|
||||
@@ -449,7 +483,8 @@ GET {{baseUrl}}/api/v1/rvw/tasks/{{taskId}}/report
|
||||
-- 3. 迁移review_tasks表到新Schema
|
||||
ALTER TABLE public.review_tasks SET SCHEMA review_schema;
|
||||
|
||||
-- 4. 娣诲姞鏂板瓧娈碉紙鏀<EFBFBD>寔鏈<EFBFBD>潵鎵╁睍锛? ALTER TABLE review_schema.review_tasks
|
||||
-- 4. 添加新字段(支持未来扩展)
|
||||
ALTER TABLE review_schema.review_tasks
|
||||
ADD COLUMN IF NOT EXISTS journal_id UUID REFERENCES review_schema.journal_configs(id),
|
||||
ADD COLUMN IF NOT EXISTS author_name VARCHAR(255),
|
||||
ADD COLUMN IF NOT EXISTS selected_agents TEXT[] DEFAULT ARRAY['editorial', 'methodology'],
|
||||
@@ -470,7 +505,8 @@ GET {{baseUrl}}/api/v1/rvw/tasks/{{taskId}}/report
|
||||
|
||||
- [ ] **2.4** 更新Prisma Schema
|
||||
- 修改 `@@schema("review_schema")`
|
||||
- 娣诲姞鏂板瓧娈?
|
||||
- 添加新字段
|
||||
|
||||
- [ ] **2.5** 执行迁移
|
||||
```bash
|
||||
npx prisma migrate dev --name rvw_schema_migration
|
||||
@@ -478,8 +514,10 @@ GET {{baseUrl}}/api/v1/rvw/tasks/{{taskId}}/report
|
||||
|
||||
#### Phase 2 验证
|
||||
|
||||
- [ ] **2.6** 楠岃瘉鏁版嵁瀹屾暣鎬? ```sql
|
||||
-- 纭<><E7BAAD>鏁版嵁閲忎竴鑷? SELECT COUNT(*) FROM review_schema.review_tasks;
|
||||
- [ ] **2.6** 验证数据完整性
|
||||
```sql
|
||||
-- 确认数据量一致
|
||||
SELECT COUNT(*) FROM review_schema.review_tasks;
|
||||
|
||||
-- 确认字段可用
|
||||
SELECT id, selected_agents, editorial_score FROM review_schema.review_tasks LIMIT 5;
|
||||
@@ -491,15 +529,15 @@ GET {{baseUrl}}/api/v1/rvw/tasks/{{taskId}}/report
|
||||
LIMIT 5;
|
||||
```
|
||||
|
||||
**Phase 2 楠屾敹鏍囧噯锛?*
|
||||
**Phase 2 验收标准:**
|
||||
|
||||
| 娴嬭瘯椤?| 棰勬湡缁撴灉 | 閫氳繃 |
|
||||
| 测试项 | 预期结果 | 通过 |
|
||||
|--------|---------|:----:|
|
||||
| 鏁版嵁杩佺Щ | 鏁版嵁閲忎竴鑷?| 猬?|
|
||||
| 鏂板瓧娈?| 瀛楁<E7809B>瀛樺湪涓斿彲鐢?| 猬?|
|
||||
| 澶栭敭鍏崇郴 | 鍏宠仈姝e父 | 猬?|
|
||||
| 绱㈠紩鏈夋晥 | 鏌ヨ<E98F8C>鎬ц兘姝e父 | 猬?|
|
||||
| API姝e父 | 鍚庣<E98D9A>API浠嶅彲鐢?| 猬?|
|
||||
| 数据迁移 | 数据量一致 | ⬜ |
|
||||
| 新字段 | 字段存在且可用 | ⬜ |
|
||||
| 外键关系 | 关联正常 | ⬜ |
|
||||
| 索引有效 | 查询性能正常 | ⬜ |
|
||||
| API正常 | 后端API仍可用 | ⬜ |
|
||||
|
||||
- [ ] **2.7** 确认Phase 2通过
|
||||
|
||||
@@ -507,33 +545,38 @@ GET {{baseUrl}}/api/v1/rvw/tasks/{{taskId}}/report
|
||||
|
||||
### Phase 3:前端重构(3天)
|
||||
|
||||
#### Day 3锛氭ā鍧楃粨鏋?+ API灞?
|
||||
#### Day 3:模块结构 + API层
|
||||
|
||||
**3.1 创建模块结构**
|
||||
|
||||
```
|
||||
frontend-v2/src/modules/rvw/
|
||||
├── api/
|
||||
鈹? 鈹斺攢鈹€ reviewApi.ts # API灏佽<EFBFBD>
|
||||
│ └── reviewApi.ts # API封装
|
||||
├── components/
|
||||
鈹? 鈹溾攢鈹€ ScoreCard.tsx # 澶嶇敤
|
||||
鈹? 鈹溾攢鈹€ EditorialReview.tsx # 澶嶇敤
|
||||
鈹? 鈹溾攢鈹€ MethodologyReview.tsx # 澶嶇敤
|
||||
鈹? 鈹溾攢鈹€ AgentSelector.tsx # 馃啎 鏅鸿兘浣撻€夋嫨寮圭獥
|
||||
鈹? 鈹溾攢鈹€ BatchToolbar.tsx # 馃啎 鎵归噺鎿嶄綔鏍?鈹? 鈹溾攢鈹€ TaskTable.tsx # 馃啎 浠诲姟鍒楄〃琛ㄦ牸
|
||||
鈹? 鈹斺攢鈹€ StatusFilter.tsx # 馃啎 鐘舵€佺瓫閫?鈹溾攢鈹€ pages/
|
||||
鈹? 鈹溾攢鈹€ ReviewDashboard.tsx # 馃啎 瀹$ǹ宸ヤ綔鍙?鈹? 鈹斺攢鈹€ ReviewDetail.tsx # 鎶ュ憡璇︽儏锛堜紭鍖栵級
|
||||
│ ├── ScoreCard.tsx # 复用
|
||||
│ ├── EditorialReview.tsx # 复用
|
||||
│ ├── MethodologyReview.tsx # 复用
|
||||
│ ├── AgentSelector.tsx # 🆕 智能体选择弹窗
|
||||
│ ├── BatchToolbar.tsx # 🆕 批量操作栏
|
||||
│ ├── TaskTable.tsx # 🆕 任务列表表格
|
||||
│ └── StatusFilter.tsx # 🆕 状态筛选
|
||||
├── pages/
|
||||
│ ├── ReviewDashboard.tsx # 🆕 审稿工作台
|
||||
│ └── ReviewDetail.tsx # 报告详情(优化)
|
||||
├── hooks/
|
||||
鈹? 鈹溾攢鈹€ useReviewTask.ts
|
||||
鈹? 鈹斺攢鈹€ useBatchOperation.ts
|
||||
│ ├── useReviewTask.ts
|
||||
│ └── useBatchOperation.ts
|
||||
├── stores/
|
||||
鈹? 鈹斺攢鈹€ useReviewStore.ts
|
||||
│ └── useReviewStore.ts
|
||||
├── types/
|
||||
鈹? 鈹斺攢鈹€ index.ts
|
||||
│ └── index.ts
|
||||
└── index.tsx
|
||||
```
|
||||
|
||||
- [ ] **3.1.1** 创建目录结构
|
||||
- [ ] **3.1.2** 澶嶇敤鐜版湁缁勪欢锛圫coreCard銆丒ditorialReview銆丮ethodologyReview锛?
|
||||
- [ ] **3.1.2** 复用现有组件(ScoreCard、EditorialReview、MethodologyReview)
|
||||
|
||||
**3.2 API封装**
|
||||
|
||||
```typescript
|
||||
@@ -542,12 +585,12 @@ export type AgentType = 'editorial' | 'methodology';
|
||||
|
||||
// 运行审查(支持选择智能体)
|
||||
export async function runReview(taskId: string, agents: AgentType[]): Promise<void> {
|
||||
return axios.post(`/api/v1/rvw/tasks/${taskId}/run`, { agents });
|
||||
return axios.post(`/api/v2/rvw/tasks/${taskId}/run`, { agents });
|
||||
}
|
||||
|
||||
// 批量运行
|
||||
export async function batchRunReview(taskIds: string[], agents: AgentType[]): Promise<void> {
|
||||
return axios.post('/api/v1/rvw/tasks/batch/run', { taskIds, agents });
|
||||
return axios.post('/api/v2/rvw/tasks/batch/run', { taskIds, agents });
|
||||
}
|
||||
|
||||
// 获取任务列表(带筛选)
|
||||
@@ -558,25 +601,30 @@ export interface TaskListParams {
|
||||
}
|
||||
|
||||
export async function getTaskList(params: TaskListParams): Promise<TaskListResponse> {
|
||||
return axios.get('/api/v1/rvw/tasks', { params });
|
||||
return axios.get('/api/v2/rvw/tasks', { params });
|
||||
}
|
||||
```
|
||||
|
||||
- [ ] **3.2.1** 实现API封装
|
||||
- [ ] **3.2.2** 实现类型定义
|
||||
|
||||
#### Day 4锛氭牳蹇冮〉闈㈠紑鍙?
|
||||
#### Day 4:核心页面开发
|
||||
|
||||
**3.3 智能体选择弹窗**
|
||||
|
||||
```tsx
|
||||
// components/AgentSelector.tsx
|
||||
interface AgentSelectorProps {
|
||||
visible: boolean;
|
||||
taskIds: string[]; // 鏀<EFBFBD>寔鍗曚釜鎴栧<EFBFBD>涓? onConfirm: (agents: AgentType[]) => void;
|
||||
taskIds: string[]; // 支持单个或多个
|
||||
onConfirm: (agents: AgentType[]) => void;
|
||||
onCancel: () => void;
|
||||
}
|
||||
|
||||
// 寮圭獥鍐呭<EFBFBD>锛?// 鉁?绋跨害瑙勮寖鎬ф櫤鑳戒綋锛堥粯璁ら€変腑锛?// 鏍煎紡銆佸弬鑰冩枃鐚<E69E83>€佸浘鐗囨<E99097>鏌?// 鈽?鏂规硶瀛︾粺璁℃櫤鑳戒綋
|
||||
// 弹窗内容:
|
||||
// ✅ 稿约规范性智能体(默认选中)
|
||||
// 格式、参考文献、图片检查
|
||||
// ☐ 方法学统计智能体
|
||||
// DeepSeek 深度逻辑推理
|
||||
//
|
||||
// 提示:可选择1个或同时选择2个智能体
|
||||
@@ -585,21 +633,37 @@ interface AgentSelectorProps {
|
||||
```
|
||||
|
||||
- [ ] **3.3.1** 实现智能体选择弹窗
|
||||
- [ ] **3.3.2** 鏀<EFBFBD>寔鍗曢€夊拰澶氶€?- [ ] **3.3.3** 榛樿<E6A69B>閫変腑瑙勮寖鎬ф櫤鑳戒綋
|
||||
- [ ] **3.3.2** 支持单选和多选
|
||||
- [ ] **3.3.3** 默认选中规范性智能体
|
||||
|
||||
**3.4 瀹$ǹ宸ヤ綔鍙?*
|
||||
**3.4 审稿工作台**
|
||||
|
||||
```
|
||||
鈹屸攢鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹?鈹? Header: [Logo] 鏅鸿兘瀹$ǹ绯荤粺 [涓婁紶鏂扮ǹ浠禲 鈹?鈹溾攢鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹?鈹? Filter: [鍏ㄩ儴|寰呭<E5AFB0>鐞唡宸插畬鎴怾 鈹?鈹溾攢鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹?鈹? 鈹屸攢鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹? 鈹?鈹? 鈹? 鈽? 鏂囦欢鍚嶇О/淇℃伅 涓婁紶鏃堕棿 瀹$ǹ缁村害 缁撴灉鎽樿<E98EBD> 鎿嶄綔 鈹? 鈹?鈹? 鈹? 鈽? 鏇块浄鍒╃彔鍗曟姉...pdf 10:30 [瑙勮寖][鏂规硶] 92鍒? [鏌ョ湅] 鈹?鈹? 鈹? 鈽? 楂樿<E6A582>鍘嬭嵂鐗?..docx 鍒氬垰 [鏈<>繍琛宂 绛夊緟... [寮€濮媇 鈹?鈹? 鈹斺攢鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹? 鈹?鈹溾攢鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹?鈹? [Batch Toolbar: 3涓<33>枃浠跺凡閫変腑 | 杩愯<E69DA9>鏅鸿兘瀹$ǹ | 鉁昡 鈹?鈹斺攢鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹?```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ Header: [Logo] 智能审稿系统 [上传新稿件] │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ Filter: [全部|待处理|已完成] │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ ┌───────────────────────────────────────────────────────────┐ │
|
||||
│ │ ☐ 文件名称/信息 上传时间 审稿维度 结果摘要 操作 │ │
|
||||
│ │ ☐ 替雷利珠单抗...pdf 10:30 [规范][方法] 92分 [查看] │
|
||||
│ │ ☐ 高血压药物...docx 刚刚 [未运行] 等待... [开始] │
|
||||
│ └───────────────────────────────────────────────────────────┘ │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ [Batch Toolbar: 3个文件已选中 | 运行智能审稿 | ✕] │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
- [ ] **3.4.1** 实现页面布局
|
||||
- [ ] **3.4.2** 实现任务列表表格
|
||||
- [ ] **3.4.3** 瀹炵幇鐘舵€佺瓫閫?- [ ] **3.4.4** 瀹炵幇鎵归噺鎿嶄綔鏍?
|
||||
#### Day 5锛氭姤鍛婅<E98D9B>鎯?+ Phase 3 楠岃瘉
|
||||
- [ ] **3.4.3** 实现状态筛选
|
||||
- [ ] **3.4.4** 实现批量操作栏
|
||||
|
||||
**3.5 鎶ュ憡璇︽儏椤?*
|
||||
#### Day 5:报告详情 + Phase 3 验证
|
||||
|
||||
- [ ] **3.5.1** 瀹炵幇Tab鍒囨崲锛堣<E9949B>鑼冩€?鏂规硶瀛︼級
|
||||
**3.5 报告详情页**
|
||||
|
||||
- [ ] **3.5.1** 实现Tab切换(规范性/方法学)
|
||||
- [ ] **3.5.2** 复用评估详情组件
|
||||
- [ ] **3.5.3** 根据选择的智能体显示对应Tab
|
||||
- [ ] **3.5.4** 实现导出报告按钮
|
||||
@@ -622,14 +686,14 @@ interface AgentSelectorProps {
|
||||
|
||||
**Phase 3 验证测试**
|
||||
|
||||
| 娴嬭瘯椤?| 棰勬湡缁撴灉 | 閫氳繃 |
|
||||
| 测试项 | 预期结果 | 通过 |
|
||||
|--------|---------|:----:|
|
||||
| 椤甸潰鍔犺浇 | 宸ヤ綔鍙版<E98D99>甯告樉绀?| 猬?|
|
||||
| 鏂囦欢涓婁紶 | 鏀<>寔澶氭枃浠?| 猬?|
|
||||
| 鏅鸿兘浣撻€夋嫨 | 鍙<>€?涓<>垨2涓?| 猬?|
|
||||
| 鎵归噺鎿嶄綔 | 鎵归噺杩愯<E69DA9>鎴愬姛 | 猬?|
|
||||
| 鐘舵€佺瓫閫?| 绛涢€夌粨鏋滄<E98F8B>纭?| 猬?|
|
||||
| 鎶ュ憡鏌ョ湅 | 鏄剧ず瀵瑰簲璇勪及缁撴灉 | 猬?|
|
||||
| 页面加载 | 工作台正常显示 | ⬜ |
|
||||
| 文件上传 | 支持多文件 | ⬜ |
|
||||
| 智能体选择 | 可选1个或2个 | ⬜ |
|
||||
| 批量操作 | 批量运行成功 | ⬜ |
|
||||
| 状态筛选 | 筛选结果正确 | ⬜ |
|
||||
| 报告查看 | 显示对应评估结果 | ⬜ |
|
||||
|
||||
- [ ] **3.7** 确认Phase 3通过
|
||||
|
||||
@@ -637,41 +701,46 @@ interface AgentSelectorProps {
|
||||
|
||||
### Phase 4:集成测试(1天)
|
||||
|
||||
**4.1 绔<EFBFBD>埌绔<EFBFBD>祴璇?*
|
||||
**4.1 端到端测试**
|
||||
|
||||
| 测试场景 | 步骤 | 预期结果 |
|
||||
|---------|------|---------|
|
||||
| 鍗曟枃浠?鍗曟櫤鑳戒綋 | 涓婁紶鈫掗€夎<E282AC>鑼冩€р啋鏌ョ湅 | 鍙<>樉绀鸿<E7BB80>鑼冩€ф姤鍛?|
|
||||
| 鍗曟枃浠?鍙屾櫤鑳戒綋 | 涓婁紶鈫掗€変袱涓<E8A2B1>啋鏌ョ湅 | 鏄剧ず涓や釜鎶ュ憡Tab |
|
||||
| 单文件+单智能体 | 上传→选规范性→查看 | 只显示规范性报告 |
|
||||
| 单文件+双智能体 | 上传→选两个→查看 | 显示两个报告Tab |
|
||||
| 批量+双智能体 | 上传3个→批量运行 | 3个都完成 |
|
||||
| 鐘舵€佺瓫閫?| 涓婁紶鈫掔瓫閫夊緟澶勭悊 | 姝g‘杩囨护 |
|
||||
| 状态筛选 | 上传→筛选待处理 | 正确过滤 |
|
||||
|
||||
- [ ] **4.1.1** 执行端到端测试
|
||||
- [ ] **4.1.2** 修复发现的问题
|
||||
|
||||
- [ ] **4.1.1** 鎵ц<E98EB5>绔<EFBFBD>埌绔<E59F8C>祴璇?- [ ] **4.1.2** 淇<><E6B787>鍙戠幇鐨勯棶棰?
|
||||
**4.2 性能测试**
|
||||
|
||||
| 指标 | 目标 | 实际 |
|
||||
|------|------|------|
|
||||
| 鍒楄〃鍔犺浇 | < 1绉?| 猬?|
|
||||
| 鍗曟枃浠跺<EFBFBD>鏌?| < 2鍒嗛挓 | 猬?|
|
||||
| 5鏂囦欢骞跺彂 | < 5鍒嗛挓 | 猬?|
|
||||
| 列表加载 | < 1秒 | ⬜ |
|
||||
| 单文件审查 | < 2分钟 | ⬜ |
|
||||
| 5文件并发 | < 5分钟 | ⬜ |
|
||||
|
||||
- [ ] **4.2.1** 执行性能测试
|
||||
|
||||
**4.3 鍏煎<EFBFBD>鎬ф祴璇?*
|
||||
**4.3 兼容性测试**
|
||||
|
||||
- [ ] **4.3.1** Chrome浏览器测试
|
||||
- [ ] **4.3.2** Edge浏览器测试
|
||||
- [ ] **4.3.3** 旧API兼容性确认
|
||||
|
||||
- [ ] **4.3.1** Chrome娴忚<E5A8B4>鍣ㄦ祴璇?- [ ] **4.3.2** Edge娴忚<E5A8B4>鍣ㄦ祴璇?- [ ] **4.3.3** 鏃<>PI鍏煎<E98D8F>鎬х‘璁?
|
||||
---
|
||||
|
||||
### Phase 5锛氶獙鏀朵笌涓婄嚎锛?.5澶╋級
|
||||
### Phase 5:验收与上线(0.5天)
|
||||
|
||||
**5.1 MVP验收标准**
|
||||
|
||||
| 楠屾敹椤?| 棰勬湡缁撴灉 | 閫氳繃 |
|
||||
| 验收项 | 预期结果 | 通过 |
|
||||
|--------|---------|:----:|
|
||||
| 娴佺▼閫?| 5涓狿DF锛?鍒嗛挓鍐呭叏閮ㄥ畬鎴?| 猬?|
|
||||
| 瑙勮寖鎬у噯纭?| 鍒犳帀鎽樿<E98EBD>缁撹<E7BC81>蹇呴』鎶ラ敊 | 猬?|
|
||||
| 鏂规硶瀛﹀噯纭?| 娣锋穯缁熻<E7BC81>鏂规硶蹇呴』鎶ュ瓨鐤?| 猬?|
|
||||
| 鏃犲穿婧?| 杩炵画涓婁紶20涓<30>笉鍗℃<E98D97> | 猬?|
|
||||
| 流程通 | 5个PDF,3分钟内全部完成 | ⬜ |
|
||||
| 规范性准确 | 删掉摘要结论必须报错 | ⬜ |
|
||||
| 方法学准确 | 混淆统计方法必须报存疑 | ⬜ |
|
||||
| 无崩溃 | 连续上传20个不卡死 | ⬜ |
|
||||
|
||||
- [ ] **5.1.1** 执行验收测试
|
||||
- [ ] **5.1.2** 编写验收报告
|
||||
@@ -680,19 +749,20 @@ interface AgentSelectorProps {
|
||||
|
||||
- [ ] **5.2.1** 更新文档
|
||||
- [ ] **5.2.2** 通知相关人员
|
||||
- [ ] **5.2.3** 鐩戞帶涓婄嚎鍚庣姸鎬?
|
||||
- [ ] **5.2.3** 监控上线后状态
|
||||
|
||||
---
|
||||
|
||||
## 📅 时间估算
|
||||
|
||||
| Phase | 浠诲姟 | 棰勪及宸ユ椂 | 楠岃瘉鐐?|
|
||||
| Phase | 任务 | 预估工时 | 验证点 |
|
||||
|-------|------|---------|--------|
|
||||
| **Phase 1** | 鍚庣<EFBFBD>妯″潡杩佺Щ | 2澶?| 鉁?API娴嬭瘯閫氳繃 |
|
||||
| **Phase 2** | 鏁版嵁搴撹縼绉?| 0.5澶?| 鉁?鏁版嵁瀹屾暣鎬ч獙璇?|
|
||||
| **Phase 3** | 鍓嶇<EFBFBD>閲嶆瀯 | 3澶?| 鉁?鍔熻兘娴嬭瘯閫氳繃 |
|
||||
| **Phase 4** | 闆嗘垚娴嬭瘯 | 1澶?| 鉁?绔<>埌绔<E59F8C>祴璇曢€氳繃 |
|
||||
| **Phase 5** | 楠屾敹涓婄嚎 | 0.5澶?| 鉁?MVP楠屾敹閫氳繃 |
|
||||
| **鎬昏<EFBFBD>** | - | **7澶?* | - |
|
||||
| **Phase 1** | 后端模块迁移 | 2天 | ✓ API测试通过 |
|
||||
| **Phase 2** | 数据库迁移 | 0.5天 | ✓ 数据完整性验证 |
|
||||
| **Phase 3** | 前端重构 | 3天 | ✓ 功能测试通过 |
|
||||
| **Phase 4** | 集成测试 | 1天 | ✓ 端到端测试通过 |
|
||||
| **Phase 5** | 验收上线 | 0.5天 | ✓ MVP验收通过 |
|
||||
| **总计** | - | **7天** | - |
|
||||
|
||||
---
|
||||
|
||||
@@ -700,38 +770,41 @@ interface AgentSelectorProps {
|
||||
|
||||
| 功能 | 预留字段 | 后续计划 |
|
||||
|------|---------|---------|
|
||||
| **PICO鍗$墖** | `pico_extract` | 鏂规硶瀛﹁瘎浼版墿灞?|
|
||||
| **绯荤粺璁剧疆** | `JournalConfig`琛?| 鏈熷垔Logo/妯″瀷閰嶇疆 |
|
||||
| **PICO卡片** | `pico_extract` | 方法学评估扩展 |
|
||||
| **系统设置** | `JournalConfig`表 | 期刊Logo/模型配置 |
|
||||
| **历史归档** | `is_archived`, `archived_at` | 自动归档7天前数据 |
|
||||
| **鐧诲綍椤甸潰** | - | 鐙<EFBFBD>珛浜у搧鏃跺紑鍙?|
|
||||
| **登录页面** | - | 独立产品时开发 |
|
||||
|
||||
---
|
||||
|
||||
## ⚠️ 风险控制
|
||||
|
||||
### 1. 鏁版嵁搴撹縼绉婚<EFBFBD>闄?
|
||||
### 1. 数据库迁移风险
|
||||
|
||||
| 风险 | 概率 | 影响 | 控制措施 |
|
||||
|------|------|------|---------|
|
||||
| 鏁版嵁涓㈠け | 浣?| 楂?| 杩佺Щ鍓嶅<E98D93>浠?|
|
||||
| 杩佺Щ澶辫触 | 涓?| 涓?| 鍑嗗<E98D91>鍥炴粴SQL |
|
||||
| 鎬ц兘涓嬮檷 | 浣?| 涓?| 楠岃瘉绱㈠紩鏈夋晥鎬?|
|
||||
| 数据丢失 | 低 | 高 | 迁移前备份 |
|
||||
| 迁移失败 | 中 | 中 | 准备回滚SQL |
|
||||
| 性能下降 | 低 | 中 | 验证索引有效性 |
|
||||
|
||||
### 2. 功能回归风险
|
||||
|
||||
| 风险 | 概率 | 影响 | 控制措施 |
|
||||
|------|------|------|---------|
|
||||
| 鏃<EFBFBD>PI涓<EFBFBD>柇 | 浣?| 楂?| 淇濈暀v1璺<31>敱 |
|
||||
| 璇勪及缁撴灉寮傚父 | 浣?| 楂?| 瀵规瘮娴嬭瘯缁撴灉 |
|
||||
| 鍓嶇<EFBFBD>鐧藉睆 | 涓?| 涓?| 闃舵<E99783>鎬ф祴璇?|
|
||||
| 旧API中断 | 低 | 高 | 保留v1路由 |
|
||||
| 评估结果异常 | 低 | 高 | 对比测试结果 |
|
||||
| 前端白屏 | 中 | 中 | 阶段性测试 |
|
||||
|
||||
### 3. 回滚计划
|
||||
|
||||
```bash
|
||||
# 濡傛灉闇€瑕佸洖婊氬埌杩佺Щ鍓嶇姸鎬?
|
||||
# 如果需要回滚到迁移前状态
|
||||
|
||||
# 1. 停止服务
|
||||
pm2 stop all
|
||||
|
||||
# 2. 鍥炴粴鏁版嵁搴?pg_restore -h localhost -U postgres -d airesearch -c backup_phase2.dump
|
||||
# 2. 回滚数据库
|
||||
pg_restore -h localhost -U postgres -d airesearch -c backup_phase2.dump
|
||||
|
||||
# 3. 切换到旧代码分支
|
||||
git checkout main
|
||||
@@ -742,14 +815,15 @@ pm2 start all
|
||||
|
||||
---
|
||||
|
||||
## 馃摎 鍙傝€冩枃妗?
|
||||
- [鏅鸿兘鏈熷垔瀹$ǹ绯荤粺MVP PRD](../01-闇€姹傚垎鏋?鏅鸿兘鏈熷垔瀹$ǹ绯荤粺%20MVP%20浜у搧闇€姹傛枃妗?md)
|
||||
- [鏅鸿兘瀹$ǹV7鍘熷瀷](../01-闇€姹傚垎鏋?鏅鸿兘瀹$ǹV7.html)
|
||||
- [浜戝師鐢熷紑鍙戣<EFBFBD>鑼僝(../../04-寮€鍙戣<E98D99>鑼?08-浜戝師鐢熷紑鍙戣<E98D99>鑼?md)
|
||||
- [鐜版湁绯荤粺鎶€鏈<EFBFBD>懜搴曟姤鍛奭(../../00-椤圭洰姒傝堪/鐜版湁绯荤粺鎶€鏈<E282AC>懜搴曟姤鍛?md)
|
||||
## 📚 参考文档
|
||||
|
||||
- [智能期刊审稿系统MVP PRD](../01-需求分析/智能期刊审稿系统%20MVP%20产品需求文档.md)
|
||||
- [智能审稿V7原型](../01-需求分析/智能审稿V7.html)
|
||||
- [云原生开发规范](../../04-开发规范/08-云原生开发规范.md)
|
||||
- [现有系统技术摸底报告](../../00-项目概述/现有系统技术摸底报告.md)
|
||||
|
||||
---
|
||||
|
||||
**鏂囨。鐗堟湰锛?* v2.1
|
||||
**文档版本:** v2.1
|
||||
**最后更新:** 2026-01-07
|
||||
**下一步:** 确认后开始Phase 1
|
||||
|
||||
Reference in New Issue
Block a user