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:
@@ -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])
|
||||
}
|
||||
|
||||
@@ -106,6 +106,8 @@ main()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user