feat:更新练习题接口

This commit is contained in:
2026-07-30 13:07:26 +08:00
parent 50a27323cc
commit 9c9ac3ab1c
9 changed files with 83 additions and 266 deletions

View File

@@ -1,9 +1,8 @@
from sqlalchemy import select, delete
from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy.orm import selectinload
from models.library import LibraryFile, LibraryFileQuestion
from schemas.library import LibraryFileRequest, LibraryFileResponse, QuestionResponse
from models.library import LibraryFile
from schemas.library import LibraryFileRequest, LibraryFileResponse
async def list_files(db: AsyncSession) -> list[LibraryFileResponse]:
@@ -20,7 +19,6 @@ async def list_files(db: AsyncSession) -> list[LibraryFileResponse]:
size=file.size,
content=file.content,
uploadTime=file.create_time.strftime("%Y-%m-%d %H:%M:%S"),
questions=[],
)
for file in files
]
@@ -28,7 +26,7 @@ async def list_files(db: AsyncSession) -> list[LibraryFileResponse]:
async def add_file(db: AsyncSession, data: LibraryFileRequest) -> bool:
"""
创建题库文件及其题目
创建题库文件
"""
file = LibraryFile(
subject=data.subject,
@@ -40,18 +38,6 @@ async def add_file(db: AsyncSession, data: LibraryFileRequest) -> bool:
)
db.add(file)
await db.flush()
for q in data.questions:
question = LibraryFileQuestion(
library_file_id=file.id,
type=q.type,
question=q.question,
options=q.options,
answer=q.answer
)
db.add(question)
await db.commit()
return True
@@ -59,7 +45,7 @@ async def add_file(db: AsyncSession, data: LibraryFileRequest) -> bool:
async def edit_file(db: AsyncSession, file_id: int, data: LibraryFileRequest) -> bool:
"""
编辑题库文件及其题目
编辑题库文件
"""
result = await db.execute(
@@ -76,33 +62,13 @@ async def edit_file(db: AsyncSession, file_id: int, data: LibraryFileRequest) ->
file.type = data.type
file.content = data.content
await db.execute(
delete(LibraryFileQuestion)
.where(LibraryFileQuestion.library_file_id == file.id)
)
# 4. 插入新题目
for q in data.questions:
question = LibraryFileQuestion(
library_file_id=file.id,
type=q.type,
question=q.question,
options=q.options,
answer=q.answer,
)
db.add(question)
await db.commit()
return True
async def get_file(db: AsyncSession, file_id: int) -> LibraryFileResponse:
stmt = (
select(LibraryFile)
.options(selectinload(LibraryFile.questions))
.where(LibraryFile.id == file_id)
)
stmt = (select(LibraryFile).where(LibraryFile.id == file_id))
result = await db.execute(stmt)
file = result.scalar_one_or_none()
@@ -115,14 +81,4 @@ async def get_file(db: AsyncSession, file_id: int) -> LibraryFileResponse:
size=file.size,
content=file.content,
uploadTime=file.create_time.strftime("%Y-%m-%d %H:%M:%S"),
questions=[
QuestionResponse(
id=q.id,
type=q.type,
question=q.question,
options=q.options,
answer=q.answer
)
for q in file.questions
],
)

View File

