Add spell practice, memory analytics, auth persistence, and word library UX.
Includes per-word training stats and curves, quiz session auto-save, remember-login, paginated word list with floating page arrows, and Obsidian-style relationship graph baseline. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -46,7 +46,7 @@ def login(data: UserLogin, db: Session = Depends(get_db)):
|
||||
if not user or not verify_password(data.password, user.password_hash):
|
||||
raise HTTPException(status_code=401, detail="用户名或密码错误")
|
||||
|
||||
token = create_access_token(user.id, user.username)
|
||||
token = create_access_token(user.id, user.username, remember=data.remember)
|
||||
return TokenResponse(access_token=token)
|
||||
|
||||
|
||||
|
||||
@@ -24,6 +24,15 @@ def daily_quiz(
|
||||
return DailyQuizResponse(**result)
|
||||
|
||||
|
||||
@router.get("/spell", response_model=DailyQuizResponse)
|
||||
def spell_quiz(
|
||||
db: Session = Depends(get_db),
|
||||
current_user: User = Depends(get_current_user),
|
||||
):
|
||||
result = quiz_service.get_spell_quiz(db, current_user)
|
||||
return DailyQuizResponse(**result)
|
||||
|
||||
|
||||
@router.post("/answer", response_model=QuizAnswerResponse)
|
||||
def submit_answer(
|
||||
data: QuizAnswerRequest,
|
||||
@@ -37,6 +46,7 @@ def submit_answer(
|
||||
data.question_type,
|
||||
data.user_answer,
|
||||
data.correct_answer,
|
||||
data.duration_seconds or 0,
|
||||
)
|
||||
return QuizAnswerResponse(**result)
|
||||
|
||||
|
||||
@@ -6,7 +6,14 @@ from sqlalchemy.orm import Session
|
||||
from auth import get_current_user
|
||||
from database import get_db
|
||||
from models import User
|
||||
from schemas import WordCreate, WordOut, WordUpdate
|
||||
from schemas import (
|
||||
MemoryVisualizationResponse,
|
||||
WordCreate,
|
||||
WordMemoryDetailResponse,
|
||||
WordOut,
|
||||
WordUpdate,
|
||||
)
|
||||
from services.memory_visual_service import memory_visual_service
|
||||
from services.word_service import word_service
|
||||
|
||||
router = APIRouter(prefix="/api/words", tags=["words"])
|
||||
@@ -31,6 +38,23 @@ def list_words(
|
||||
return word_service.list_words(db, current_user, status)
|
||||
|
||||
|
||||
@router.get("/memory-viz", response_model=MemoryVisualizationResponse)
|
||||
def memory_visualization(
|
||||
db: Session = Depends(get_db),
|
||||
current_user: User = Depends(get_current_user),
|
||||
):
|
||||
return memory_visual_service.get_visualization(db, current_user)
|
||||
|
||||
|
||||
@router.get("/{word_id}/memory", response_model=WordMemoryDetailResponse)
|
||||
def word_memory(
|
||||
word_id: int,
|
||||
db: Session = Depends(get_db),
|
||||
current_user: User = Depends(get_current_user),
|
||||
):
|
||||
return memory_visual_service.get_word_memory(db, current_user, word_id)
|
||||
|
||||
|
||||
@router.get("/{word_id}", response_model=WordOut)
|
||||
def get_word(
|
||||
word_id: int,
|
||||
|
||||
Reference in New Issue
Block a user