Files
AIclinicalresearch/docs/03-业务模块/RVW-稿件审查系统/04-开发计划/RVW模块迁移计划.md
HaHafeng 1b53ab9d52 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%)
2026-01-14 19:15:01 +08:00

756 lines
25 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# RVW绋夸欢瀹℃煡妯″潡杩佺Щ璁″垝锛坴2.1 - 绋冲畾杩佺Щ鐗堬級
> **鏂囨。鐗堟湰锛?* v2.1
> **鍒涘缓鏃ユ湡锛?* 2026-01-07
> **鏈€鍚庢洿鏂帮細** 2026-01-07
> **缁存姢鑰咃細** 寮€鍙戝洟闃?
> **鏂囨。鐩<E38082>殑锛?* 灏嗙ǹ浠跺<E6B5A0>鏌ュ姛鑳戒粠鏃ф灦鏋勫畨鍏ㄨ縼绉诲埌鏂版灦鏋勶紝鍚屾椂鏁村悎MVP鏍稿績闇€姹?
---
## 馃搵 椤圭洰姒傝堪
### 1. 鑳屾櫙
绋夸欢瀹℃煡鍔熻兘鏄?025-10-30锛圖ay 30锛夌嫭绔嬪紑鍙戠殑鍔熻兘妯″潡锛岀洰鍓嶄綅浜?`backend/src/legacy/` 鍜?`frontend/`<>綍涓<E7B68D>€傜幇闇€瑕侊細
1. **鏋舵瀯杩佺Щ**锛氳縼绉诲埌鏍囧噯鐨勬ā鍧楃洰褰曠粨鏋勶紙`modules/rvw`锛?2. **鍔熻兘鍗囩骇**锛氭暣鍚堛€婃櫤鑳芥湡鍒婂<E98D92>绋跨郴缁烳VP浜у搧闇€姹傛枃妗€嬬殑鏍稿績鍔熻兘
### 2. 杩佺Щ鍘熷垯
| 鍘熷垯 | 璇存槑 |
|------|------|
| **绋冲畾浼樺厛** | 姣忎釜Phase瀹屾垚鍚庡繀椤婚€氳繃娴嬭瘯楠岃瘉 |
| **瀹夊叏鍙<E58F8F>** | 鏁版嵁搴撹縼绉诲墠蹇呴』澶囦唤锛屾敮鎸佸洖婊?|
| **闃舵<E99783>楠岃瘉** | 姣忎釜Phase鏈夋槑纭<E6A791>殑楠屾敹鏍囧噯 |
| **鍚戝悗鍏煎<E98D8F>** | 淇濈暀鏃<E69A80>PI杩囨浮鏈燂紝涓嶅奖鍝嶇幇鏈夊姛鑳?|
| **娓愯繘寮?* | 鍏堟牳蹇冨悗鎵╁睍锛屽厛鍚庣<E98D9A>鍚庡墠绔?|
### 3. 鍔熻兘鑼冨洿
| 鍔熻兘 | 鏈<><E98F88>寮€鍙?| 鏁版嵁搴撴敮鎾?| 璇存槑 |
|------|:--------:|:----------:|------|
| **鏍稿績AI璇勪及** | 鉁?| 鉁?| 绋跨害瑙勮寖鎬?鏂规硶瀛?|
| **鎵归噺涓婁紶** | 鉁?| 鉁?| 澶氭枃浠朵笂浼?|
| **瀹$ǹ宸ヤ綔鍙?* | 鉁?| 鉁?| 瀹借〃甯冨眬+绛涢€?|
| **鏅鸿兘浣撻€夋嫨** | 鉁?| 鉁?| 鍙<>€?涓<>垨2涓?|
| **鎵归噺鎿嶄綔** | 鉁?| 鉁?| 鎵归噺杩愯<E69DA9>瀹℃煡 |
| **鐘舵€佺瓫閫?* | 鉁?| 鉁?| 鍏ㄩ儴/寰呭<E5AFB0>鐞?宸插畬鎴?|
| PDF鎶ュ憡瀵煎嚭 | 鉁?| 鉁?| 浼樺寲鐜版湁鍔熻兘 |
| PICO鍗墖 | 鈴革笍 | 鉁?| **鏆備笉寮€鍙戯紝鏁版嵁搴撻<E690B4>鐣?* |
| 绯荤粺璁剧疆 | 鈴革笍 | 鉁?| **鏆備笉寮€鍙戯紝鏁版嵁搴撻<E690B4>鐣?* |
| 鍘嗗彶褰掓。 | 鈴革笍 | 鉁?| **鏆備笉寮€鍙戯紝鏁版嵁搴撻<E690B4>鐣?* |
| 鐧诲綍椤甸潰 | 鈴革笍 | - | 鏆備笉寮€鍙?|
### 4. 鏅鸿兘浣撻€夋嫨璇存槑
鐢ㄦ埛鍙<EFBFBD>互鐏垫椿閫夋嫨杩愯<EFBFBD>鐨勬櫤鑳戒綋锛?
```
閫夐」 A: 鍙<>€夋嫨銆岀ǹ绾﹁<E7BBBE>鑼冩€ф櫤鑳戒綋銆? 鈫?鍙<>繍琛岃<E7909B>鑼冩€ц瘎浼?閫夐」 B: 鍙<>€夋嫨銆屾柟娉曞<E5A889>缁熻<E7BC81>鏅鸿兘浣撱€? 鈫?鍙<>繍琛屾柟娉曞<E5A889>璇勪及
閫夐」 C: 鍚屾椂閫夋嫨涓や釜鏅鸿兘浣? 鈫?鍚屾椂杩愯<E69DA9>涓ら」璇勪及锛堥粯璁わ級
```
---
## 馃搳 鏁版嵁搴撹<E690B4>璁★紙瀹屾暣鐗堬紝鏀<E7B49D>拺鏈<E68BBA>潵鎵╁睍锛?
### 1. 鏈熷垔閰嶇疆琛<E79686>紙棰勭暀锛屾殏涓嶄娇鐢<E5A887>
```prisma
// review_schema
model JournalConfig {
id String @id @default(uuid())
name String // 鏈熷垔鍚嶇О
logoUrl String? @map("logo_url") // Logo URL锛堥<E9949B>鐣欙級
defaultModel String @default("deepseek-v3") @map("default_model")
settings Json? // 鍏朵粬閰嶇疆锛堥<E9949B>鐣欙級
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
reviewTasks ReviewTask[]
@@map("journal_configs")
@@schema("review_schema")
}
```
### 2. 瀹ǹ浠诲姟琛<E5A79F>紙鎵╁睍鐗堬級
```prisma
model ReviewTask {
id String @id @default(uuid())
userId String @map("user_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")
// 璇勪及缁撴灉
editorialReview Json? @map("editorial_review")
methodologyReview Json? @map("methodology_review")
overallScore Float? @map("overall_score")
// 缁撴灉鎽樿<E98EBD>锛堢敤浜庡垪琛ㄥ睍绀猴級
editorialScore Float? @map("editorial_score")
methodologyStatus String? @map("methodology_status") // pass/warn/fail
// 棰勭暀锛歅ICO鎻愬彇锛堟殏涓嶄娇鐢<E5A887>
picoExtract Json? @map("pico_extract")
// 鍏冩暟鎹? 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")
archivedAt DateTime? @map("archived_at")
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
// 鍏宠仈
user users @relation(fields: [userId], references: [id], onDelete: Cascade)
journal JournalConfig? @relation(fields: [journalId], references: [id])
@@index([userId])
@@index([journalId])
@@index([status])
@@index([createdAt])
@@index([isArchived])
@@map("review_tasks")
@@schema("review_schema")
}
```
### 3. 瀛楁<E7809B>璇存槑
| 瀛楁<E7809B> | 鏈<><E98F88>浣跨敤 | 棰勭暀鐢ㄩ€?|
|------|:--------:|---------|
| `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
# 2. 璁板綍褰撳墠鏁版嵁閲?SELECT COUNT(*) FROM public.review_tasks;
# 3. 瀵煎嚭鍏抽敭鏁版嵁锛堝彲閫夛級
COPY public.review_tasks TO '/tmp/review_tasks_backup.csv' WITH CSV HEADER;
```
### 2. 鍥炴粴鏂规<E98F82>
```bash
# 濡傛灉杩佺Щ澶辫触锛屽洖婊氭暟鎹<E69A9F>
pg_restore -h localhost -U postgres -d airesearch -c backup_before_rvw_migration.dump
# 濡傛灉鍙<E78189>渶瑕佸洖婊歋chema杩佺Щ
ALTER TABLE review_schema.review_tasks SET SCHEMA public;
DROP SCHEMA review_schema;
```
### 3. 闃舵<E99783>鎬ч獙璇?
姣忎釜Phase瀹屾垚鍚庡繀椤婚€氳繃浠ヤ笅楠岃瘉锛?
| Phase | 楠岃瘉鍐呭<E98D90> | 楠屾敹鏍囧噯 |
|-------|---------|---------|
| Phase 1 | 鍚庣<E98D9A>API娴嬭瘯 | 鎵€鏈堿PI杩斿洖姝锛屾棩蹇楁棤ERROR |
| Phase 2 | 鏁版嵁搴撹縼绉?| 鏁版嵁瀹屾暣锛屾煡璇㈡<E79287>甯革紝绱㈠紩鏈夋晥 |
| Phase 3 | 鍓嶇<E98D93>鍔熻兘娴嬭瘯 | 鏍稿績娴佺▼閫氶『锛屾棤鐧藉睆/鎶ラ敊 |
| Phase 4 | 闆嗘垚娴嬭瘯 | 绔<>埌绔<E59F8C>祦绋嬫<E7BB8B>甯?|
| Phase 5 | 楠屾敹娴嬭瘯 | 绗﹀悎MVP楠屾敹鏍囧噯 |
---
## 馃搵 寮€鍙戜换鍔℃竻鍗?
### Phase 1锛氬悗绔<E68297>ā鍧楄縼绉伙紙2澶╋級
#### Day 1 涓婂崍锛氬垱寤烘ā鍧楃粨鏋?+ 澶嶇敤鏍稿績浠g爜
**1.1 鍒涘缓鐩<E7BC93>綍缁撴瀯**
```
backend/src/modules/rvw/
鈹溾攢鈹€ routes/
鈹? 鈹斺攢鈹€ index.ts # 璺<>敱瀹氫箟
鈹溾攢鈹€ controllers/
鈹? 鈹斺攢鈹€ reviewController.ts # 鎺у埗鍣?鈹溾攢鈹€ services/
鈹? 鈹溾攢鈹€ reviewService.ts # 涓绘湇鍔★紙澶嶇敤+鎵╁睍锛?鈹? 鈹溾攢鈹€ editorialService.ts # 绋跨害璇勪及锛堝<E9949B><EFBFBD>
鈹? 鈹斺攢鈹€ methodologyService.ts # 鏂规硶瀛﹁瘎浼帮紙澶嶇敤锛?鈹溾攢鈹€ types/
鈹? 鈹斺攢鈹€ index.ts # 绫诲瀷瀹氫箟
鈹溾攢鈹€ prompts/
鈹? 鈹溾攢鈹€ editorial_system.txt # 绋跨害Prompt
鈹? 鈹斺攢鈹€ methodology_system.txt # 鏂规硶瀛<E7A1B6>rompt
鈹斺攢鈹€ index.ts # 妯″潡鍏ュ彛
```
- [ ] **1.1.1** 鍒涘缓鐩<E7BC93>綍缁撴瀯
- [ ] **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** 鏇挎崲 `console.log` 鈫?`logger`
- [ ] **1.2.2** 绉婚櫎 Mock鐢ㄦ埛ID锛岄泦鎴怞WT璁よ瘉
- [ ] **1.2.3** 浣跨敤 `process.env` 閰嶇疆
#### Day 1 涓嬪崍锛氭櫤鑳戒綋閫夋嫨閫昏緫
**1.3 鏅鸿兘浣撻€夋嫨瀹炵幇**
```typescript
// types/index.ts
export type AgentType = 'editorial' | 'methodology';
export interface RunReviewParams {
taskId: string;
agents: AgentType[]; // 鍙<>€?涓<>垨2涓?}
// services/reviewService.ts
async function runReview(params: RunReviewParams) {
const { taskId, agents } = params;
// 楠岃瘉锛氳嚦灏戦€夋嫨1涓<31>櫤鑳戒綋
if (agents.length === 0) {
throw new Error('璇疯嚦灏戦€夋嫨涓€涓<E282AC>櫤鑳戒綋');
}
// 鏇存柊浠诲姟鐘舵€? await prisma.reviewTask.update({
where: { id: taskId },
data: {
status: 'reviewing',
selectedAgents: agents,
startedAt: new Date()
}
});
// 鍙<>繍琛岄€変腑鐨勬櫤鑳戒綋
let editorialResult = null;
let methodologyResult = null;
if (agents.includes('editorial')) {
editorialResult = await editorialService.review(taskId);
}
if (agents.includes('methodology')) {
methodologyResult = await methodologyService.review(taskId);
}
// 璁$畻缁煎悎鍒嗘暟
const overallScore = calculateOverallScore(editorialResult, methodologyResult, agents);
// 鏇存柊缁撴灉
await prisma.reviewTask.update({
where: { id: taskId },
data: {
status: 'completed',
editorialReview: editorialResult,
methodologyReview: methodologyResult,
editorialScore: editorialResult?.overall_score,
methodologyStatus: getMethodologyStatus(methodologyResult),
overallScore,
completedAt: new Date(),
durationSeconds: calculateDuration(taskId)
}
});
}
// 鏍规嵁閫夋嫨鐨勬櫤鑳戒綋璁$畻缁煎悎鍒嗘暟
function calculateOverallScore(editorial: any, methodology: any, agents: AgentType[]) {
if (agents.length === 2 && editorial && methodology) {
// 涓や釜閮介€夛細40% + 60%
return editorial.overall_score * 0.4 + methodology.overall_score * 0.6;
} else if (agents.includes('editorial') && editorial) {
// 鍙<>€夎<E282AC>鑼冩€? return editorial.overall_score;
} else if (agents.includes('methodology') && methodology) {
// 鍙<>€夋柟娉曞<E5A889>
return methodology.overall_score;
}
return null;
}
```
- [ ] **1.3.1** 瀹炵幇鏅鸿兘浣撻€夋嫨绫诲瀷瀹氫箟
- [ ] **1.3.2** 瀹炵幇 `runReview()` 鍑芥暟
- [ ] **1.3.3** 瀹炵幇缁煎悎鍒嗘暟璁$畻閫昏緫
- [ ] **1.3.4** 瀹炵幇鏂规硶瀛︾姸鎬佸垽鏂<E59EBD>紙pass/warn/fail锛?
#### Day 2 涓婂崍锛氭壒閲忔搷浣?+ API鎵╁睍
**1.4 鎵归噺杩愯<E69DA9>瀹炵幇**
```typescript
// services/reviewService.ts
async function batchRunReview(params: BatchRunParams) {
const { taskIds, agents } = params;
// 闄愬埗骞跺彂鏁? const MAX_CONCURRENT = 5;
const results = [];
for (let i = 0; i < taskIds.length; i += MAX_CONCURRENT) {
const batch = taskIds.slice(i, i + MAX_CONCURRENT);
const batchResults = await Promise.allSettled(
batch.map(taskId => runReview({ taskId, agents }))
);
results.push(...batchResults);
}
return results;
}
```
- [ ] **1.4.1** 瀹炵幇鎵归噺杩愯<E69DA9>鎺ュ彛
- [ ] **1.4.2** 瀹炵幇骞跺彂鎺у埗锛堟渶澶?涓<>
- [ ] **1.4.3** 瀹炵幇閿欒<E996BF>澶勭悊锛堝崟涓<E5B49F>け璐ヤ笉褰卞搷鍏朵粬锛?
**1.5 API璺<49>敱瀹氫箟**
```typescript
// routes/index.ts
export default async function rvwRoutes(fastify: FastifyInstance) {
// 浠诲姟绠$悊
fastify.post('/tasks', reviewController.createTask); // 鍒涘缓/涓婁紶
fastify.get('/tasks', reviewController.getTaskList); // 鍒楄〃锛堢瓫閫夛級
fastify.get('/tasks/:taskId', reviewController.getTaskDetail); // 璇︽儏
fastify.get('/tasks/:taskId/report', reviewController.getTaskReport); // 鎶ュ憡
fastify.delete('/tasks/:taskId', reviewController.deleteTask); // 鍒犻櫎
// 杩愯<E69DA9>瀹℃煡锛堟牳蹇冨姛鑳斤級
fastify.post('/tasks/:taskId/run', reviewController.runReview); // 鍗曚釜杩愯<E69DA9>
fastify.post('/tasks/batch/run', reviewController.batchRunReview); // 鎵归噺杩愯<E69DA9>
}
```
- [ ] **1.5.1** 瀹炵幇璺<E5B987>敱瀹氫箟
- [ ] **1.5.2** 瀹炵幇鎺у埗鍣ㄦ柟娉?- [ ] **1.5.3** 娣诲姞璇锋眰楠岃瘉
#### Day 2 涓嬪崍锛氭敞鍐岃矾鐢?+ Phase 1 楠岃瘉
**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');
// 淇濈暀鏃ц矾鐢憋紙鍏煎<E98D8F>锛?await fastify.register(reviewRoutes, { prefix: '/api/v1' });
logger.info('鉁?Legacy瀹ǹ璺<C7B9>敱淇濈暀: /api/v1/review');
```
- [ ] **1.6.1** 娉ㄥ唽鏂拌矾鐢?- [ ] **1.6.2** 淇濈暀鏃ц矾鐢卞吋瀹?
**1.7 Phase 1 楠岃瘉娴嬭瘯**
```http
### 1.
POST {{baseUrl}}/api/v1/rvw/tasks
Content-Type: multipart/form-data
# file: test.docx
### 2. <EFBFBD><EFBFBD>э
POST {{baseUrl}}/api/v1/rvw/tasks/{{taskId}}/run
Content-Type: application/json
{ "agents": ["editorial"] }
### 3. <EFBFBD><EFBFBD>?POST {{baseUrl}}/api/v1/rvw/tasks/{{taskId}}/run
Content-Type: application/json
{ "agents": ["methodology"] }
### 4. <EFBFBD><EFBFBD>
POST {{baseUrl}}/api/v1/rvw/tasks/{{taskId}}/run
Content-Type: application/json
{ "agents": ["editorial", "methodology"] }
### 5. <EFBFBD>
POST {{baseUrl}}/api/v1/rvw/tasks/batch/run
Content-Type: application/json
{
"taskIds": ["id1", "id2", "id3"],
"agents": ["editorial", "methodology"]
}
### 6.
GET {{baseUrl}}/api/v1/rvw/tasks?status=pending&limit=10
### 7.
GET {{baseUrl}}/api/v1/rvw/tasks/{{taskId}}/report
```
**Phase 1 楠屾敹鏍囧噯锛?*
| 娴嬭瘯椤?| 棰勬湡缁撴灉 | 閫氳繃 |
|--------|---------|:----:|
| 鍒涘缓浠诲姟 | 杩斿洖taskId锛岀姸鎬乸ending | 猬?|
| 鍙<>€夎<E282AC>鑼冩€?| 鍙<>湁editorialReview鏈夊€?| 猬?|
| 鍙<>€夋柟娉曞<E5A889> | 鍙<>湁methodologyReview鏈夊€?| 猬?|
| 涓や釜閮介€?| 涓や釜Review閮芥湁鍊?| 猬?|
| 鎵归噺杩愯<E69DA9> | 澶氫釜浠诲姟閮藉畬鎴?| 猬?|
| 鏃<>PI鍏煎<E98D8F> | `/api/v1/review/*` 姝e父 | 猬?|
- [ ] **1.7.1** 缂栧啓娴嬭瘯鐢ㄤ緥
- [ ] **1.7.2** 鎵ц<E98EB5>娴嬭瘯
- [ ] **1.7.3**<><E6B787><EFBFBD><E99782>
- [ ] **1.7.4**<><E7BAAD>Phase 1閫氳繃
---
### Phase 2锛氭暟鎹<E69A9F>簱Schema杩佺Щ锛?.5澶╋級
#### 杩佺Щ鍓嶏細澶囦唤
- [ ] **2.1** 澶囦唤鏁版嵁搴? ```bash
pg_dump -h localhost -U postgres -d airesearch -F c -f backup_phase2.dump
```
- [ ] **2.2** 璁板綍褰撳墠鏁版嵁
```sql
SELECT COUNT(*) FROM public.review_tasks;
```
#### 杩佺Щ鎵ц<E98EB5>
- [ ] **2.3** 鍒涘缓杩佺ЩSQL
```sql
-- 1. 鍒涘缓鏂癝chema
CREATE SCHEMA IF NOT EXISTS review_schema;
-- 2. 鍒涘缓鏈熷垔閰嶇疆琛<E79686>紙棰勭暀锛? CREATE TABLE review_schema.journal_configs (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
name VARCHAR(255) NOT NULL,
logo_url TEXT,
default_model VARCHAR(50) DEFAULT 'deepseek-v3',
settings JSONB,
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW()
);
-- 3. 杩佺Щreview_tasks琛ㄥ埌鏂癝chema
ALTER TABLE public.review_tasks SET SCHEMA review_schema;
-- 4. 娣诲姞鏂板瓧娈碉紙鏀<E7B499>寔鏈<E5AF94>潵鎵╁睍锛? 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'],
ADD COLUMN IF NOT EXISTS editorial_score FLOAT,
ADD COLUMN IF NOT EXISTS methodology_status VARCHAR(20),
ADD COLUMN IF NOT EXISTS pico_extract JSONB,
ADD COLUMN IF NOT EXISTS is_archived BOOLEAN DEFAULT FALSE,
ADD COLUMN IF NOT EXISTS archived_at TIMESTAMPTZ;
-- 5. 鍒涘缓绱㈠紩
CREATE INDEX IF NOT EXISTS idx_review_tasks_journal ON review_schema.review_tasks(journal_id);
CREATE INDEX IF NOT EXISTS idx_review_tasks_archived ON review_schema.review_tasks(is_archived);
-- 6. 鍒涘缓榛樿<E6A69B>鏈熷垔閰嶇疆
INSERT INTO review_schema.journal_configs (name, default_model)
VALUES ('榛樿<E6A69B>鏈熷垔', 'deepseek-v3');
```
- [ ] **2.4** 鏇存柊Prisma Schema
- 淇<>敼 `@@schema("review_schema")`
- 娣诲姞鏂板瓧娈?
- [ ] **2.5** 鎵ц<E98EB5>杩佺Щ
```bash
npx prisma migrate dev --name rvw_schema_migration
```
#### Phase 2 楠岃瘉
- [ ] **2.6** 楠岃瘉鏁版嵁瀹屾暣鎬? ```sql
-- 纭<><E7BAAD>鏁版嵁閲忎竴鑷? SELECT COUNT(*) FROM review_schema.review_tasks;
-- 纭<><E7BAAD>瀛楁<E7809B><EFBFBD>
SELECT id, selected_agents, editorial_score FROM review_schema.review_tasks LIMIT 5;
-- 纭<><E7BAAD>澶栭敭鍏崇郴
SELECT rt.id, rt.user_id, u.email
FROM review_schema.review_tasks rt
JOIN public.users u ON rt.user_id = u.id
LIMIT 5;
```
**Phase 2 楠屾敹鏍囧噯锛?*
| 娴嬭瘯椤?| 棰勬湡缁撴灉 | 閫氳繃 |
|--------|---------|:----:|
| 鏁版嵁杩佺Щ | 鏁版嵁閲忎竴鑷?| 猬?|
| 鏂板瓧娈?| 瀛楁<E7809B>瀛樺湪涓斿彲鐢?| 猬?|
| 澶栭敭鍏崇郴 | 鍏宠仈姝e父 | 猬?|
| 绱㈠紩鏈夋晥 | 鏌ヨ<E98F8C>鎬ц兘姝父 | 猬?|
| API姝父 | 鍚庣<E98D9A>API浠嶅彲鐢?| 猬?|
- [ ] **2.7** 纭<><E7BAAD>Phase 2閫氳繃
---
### Phase 3锛氬墠绔<E5A2A0>噸鏋勶紙3澶╋級
#### Day 3锛氭ā鍧楃粨鏋?+ API灞?
**3.1 鍒涘缓妯″潡缁撴瀯**
```
frontend-v2/src/modules/rvw/
鈹溾攢鈹€ api/
鈹? 鈹斺攢鈹€ reviewApi.ts # API灏佽<E7818F>
鈹溾攢鈹€ components/
鈹? 鈹溾攢鈹€ ScoreCard.tsx # 澶嶇敤
鈹? 鈹溾攢鈹€ EditorialReview.tsx # 澶嶇敤
鈹? 鈹溾攢鈹€ MethodologyReview.tsx # 澶嶇敤
鈹? 鈹溾攢鈹€ AgentSelector.tsx # 馃啎 鏅鸿兘浣撻€夋嫨寮圭獥
鈹? 鈹溾攢鈹€ BatchToolbar.tsx # 馃啎 鎵归噺鎿嶄綔鏍?鈹? 鈹溾攢鈹€ TaskTable.tsx # 馃啎 浠诲姟鍒楄〃琛ㄦ牸
鈹? 鈹斺攢鈹€ StatusFilter.tsx # 馃啎 鐘舵€佺瓫閫?鈹溾攢鈹€ pages/
鈹? 鈹溾攢鈹€ ReviewDashboard.tsx # 馃啎 瀹$ǹ宸ヤ綔鍙?鈹? 鈹斺攢鈹€ ReviewDetail.tsx # 鎶ュ憡璇︽儏锛堜紭鍖栵級
鈹溾攢鈹€ hooks/
鈹? 鈹溾攢鈹€ useReviewTask.ts
鈹? 鈹斺攢鈹€ useBatchOperation.ts
鈹溾攢鈹€ stores/
鈹? 鈹斺攢鈹€ useReviewStore.ts
鈹溾攢鈹€ types/
鈹? 鈹斺攢鈹€ index.ts
鈹斺攢鈹€ index.tsx
```
- [ ] **3.1.1** 鍒涘缓鐩<E7BC93>綍缁撴瀯
- [ ] **3.1.2** 澶嶇敤鐜版湁缁勪欢锛圫coreCard銆丒ditorialReview銆丮ethodologyReview锛?
**3.2 API灏佽<E7818F>**
```typescript
// api/reviewApi.ts
export type AgentType = 'editorial' | 'methodology';
// 杩愯<E69DA9>瀹℃煡锛堟敮鎸侀€夋嫨鏅鸿兘浣擄級
export async function runReview(taskId: string, agents: AgentType[]): Promise<void> {
return axios.post(`/api/v1/rvw/tasks/${taskId}/run`, { agents });
}
// 鎵归噺杩愯<E69DA9>
export async function batchRunReview(taskIds: string[], agents: AgentType[]): Promise<void> {
return axios.post('/api/v1/rvw/tasks/batch/run', { taskIds, agents });
}
// 鑾峰彇浠诲姟鍒楄〃锛堝甫绛涢€夛級
export interface TaskListParams {
status?: 'all' | 'pending' | 'completed';
limit?: number;
offset?: number;
}
export async function getTaskList(params: TaskListParams): Promise<TaskListResponse> {
return axios.get('/api/v1/rvw/tasks', { params });
}
```
- [ ] **3.2.1** 瀹炵幇API灏佽<E7818F>
- [ ] **3.2.2** 瀹炵幇绫诲瀷瀹氫箟
#### Day 4锛氭牳蹇冮〉闈㈠紑鍙?
**3.3 鏅鸿兘浣撻€夋嫨寮圭獥**
```tsx
// components/AgentSelector.tsx
interface AgentSelectorProps {
visible: boolean;
taskIds: string[]; // 鏀<>寔鍗曚釜鎴栧<E98EB4>涓? onConfirm: (agents: AgentType[]) => void;
onCancel: () => void;
}
// 寮圭獥鍐呭<E98D90>锛?// 鉁?绋跨害瑙勮寖鎬ф櫤鑳戒綋锛堥粯璁ら€変腑锛?// 鏍煎紡銆佸弬鑰冩枃鐚<E69E83>€佸浘鐗囨<E99097>鏌?// 鈽?鏂规硶瀛︾粺璁℃櫤鑳戒綋
// DeepSeek 娣卞害閫昏緫鎺ㄧ悊
//
// 鎻愮ず锛氬彲閫夋嫨1涓<31>垨鍚屾椂閫夋嫨2涓<32>櫤鑳戒綋
//
// [鍙栨秷] [绔嬪嵆杩愯<E69DA9>]
```
- [ ] **3.3.1** 瀹炵幇鏅鸿兘浣撻€夋嫨寮圭獥
- [ ] **3.3.2** 鏀<>寔鍗曢€夊拰澶氶€?- [ ] **3.3.3** 榛樿<E6A69B>閫変腑瑙勮寖鎬ф櫤鑳戒綋
**3.4 瀹$ǹ宸ヤ綔鍙?*
```
鈹屸攢鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹?鈹? Header: [Logo] 鏅鸿兘瀹$ǹ绯荤粺 [涓婁紶鏂扮ǹ浠禲 鈹?鈹溾攢鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹?鈹? Filter: [鍏ㄩ儴|寰呭<E5AFB0>鐞唡宸插畬鎴怾 鈹?鈹溾攢鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹?鈹? 鈹屸攢鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹? 鈹?鈹? 鈹? 鈽? 鏂囦欢鍚嶇О/淇℃伅 涓婁紶鏃堕棿 瀹$ǹ缁村害 缁撴灉鎽樿<E98EBD> 鎿嶄綔 鈹? 鈹?鈹? 鈹? 鈽? 鏇块浄鍒╃彔鍗曟姉...pdf 10:30 [瑙勮寖][鏂规硶] 92鍒? [鏌ョ湅] 鈹?鈹? 鈹? 鈽? 楂樿<E6A582>鍘嬭嵂鐗?..docx 鍒氬垰 [鏈<>繍琛宂 绛夊緟... [寮€濮媇 鈹?鈹? 鈹斺攢鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹? 鈹?鈹溾攢鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹?鈹? [Batch Toolbar: 3涓<33>枃浠跺凡閫変腑 | 杩愯<E69DA9>鏅鸿兘瀹ǹ | 鉁昡 鈹?鈹斺攢鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹?```
- [ ] **3.4.1** 瀹炵幇椤甸潰甯冨眬
- [ ] **3.4.2** 瀹炵幇浠诲姟鍒楄〃琛ㄦ牸
- [ ] **3.4.3** 瀹炵幇鐘舵€佺瓫閫?- [ ] **3.4.4** 瀹炵幇鎵归噺鎿嶄綔鏍?
#### Day 5锛氭姤鍛婅<E98D9B>鎯?+ Phase 3 楠岃瘉
**3.5 鎶ュ憡璇︽儏椤?*
- [ ] **3.5.1** 瀹炵幇Tab鍒囨崲锛堣<E9949B>鑼冩€?鏂规硶瀛︼級
- [ ] **3.5.2** 澶嶇敤璇勪及璇︽儏缁勪欢
- [ ] **3.5.3** 鏍规嵁閫夋嫨鐨勬櫤鑳戒綋鏄剧ず瀵瑰簲Tab
- [ ] **3.5.4** 瀹炵幇瀵煎嚭鎶ュ憡鎸夐挳
**3.6 璺<>敱閰嶇疆**
```typescript
// router/index.tsx
{
path: '/rvw',
children: [
{ path: '', element: <ReviewDashboard /> },
{ path: ':taskId', element: <ReviewDetail /> }
]
}
```
- [ ] **3.6.1** 閰嶇疆璺<E79686>
- [ ] **3.6.2** 娣诲姞瀵艰埅鑿滃崟
**Phase 3 楠岃瘉娴嬭瘯**
| 娴嬭瘯椤?| 棰勬湡缁撴灉 | 閫氳繃 |
|--------|---------|:----:|
| 椤甸潰鍔犺浇 | 宸ヤ綔鍙版<E98D99>甯告樉绀?| 猬?|
| 鏂囦欢涓婁紶 | 鏀<>寔澶氭枃浠?| 猬?|
| 鏅鸿兘浣撻€夋嫨 | 鍙<>€?涓<>垨2涓?| 猬?|
| 鎵归噺鎿嶄綔 | 鎵归噺杩愯<E69DA9>鎴愬姛 | 猬?|
| 鐘舵€佺瓫閫?| 绛涢€夌粨鏋滄<E98F8B>纭?| 猬?|
| 鎶ュ憡鏌ョ湅 | 鏄剧ず瀵瑰簲璇勪及缁撴灉 | 猬?|
- [ ] **3.7** 纭<><E7BAAD>Phase 3閫氳繃
---
### Phase 4锛氶泦鎴愭祴璇曪紙1澶╋級
**4.1 绔<>埌绔<E59F8C>祴璇?*
| 娴嬭瘯鍦烘櫙 | 姝ラ<E5A79D> | 棰勬湡缁撴灉 |
|---------|------|---------|
| 鍗曟枃浠?鍗曟櫤鑳戒綋 | 涓婁紶鈫掗€夎<E282AC>鑼冩€р啋鏌ョ湅 | 鍙<>樉绀鸿<E7BB80>鑼冩€ф姤鍛?|
| 鍗曟枃浠?鍙屾櫤鑳戒綋 | 涓婁紶鈫掗€変袱涓<E8A2B1>啋鏌ョ湅 | 鏄剧ず涓や釜鎶ュ憡Tab |
| 鎵归噺+鍙屾櫤鑳戒綋 | 涓婁紶3涓<33>啋鎵归噺杩愯<E69DA9> | 3涓<33>兘瀹屾垚 |
| 鐘舵€佺瓫閫?| 涓婁紶鈫掔瓫閫夊緟澶勭悊 | 姝g‘杩囨护 |
- [ ] **4.1.1** 鎵ц<E98EB5><EFBFBD>埌绔<E59F8C>祴璇?- [ ] **4.1.2** 淇<><E6B787>鍙戠幇鐨勯棶棰?
**4.2 鎬ц兘娴嬭瘯**
| 鎸囨爣 | 鐩<>爣 | 瀹為檯 |
|------|------|------|
| 鍒楄〃鍔犺浇 | < 1绉?| 猬?|
| 鍗曟枃浠跺<E6B5A0>鏌?| < 2鍒嗛挓 | 猬?|
| 5鏂囦欢骞跺彂 | < 5鍒嗛挓 | 猬?|
- [ ] **4.2.1** 鎵ц<E98EB5>鎬ц兘娴嬭瘯
**4.3 鍏煎<E98D8F>鎬ф祴璇?*
- [ ] **4.3.1** Chrome娴忚<E5A8B4>鍣ㄦ祴璇?- [ ] **4.3.2** Edge娴忚<E5A8B4>鍣ㄦ祴璇?- [ ] **4.3.3** 鏃<>PI鍏煎<E98D8F>х璁?
---
### Phase 5锛氶獙鏀朵笌涓婄嚎锛?.5澶╋級
**5.1 MVP楠屾敹鏍囧噯**
| 楠屾敹椤?| 棰勬湡缁撴灉 | 閫氳繃 |
|--------|---------|:----:|
| 娴佺▼閫?| 5涓狿DF锛?鍒嗛挓鍐呭叏閮ㄥ畬鎴?| 猬?|
| 瑙勮寖鎬у噯纭?| 鍒犳帀鎽樿<E98EBD>缁撹<E7BC81>蹇呴』鎶ラ敊 | 猬?|
| 鏂规硶瀛﹀噯纭?| 娣锋穯缁熻<E7BC81>鏂规硶蹇呴』鎶ュ瓨鐤?| 猬?|
| 鏃犲穿婧?| 杩炵画涓婁紶20涓<30>笉鍗℃<E98D97> | 猬?|
- [ ] **5.1.1** 鎵ц<E98EB5>楠屾敹娴嬭瘯
- [ ] **5.1.2** 缂栧啓楠屾敹鎶ュ憡
**5.2 涓婄嚎鍑嗗<E98D91>**
- [ ] **5.2.1** 鏇存柊鏂囨。
- [ ] **5.2.2** 閫氱煡鐩稿叧浜哄憳
- [ ] **5.2.3** 鐩戞帶涓婄嚎鍚庣姸鎬?
---
## 馃搮 鏃堕棿浼扮畻
| Phase | 浠诲姟 | 棰勪及宸ユ椂 | 楠岃瘉鐐?|
|-------|------|---------|--------|
| **Phase 1** | 鍚庣<E98D9A>妯″潡杩佺Щ | 2澶?| 鉁?API娴嬭瘯閫氳繃 |
| **Phase 2** | 鏁版嵁搴撹縼绉?| 0.5澶?| 鉁?鏁版嵁瀹屾暣鎬ч獙璇?|
| **Phase 3** | 鍓嶇<E98D93>閲嶆瀯 | 3澶?| 鉁?鍔熻兘娴嬭瘯閫氳繃 |
| **Phase 4** | 闆嗘垚娴嬭瘯 | 1澶?| 鉁?绔<>埌绔<E59F8C>祴璇曢€氳繃 |
| **Phase 5** | 楠屾敹涓婄嚎 | 0.5澶?| 鉁?MVP楠屾敹閫氳繃 |
| **鎬昏<E98EAC>** | - | **7澶?* | - |
---
## 鈴革笍 鏆備笉寮€鍙戠殑鍔熻兘锛堟暟鎹<E69A9F>簱宸查<E5AEB8>鐣欙級
| 鍔熻兘 | 棰勭暀瀛楁<E7809B> | 鍚庣画璁″垝 |
|------|---------|---------|
| **PICO鍗墖** | `pico_extract` | 鏂规硶瀛﹁瘎浼版墿灞?|
| **绯荤粺璁剧疆** | `JournalConfig`琛?| 鏈熷垔Logo/妯″瀷閰嶇疆 |
| **鍘嗗彶褰掓。** | `is_archived`, `archived_at` | 鑷<>姩褰掓。7澶╁墠鏁版嵁 |
| **鐧诲綍椤甸潰** | - | 鐙<>珛浜у搧鏃跺紑鍙?|
---
## 鈿狅笍 椋庨櫓鎺у埗
### 1. 鏁版嵁搴撹縼绉婚<E7BB89>闄?
| 椋庨櫓 | 姒傜巼 | 褰卞搷 | 鎺у埗鎺<E59F97>柦 |
|------|------|------|---------|
| 鏁版嵁涓㈠け | 浣?| 楂?| 杩佺Щ鍓嶅<E98D93>浠?|
| 杩佺Щ澶辫触 | 涓?| 涓?| 鍑嗗<E98D91>鍥炴粴SQL |
| 鎬ц兘涓嬮檷 | 浣?| 涓?| 楠岃瘉绱㈠紩鏈夋晥鎬?|
### 2. 鍔熻兘鍥炲綊椋庨櫓
| 椋庨櫓 | 姒傜巼 | 褰卞搷 | 鎺у埗鎺<E59F97>柦 |
|------|------|------|---------|
| 鏃<>PI涓<49>柇 | 浣?| 楂?| 淇濈暀v1璺<31>敱 |
| 璇勪及缁撴灉寮傚父 | 浣?| 楂?| 瀵规瘮娴嬭瘯缁撴灉 |
| 鍓嶇<E98D93>鐧藉睆 | 涓?| 涓?| 闃舵<E99783>鎬ф祴璇?|
### 3. 鍥炴粴璁″垝
```bash
# 濡傛灉闇€瑕佸洖婊氬埌杩佺Щ鍓嶇姸鎬?
# 1. 鍋滄<E98D8B>鏈嶅姟
pm2 stop all
# 2. 鍥炴粴鏁版嵁搴?pg_restore -h localhost -U postgres -d airesearch -c backup_phase2.dump
# 3. 鍒囨崲鍒版棫浠g爜鍒嗘敮
git checkout main
# 4. 閲嶅惎鏈嶅姟
pm2 start all
```
---
## 馃摎 鍙傝€冩枃妗?
- [鏅鸿兘鏈熷垔瀹ǹ绯荤粺MVP PRD](../01-闇€姹傚垎鏋?鏅鸿兘鏈熷垔瀹$ǹ绯荤粺%20MVP%20浜у搧闇€姹傛枃妗?md)
- [鏅鸿兘瀹ǹV7鍘熷瀷](../01-闇€姹傚垎鏋?鏅鸿兘瀹ǹV7.html)
- [浜戝師鐢熷紑鍙戣<E98D99>鑼僝(../../04-寮€鍙戣<E98D99>鑼?08-浜戝師鐢熷紑鍙戣<E98D99>鑼?md)
- [鐜版湁绯荤粺鎶€鏈<E282AC>懜搴曟姤鍛奭(../../00-椤圭洰姒傝堪/鐜版湁绯荤粺鎶€鏈<E282AC>懜搴曟姤鍛?md)
---
**鏂囨。鐗堟湰锛?* v2.1
**鏈€鍚庢洿鏂帮細** 2026-01-07
**涓嬩竴姝ワ細**<><E7BAAD>鍚庡紑濮婸hase 1