Add word-book practice, iOS app shell, and fix embedded WebView blank screen.
Ship dual-track learning (daily accumulation vs textbook),沪教/商务词书 APIs and UI, native iOS wrapper with bundled H5, and production book import on deploy. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -47,6 +47,7 @@ class TranslateResponse(BaseModel):
|
||||
phonetic: Optional[str] = None
|
||||
example_en: Optional[str] = None
|
||||
example_cn: Optional[str] = None
|
||||
found: bool = True
|
||||
|
||||
|
||||
# Words
|
||||
@@ -67,6 +68,8 @@ class WordUpdate(BaseModel):
|
||||
class WordOut(BaseModel):
|
||||
id: int
|
||||
user_id: int
|
||||
book_id: int = 0
|
||||
book_entry_id: Optional[int] = None
|
||||
source_text: str
|
||||
target_text: str
|
||||
source_lang: str
|
||||
@@ -195,6 +198,8 @@ class QuizQuestion(BaseModel):
|
||||
class DailyQuizResponse(BaseModel):
|
||||
questions: list[QuizQuestion]
|
||||
total: int
|
||||
track: str = "accumulation"
|
||||
book_id: Optional[int] = None
|
||||
|
||||
|
||||
class QuizAnswerRequest(BaseModel):
|
||||
@@ -223,6 +228,70 @@ class QuizStatsResponse(BaseModel):
|
||||
daily_target: int
|
||||
today_completed: int
|
||||
streak_days: int
|
||||
track: str = "accumulation"
|
||||
book_id: Optional[int] = None
|
||||
|
||||
|
||||
# Word books
|
||||
class WordBookOut(BaseModel):
|
||||
id: int
|
||||
slug: str
|
||||
title: str
|
||||
description: Optional[str] = None
|
||||
level: str
|
||||
word_count: int
|
||||
unit_count: int
|
||||
sort_order: int
|
||||
daily_target: int
|
||||
master_required_count: int
|
||||
weak_wrong_threshold: int
|
||||
learn_mode: str
|
||||
|
||||
class Config:
|
||||
from_attributes = True
|
||||
|
||||
|
||||
class WordBookUnitOut(BaseModel):
|
||||
unit: int
|
||||
title: Optional[str] = None
|
||||
word_count: int
|
||||
|
||||
|
||||
class WordBookDetailOut(WordBookOut):
|
||||
units: list[WordBookUnitOut] = []
|
||||
|
||||
|
||||
class WordBookProgressOut(BaseModel):
|
||||
book_id: int
|
||||
total: int
|
||||
introduced: int
|
||||
mastered: int
|
||||
learning: int
|
||||
locked: int
|
||||
|
||||
|
||||
class BookPracticeSettingsOut(BaseModel):
|
||||
book_id: int
|
||||
daily_target: int
|
||||
master_required_count: int
|
||||
weak_wrong_threshold: int
|
||||
|
||||
|
||||
class ActiveBookOut(BaseModel):
|
||||
book: Optional[WordBookOut] = None
|
||||
progress: Optional[WordBookProgressOut] = None
|
||||
settings: Optional[BookPracticeSettingsOut] = None
|
||||
|
||||
|
||||
class SetActiveBookRequest(BaseModel):
|
||||
book_id: int = Field(ge=1)
|
||||
|
||||
|
||||
class BookPracticeSettingsUpdate(BaseModel):
|
||||
book_id: Optional[int] = Field(None, ge=1)
|
||||
daily_target: Optional[int] = Field(None, ge=5, le=50)
|
||||
master_required_count: Optional[int] = Field(None, ge=1, le=10)
|
||||
weak_wrong_threshold: Optional[int] = Field(None, ge=1, le=10)
|
||||
|
||||
|
||||
# Settings
|
||||
|
||||
Reference in New Issue
Block a user