@@ -1,68 +1,51 @@
from sqlalchemy import select
from sqlalchemy import select, delete
from sqlalchemy.ext.asyncio import AsyncSession
from models.library import Mistake, LibraryFile, LibraryFileQuestion
from schemas.mistake import MistakeResponse
from models.library import Mistake
from schemas.mistake import MistakeResponse, MistakeRequest
async def list_mistakes(db: AsyncSession) -> list[MistakeResponse]:
stmt = (
select(
Mistake.id,
LibraryFile.subject,
LibraryFile.module,
LibraryFile.name,
LibraryFileQuestion.type,
LibraryFileQuestion.question,
LibraryFileQuestion.options,
LibraryFileQuestion.answer,
Mistake.wrong_count,
)
.join(
LibraryFileQuestion,
Mistake.question_id == LibraryFileQuestion.id,
)
.join(
LibraryFile,
Mistake.library_file_id == LibraryFile.id,
)
)
stmt = stmt.order_by(Mistake.create_time.desc())
result = await db.execute(stmt)
rows = result.mappings().all()
stmt = select(Mistake).order_by(Mistake.id.desc())
mistakes = (await db.execute(stmt)).scalars().all()
return [
MistakeResponse(
id=row["id"],
subject=row["subject"],
module=row["module"],
name=row["name"],
type=row["type"],
question=row["question"],
options=row["options"],
answer=row["answer"],
wrongCount=row["wrong_count"],
id=mistake.id,
subject=mistake.subject,
module=mistake.module,
name=mistake.name,
type=mistake.type,
question=mistake.question,
options=mistake.options,
answer=mistake.answer
)
for row in rows
for mistake in mistakes
]
async def update_mistake(db: AsyncSession, library_file_id: int, question_id: int):
stmt = select(Mistake).where(
Mistake.library_file_id == library_file_id,
Mistake.question_id == question_id,
async def add_mistakes(db: AsyncSession, data: list[MistakeRequest]):
db.add_all(
[
Mistake(
subject=item.subject,
module=item.module,
name=item.name,
type=item.type,
question=item.question,
options=item.options,
answer=item.answer,
)
for item in data
]
)
result = await db.execute(stmt)
wrong = result.scalar_one_or_none()
if wrong:
wrong.wrong_count += 1
else:
wrong = Mistake(
library_file_id=library_file_id,
question_id=question_id,
wrong_count=1
)
db.add(wrong)
await db.commit()
return True
await db.flush()
async def remove_mistake(db: AsyncSession, mistake_id: int) -> bool:
await db.execute(delete(Mistake).where(Mistake.id == mistake_id))
await db.commit()
return True

View File

@@ -2,18 +2,13 @@ from typing import List
from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy.orm import selectinload
from models.library import LibraryFile, PracticeRecord
from schemas.practice import PracticeQuestionResponse, PracticeRecordRequest, PracticeCheckResult, \
PracticeRecordResponse
from service.library_service import get_file
from service.mistake_service import update_mistake
from models.library import PracticeRecord
from schemas.practice import PracticeRecordRequest, PracticeRecordResponse
async def get_record(db: AsyncSession, library_file_id: int) -> List[PracticeRecordResponse]:
stmt = select(PracticeRecord).where(PracticeRecord.library_file_id == library_file_id).order_by(
PracticeRecord.create_time.desc())
stmt = select(PracticeRecord).where(PracticeRecord.library_file_id == library_file_id).order_by(PracticeRecord.create_time.desc())
records = (await db.execute(stmt)).scalars().all()
return [
@@ -29,71 +24,7 @@ async def get_record(db: AsyncSession, library_file_id: int) -> List[PracticeRec
]
async def get_question(db: AsyncSession, file_id: int) -> List[PracticeQuestionResponse]:
stmt = (
select(LibraryFile)
.options(selectinload(LibraryFile.questions))
.where(LibraryFile.id == file_id)
)
result = await db.execute(stmt)
file = result.scalar_one_or_none()
return [
PracticeQuestionResponse(
id=q.id,
type=q.type,
question=q.question,
options=q.options,
answer=[],
select=[]
)
for q in file.questions
]
async def check_practice(db: AsyncSession,
library_file_id: int,
questions: List[PracticeQuestionResponse]) -> List[PracticeCheckResult]:
library_file = await get_file(db, library_file_id)
db_questions = library_file.questions
check_results = []
for user_q in questions:
db_q = next((q for q in db_questions if q.id == user_q.id), None)
if not db_q:
continue
is_correct = set(user_q.select) == set(db_q.answer)
if not is_correct:
await update_mistake(
db=db,
library_file_id=library_file_id,
question_id=user_q.id,
)
check_results.append(PracticeCheckResult(
id=user_q.id,
answer=db_q.answer,
select=user_q.select,
isCorrect=is_correct,
))
correct_count = sum(1 for r in check_results if r.isCorrect)
await add_practice_record(
db,
PracticeRecordRequest(
libraryFileId=library_file_id,
totalCount=len(check_results),
correctCount=correct_count,
wrongCount=len(check_results) - correct_count,
),
)
return check_results
async def add_practice_record(db: AsyncSession, data: PracticeRecordRequest):
async def add_record(db: AsyncSession, data: PracticeRecordRequest):
record = PracticeRecord(
library_file_id=data.libraryFileId,
total_count=data.totalCount,