refactor(asl): ASL frontend architecture refactoring with left navigation

- feat: Create ASLLayout component with 7-module left navigation
- feat: Implement Title Screening Settings page with optimized PICOS layout
- feat: Add placeholder pages for Workbench and Results
- fix: Fix nested routing structure for React Router v6
- fix: Resolve Spin component warning in MainLayout
- fix: Add QueryClientProvider to App.tsx
- style: Optimize PICOS form layout (P+I left, C+O+S right)
- style: Align Inclusion/Exclusion criteria side-by-side
- docs: Add architecture refactoring and routing fix reports

Ref: Week 2 Frontend Development
Scope: ASL module MVP - Title Abstract Screening
This commit is contained in:
2025-11-18 21:51:51 +08:00
parent e3e7e028e8
commit 3634933ece
213 changed files with 20054 additions and 442 deletions

View File

@@ -42,6 +42,7 @@ model User {
batchTasks BatchTask[] // Phase 3: 批处理任务
taskTemplates TaskTemplate[] // Phase 3: 任务模板
reviewTasks ReviewTask[] // 稿件审查任务
aslProjects AslScreeningProject[] @relation("AslProjects") // ASL智能文献项目
@@index([email])
@@index([status])
@@ -391,3 +392,177 @@ model ReviewTask {
@@map("review_tasks")
@@schema("public")
}
// ==================== ASL智能文献模块 ====================
// ASL 筛选项目表
model AslScreeningProject {
id String @id @default(uuid())
userId String @map("user_id")
user User @relation("AslProjects", fields: [userId], references: [id], onDelete: Cascade)
projectName String @map("project_name")
// PICO标准
picoCriteria Json @map("pico_criteria") // { population, intervention, comparison, outcome, studyDesign }
// 筛选标准
inclusionCriteria String @map("inclusion_criteria") @db.Text
exclusionCriteria String @map("exclusion_criteria") @db.Text
// 状态
status String @default("draft") // draft, screening, completed
// 筛选配置
screeningConfig Json? @map("screening_config") // { models: ["deepseek", "qwen"], temperature: 0 }
// 关联
literatures AslLiterature[]
screeningTasks AslScreeningTask[]
screeningResults AslScreeningResult[]
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
@@map("screening_projects")
@@schema("asl_schema")
@@index([userId])
@@index([status])
}
// ASL 文献条目表
model AslLiterature {
id String @id @default(uuid())
projectId String @map("project_id")
project AslScreeningProject @relation(fields: [projectId], references: [id], onDelete: Cascade)
// 文献基本信息
pmid String?
title String @db.Text
abstract String @db.Text
authors String?
journal String?
publicationYear Int? @map("publication_year")
doi String?
// 云原生存储字段V1.0 阶段使用MVP阶段预留
pdfUrl String? @map("pdf_url") // PDF访问URL
pdfOssKey String? @map("pdf_oss_key") // OSS存储Key用于删除
pdfFileSize Int? @map("pdf_file_size") // 文件大小(字节)
// 关联
screeningResults AslScreeningResult[]
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
@@map("literatures")
@@schema("asl_schema")
@@index([projectId])
@@index([doi])
@@unique([projectId, pmid])
}
// ASL 筛选结果表
model AslScreeningResult {
id String @id @default(uuid())
projectId String @map("project_id")
project AslScreeningProject @relation(fields: [projectId], references: [id], onDelete: Cascade)
literatureId String @map("literature_id")
literature AslLiterature @relation(fields: [literatureId], references: [id], onDelete: Cascade)
// DeepSeek模型判断
dsModelName String @map("ds_model_name") // "deepseek-chat"
dsPJudgment String? @map("ds_p_judgment") // "match" | "partial" | "mismatch"
dsIJudgment String? @map("ds_i_judgment")
dsCJudgment String? @map("ds_c_judgment")
dsSJudgment String? @map("ds_s_judgment")
dsConclusion String? @map("ds_conclusion") // "include" | "exclude" | "uncertain"
dsConfidence Float? @map("ds_confidence") // 0-1
// DeepSeek模型证据
dsPEvidence String? @map("ds_p_evidence") @db.Text
dsIEvidence String? @map("ds_i_evidence") @db.Text
dsCEvidence String? @map("ds_c_evidence") @db.Text
dsSEvidence String? @map("ds_s_evidence") @db.Text
dsReason String? @map("ds_reason") @db.Text
// Qwen模型判断
qwenModelName String @map("qwen_model_name") // "qwen-max"
qwenPJudgment String? @map("qwen_p_judgment")
qwenIJudgment String? @map("qwen_i_judgment")
qwenCJudgment String? @map("qwen_c_judgment")
qwenSJudgment String? @map("qwen_s_judgment")
qwenConclusion String? @map("qwen_conclusion")
qwenConfidence Float? @map("qwen_confidence")
// Qwen模型证据
qwenPEvidence String? @map("qwen_p_evidence") @db.Text
qwenIEvidence String? @map("qwen_i_evidence") @db.Text
qwenCEvidence String? @map("qwen_c_evidence") @db.Text
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"
conflictFields Json? @map("conflict_fields") // ["P", "I", "conclusion"]
// 最终决策
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"
aiProcessedAt DateTime? @map("ai_processed_at")
aiErrorMessage String? @map("ai_error_message") @db.Text
// 可追溯信息
promptVersion String @default("v1.0.0") @map("prompt_version")
rawOutput Json? @map("raw_output") // 原始LLM输出备份
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
@@map("screening_results")
@@schema("asl_schema")
@@index([projectId])
@@index([literatureId])
@@index([conflictStatus])
@@index([finalDecision])
@@unique([projectId, literatureId])
}
// ASL 筛选任务表
model AslScreeningTask {
id String @id @default(uuid())
projectId String @map("project_id")
project AslScreeningProject @relation(fields: [projectId], references: [id], onDelete: Cascade)
taskType String @map("task_type") // "title_abstract" | "full_text"
status String @default("pending") // "pending" | "running" | "completed" | "failed"
// 进度统计
totalItems Int @map("total_items")
processedItems Int @default(0) @map("processed_items")
successItems Int @default(0) @map("success_items")
failedItems Int @default(0) @map("failed_items")
conflictItems Int @default(0) @map("conflict_items")
// 时间信息
startedAt DateTime? @map("started_at")
completedAt DateTime? @map("completed_at")
estimatedEndAt DateTime? @map("estimated_end_at")
// 错误信息
errorMessage String? @map("error_message") @db.Text
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
@@map("screening_tasks")
@@schema("asl_schema")
@@index([projectId])
@@index([status])
}

View File

@@ -106,6 +106,8 @@ main()