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:
john
2026-06-06 21:09:27 +08:00
parent 2fae90b597
commit e76fa586f1
76 changed files with 47488 additions and 445 deletions
+14 -5
View File
@@ -57,14 +57,23 @@ def mastery_at_time(word: Word, records: list[QuizRecord], at: datetime) -> floa
class MemoryVisualService:
def get_visualization(self, db: Session, user: User, horizon_days: int = 30) -> dict:
words = db.query(Word).filter(Word.user_id == user.id).all()
records = (
db.query(QuizRecord)
def get_visualization(
self, db: Session, user: User, horizon_days: int = 30, book_id: int = 0
) -> dict:
words = (
db.query(Word)
.filter(Word.user_id == user.id, Word.book_id == book_id, Word.status != "locked")
.all()
)
word_ids = {w.id for w in words}
records = [
r
for r in db.query(QuizRecord)
.filter(QuizRecord.user_id == user.id)
.order_by(QuizRecord.created_at.asc())
.all()
)
if r.word_id in word_ids
]
records_by_word: dict[int, list[QuizRecord]] = defaultdict(list)
for r in records:
records_by_word[r.word_id].append(r)