From 3f96c9c6502243b06efd4bb34a189e72e3a5557c Mon Sep 17 00:00:00 2001
From: yearning <10538594+wangweifeng1999@user.noreply.gitee.com>
Date: 星期一, 28 九月 2026 19:24:55 +0800
Subject: [PATCH] 复制项目

---
 backend/app/schemas.py |  132 ++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 132 insertions(+), 0 deletions(-)

diff --git a/backend/app/schemas.py b/backend/app/schemas.py
new file mode 100644
index 0000000..9b116ad
--- /dev/null
+++ b/backend/app/schemas.py
@@ -0,0 +1,132 @@
+from pydantic import BaseModel, Field
+
+
+class SystemSettingsOut(BaseModel):
+    system_name: str
+    logo_url: str | None = None
+
+
+class SystemSettingsUpdate(BaseModel):
+    system_name: str = Field(min_length=1, max_length=128)
+
+
+class LoginRequest(BaseModel):
+    username: str
+    password: str
+
+
+class ChangePasswordRequest(BaseModel):
+    old_password: str = Field(min_length=1, max_length=128)
+    new_password: str = Field(min_length=6, max_length=128)
+
+
+class TokenResponse(BaseModel):
+    access_token: str
+    token_type: str = "bearer"
+
+
+class UserMe(BaseModel):
+    id: int
+    username: str
+    display_name: str
+    role: str
+
+    class Config:
+        from_attributes = True
+
+
+class ScoreRow(BaseModel):
+    examinee_id: str
+    name: str | None
+    id_card: str | None
+    subject_name: str
+    score: float
+    attempt_id: str
+    room_id: str | None = None
+    paper_name: str | None = None
+    start_time: str | None = None
+    end_time: str | None = None
+
+
+class ScoresResponse(BaseModel):
+    total: int
+    page: int
+    page_size: int
+    items: list[ScoreRow]
+
+
+class QuestionDetail(BaseModel):
+    external_item_id: str
+    part_name: str | None
+    item_type: int | None
+    item_order: int | None
+    title_html: str | None
+    detail_json: str | None
+    max_score: float | None
+    reference_answer: str | None
+    user_answer: str | None
+    is_correct: bool
+    score: float
+
+
+class PartGroup(BaseModel):
+    part_name: str
+    questions: list[QuestionDetail]
+
+
+class AttemptDetail(BaseModel):
+    attempt_id: str
+    examinee_name: str | None
+    id_card: str | None
+    score: float
+    paper_total_score: float | None
+    paper_name: str | None
+    subject_name: str | None
+    room_id: str | None
+    seat_number: str | None
+    start_time: str | None
+    end_time: str | None
+    parts: list[PartGroup]
+
+
+class GraderOut(BaseModel):
+    id: int
+    username: str
+    display_name: str
+    is_active: bool
+    created_at: str
+    subjects: list[str] = []
+
+
+class GraderCreate(BaseModel):
+    username: str = Field(min_length=2, max_length=64)
+    password: str = Field(min_length=6, max_length=128)
+    display_name: str = Field(default="", max_length=128)
+    subjects: list[str] = Field(min_length=1)
+
+
+class GraderUpdate(BaseModel):
+    username: str | None = Field(default=None, min_length=2, max_length=64)
+    password: str | None = Field(default=None, min_length=6, max_length=128)
+    display_name: str | None = Field(default=None, max_length=128)
+    is_active: bool | None = None
+    subjects: list[str] | None = None
+
+
+class GradersResponse(BaseModel):
+    items: list[GraderOut]
+
+
+class ImportBatchOut(BaseModel):
+    id: int
+    subject_name: str
+    exam_id: int | None
+    exam_ids: list[int] = []
+    zip_filename: str
+    imported_at: str
+    status: str
+    attempt_count: int = 0
+    paper_name: str | None = None
+
+    class Config:
+        from_attributes = True

--
Gitblit v1.8.0