feat:更新练习题接口
This commit is contained in:
@@ -21,6 +21,7 @@ study_prompt = """
|
|||||||
- JSON 必须是合法格式,可被程序直接解析。
|
- JSON 必须是合法格式,可被程序直接解析。
|
||||||
|
|
||||||
4. **返回格式(严格遵循)**
|
4. **返回格式(严格遵循)**
|
||||||
|
- select字段是用户实际选择的,永远为空数组
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"id": 1,
|
"id": 1,
|
||||||
@@ -32,7 +33,8 @@ study_prompt = """
|
|||||||
"选项C内容",
|
"选项C内容",
|
||||||
"选项D内容"
|
"选项D内容"
|
||||||
],
|
],
|
||||||
"answer": ["A"]
|
"answer": ["A"],
|
||||||
|
"select": []
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 2,
|
"id": 2,
|
||||||
@@ -44,7 +46,8 @@ study_prompt = """
|
|||||||
"选项C内容",
|
"选项C内容",
|
||||||
"选项D内容"
|
"选项D内容"
|
||||||
],
|
],
|
||||||
"answer": ["A", "C"]
|
"answer": ["A", "C"],
|
||||||
|
"select": []
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
"""
|
"""
|
||||||
25
main.py
25
main.py
@@ -8,8 +8,8 @@ from starlette.responses import StreamingResponse
|
|||||||
from database import get_db
|
from database import get_db
|
||||||
from schemas.agent import QueryRequest
|
from schemas.agent import QueryRequest
|
||||||
from schemas.library import LibraryFileRequest, LibraryFileResponse
|
from schemas.library import LibraryFileRequest, LibraryFileResponse
|
||||||
from schemas.mistake import MistakeResponse
|
from schemas.mistake import MistakeResponse, MistakeRequest
|
||||||
from schemas.practice import PracticeQuestionResponse, PracticeCheckResult, PracticeRecordResponse
|
from schemas.practice import PracticeRecordResponse, PracticeRecordRequest
|
||||||
from service import library_service, practice_service, mistake_service
|
from service import library_service, practice_service, mistake_service
|
||||||
from service.agent_service import query_agent
|
from service.agent_service import query_agent
|
||||||
from storage import upload_rustfs
|
from storage import upload_rustfs
|
||||||
@@ -60,21 +60,26 @@ async def edit_file(id: int, data: LibraryFileRequest, db: AsyncSession = Depend
|
|||||||
return await library_service.edit_file(db, id, data)
|
return await library_service.edit_file(db, id, data)
|
||||||
|
|
||||||
|
|
||||||
@app.get("/practice/files/{id}", response_model=List[PracticeQuestionResponse])
|
|
||||||
async def get_question(id: int, db: AsyncSession = Depends(get_db)):
|
|
||||||
return await practice_service.get_question(db, id)
|
|
||||||
|
|
||||||
|
|
||||||
@app.get("/practice/record/{id}", response_model=List[PracticeRecordResponse])
|
@app.get("/practice/record/{id}", response_model=List[PracticeRecordResponse])
|
||||||
async def get_record(id: int, db: AsyncSession = Depends(get_db)):
|
async def get_record(id: int, db: AsyncSession = Depends(get_db)):
|
||||||
return await practice_service.get_record(db, id)
|
return await practice_service.get_record(db, id)
|
||||||
|
|
||||||
|
|
||||||
@app.post("/practice/check/{id}", response_model=List[PracticeCheckResult])
|
@app.post("/practice/record", response_model=bool)
|
||||||
async def check_practice(id: int, data: List[PracticeQuestionResponse], db: AsyncSession = Depends(get_db)):
|
async def add_record(data: PracticeRecordRequest, db: AsyncSession = Depends(get_db)):
|
||||||
return await practice_service.check_practice(db, id, data)
|
return await practice_service.add_record(db, data)
|
||||||
|
|
||||||
|
|
||||||
@app.get("/mistake", response_model=List[MistakeResponse])
|
@app.get("/mistake", response_model=List[MistakeResponse])
|
||||||
async def list_mistakes(db: AsyncSession = Depends(get_db)):
|
async def list_mistakes(db: AsyncSession = Depends(get_db)):
|
||||||
return await mistake_service.list_mistakes(db)
|
return await mistake_service.list_mistakes(db)
|
||||||
|
|
||||||
|
|
||||||
|
@app.post("/mistake", response_model=bool)
|
||||||
|
async def list_mistakes(data: list[MistakeRequest], db: AsyncSession = Depends(get_db)):
|
||||||
|
return await mistake_service.add_mistakes(db, data)
|
||||||
|
|
||||||
|
|
||||||
|
@app.delete("/mistake/{id}", response_model=bool)
|
||||||
|
async def remove_mistake(id: int, db: AsyncSession = Depends(get_db)):
|
||||||
|
return await mistake_service.remove_mistake(db, id)
|
||||||
|
|||||||
@@ -13,44 +13,12 @@ class LibraryFile(AuditBase):
|
|||||||
size = Column(Integer, nullable=False)
|
size = Column(Integer, nullable=False)
|
||||||
content = Column(Text, nullable=False)
|
content = Column(Text, nullable=False)
|
||||||
|
|
||||||
questions = relationship(
|
|
||||||
"LibraryFileQuestion",
|
|
||||||
back_populates="library_file",
|
|
||||||
cascade="all, delete-orphan"
|
|
||||||
)
|
|
||||||
|
|
||||||
practice_record = relationship(
|
practice_record = relationship(
|
||||||
"PracticeRecord",
|
"PracticeRecord",
|
||||||
back_populates="library_file",
|
back_populates="library_file",
|
||||||
cascade="all, delete-orphan"
|
cascade="all, delete-orphan"
|
||||||
)
|
)
|
||||||
|
|
||||||
mistake = relationship(
|
|
||||||
"Mistake",
|
|
||||||
back_populates="library_file",
|
|
||||||
cascade="all, delete-orphan"
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class LibraryFileQuestion(AuditBase):
|
|
||||||
library_file_id = Column(BigInteger, ForeignKey("library_file.id"), nullable=False)
|
|
||||||
|
|
||||||
type = Column(String(45), nullable=False)
|
|
||||||
question = Column(Text, nullable=False)
|
|
||||||
options = Column(JSONB, nullable=False)
|
|
||||||
answer = Column(JSONB, nullable=False)
|
|
||||||
|
|
||||||
library_file = relationship(
|
|
||||||
"LibraryFile",
|
|
||||||
back_populates="questions"
|
|
||||||
)
|
|
||||||
|
|
||||||
mistake = relationship(
|
|
||||||
"Mistake",
|
|
||||||
back_populates="library_file_question",
|
|
||||||
cascade="all, delete-orphan"
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class PracticeRecord(AuditBase):
|
class PracticeRecord(AuditBase):
|
||||||
library_file_id = Column(BigInteger, ForeignKey("library_file.id"), nullable=False)
|
library_file_id = Column(BigInteger, ForeignKey("library_file.id"), nullable=False)
|
||||||
@@ -64,18 +32,12 @@ class PracticeRecord(AuditBase):
|
|||||||
back_populates="practice_record",
|
back_populates="practice_record",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class Mistake(AuditBase):
|
class Mistake(AuditBase):
|
||||||
library_file_id = Column(BigInteger, ForeignKey("library_file.id"), nullable=False)
|
subject = Column(String(45), nullable=False)
|
||||||
question_id = Column(BigInteger, ForeignKey("library_file_question.id"), nullable=False)
|
module = Column(String(45), nullable=False)
|
||||||
|
name = Column(String(45), nullable=False)
|
||||||
wrong_count = Column(Integer, nullable=False)
|
type = Column(String(45), nullable=False)
|
||||||
|
question = Column(Text, nullable=False)
|
||||||
library_file = relationship(
|
options = Column(JSONB, nullable=False)
|
||||||
"LibraryFile",
|
answer = Column(JSONB, nullable=False)
|
||||||
back_populates="mistake",
|
|
||||||
)
|
|
||||||
|
|
||||||
library_file_question = relationship(
|
|
||||||
"LibraryFileQuestion",
|
|
||||||
back_populates="mistake",
|
|
||||||
)
|
|
||||||
|
|||||||
@@ -1,19 +1,4 @@
|
|||||||
from pydantic import BaseModel
|
from pydantic import BaseModel
|
||||||
from typing import List
|
|
||||||
|
|
||||||
|
|
||||||
class QuestionRequest(BaseModel):
|
|
||||||
type: str
|
|
||||||
question: str
|
|
||||||
options: List[str]
|
|
||||||
answer: List[str]
|
|
||||||
|
|
||||||
|
|
||||||
class QuestionResponse(QuestionRequest):
|
|
||||||
id: int
|
|
||||||
|
|
||||||
class Config:
|
|
||||||
from_attributes = True
|
|
||||||
|
|
||||||
|
|
||||||
class LibraryFileRequest(BaseModel):
|
class LibraryFileRequest(BaseModel):
|
||||||
@@ -24,13 +9,10 @@ class LibraryFileRequest(BaseModel):
|
|||||||
type: str
|
type: str
|
||||||
content: str
|
content: str
|
||||||
|
|
||||||
questions: List[QuestionRequest] = []
|
|
||||||
|
|
||||||
|
|
||||||
class LibraryFileResponse(LibraryFileRequest):
|
class LibraryFileResponse(LibraryFileRequest):
|
||||||
id: int
|
id: int
|
||||||
uploadTime: str
|
uploadTime: str
|
||||||
questions: List[QuestionResponse] = []
|
|
||||||
|
|
||||||
class Config:
|
class Config:
|
||||||
from_attributes = True
|
from_attributes = True
|
||||||
|
|||||||
@@ -3,8 +3,7 @@ from typing import List
|
|||||||
from pydantic import BaseModel
|
from pydantic import BaseModel
|
||||||
|
|
||||||
|
|
||||||
class MistakeResponse(BaseModel):
|
class MistakeRequest(BaseModel):
|
||||||
id: int
|
|
||||||
subject: str
|
subject: str
|
||||||
module: str
|
module: str
|
||||||
name: str
|
name: str
|
||||||
@@ -12,7 +11,13 @@ class MistakeResponse(BaseModel):
|
|||||||
question: str
|
question: str
|
||||||
options: List[str]
|
options: List[str]
|
||||||
answer: List[str]
|
answer: List[str]
|
||||||
wrongCount: int
|
|
||||||
|
class Config:
|
||||||
|
from_attributes = True
|
||||||
|
|
||||||
|
|
||||||
|
class MistakeResponse(MistakeRequest):
|
||||||
|
id: int
|
||||||
|
|
||||||
class Config:
|
class Config:
|
||||||
from_attributes = True
|
from_attributes = True
|
||||||
|
|||||||
@@ -2,8 +2,6 @@ from typing import List
|
|||||||
|
|
||||||
from pydantic import BaseModel
|
from pydantic import BaseModel
|
||||||
|
|
||||||
from schemas.library import QuestionRequest
|
|
||||||
|
|
||||||
|
|
||||||
class PracticeRecordRequest(BaseModel):
|
class PracticeRecordRequest(BaseModel):
|
||||||
libraryFileId: int
|
libraryFileId: int
|
||||||
@@ -20,14 +18,6 @@ class PracticeRecordResponse(PracticeRecordRequest):
|
|||||||
from_attributes = True
|
from_attributes = True
|
||||||
|
|
||||||
|
|
||||||
class PracticeQuestionResponse(QuestionRequest):
|
|
||||||
id: int
|
|
||||||
select: List[str]
|
|
||||||
|
|
||||||
class Config:
|
|
||||||
from_attributes = True
|
|
||||||
|
|
||||||
|
|
||||||
class PracticeCheckResult(BaseModel):
|
class PracticeCheckResult(BaseModel):
|
||||||
id: int
|
id: int
|
||||||
answer: List[str]
|
answer: List[str]
|
||||||
@@ -35,4 +25,4 @@ class PracticeCheckResult(BaseModel):
|
|||||||
isCorrect: bool
|
isCorrect: bool
|
||||||
|
|
||||||
class Config:
|
class Config:
|
||||||
from_attributes = True
|
from_attributes = True
|
||||||
|
|||||||
@@ -1,9 +1,8 @@
|
|||||||
from sqlalchemy import select, delete
|
from sqlalchemy import select
|
||||||
from sqlalchemy.ext.asyncio import AsyncSession
|
from sqlalchemy.ext.asyncio import AsyncSession
|
||||||
from sqlalchemy.orm import selectinload
|
|
||||||
|
|
||||||
from models.library import LibraryFile, LibraryFileQuestion
|
from models.library import LibraryFile
|
||||||
from schemas.library import LibraryFileRequest, LibraryFileResponse, QuestionResponse
|
from schemas.library import LibraryFileRequest, LibraryFileResponse
|
||||||
|
|
||||||
|
|
||||||
async def list_files(db: AsyncSession) -> list[LibraryFileResponse]:
|
async def list_files(db: AsyncSession) -> list[LibraryFileResponse]:
|
||||||
@@ -20,7 +19,6 @@ async def list_files(db: AsyncSession) -> list[LibraryFileResponse]:
|
|||||||
size=file.size,
|
size=file.size,
|
||||||
content=file.content,
|
content=file.content,
|
||||||
uploadTime=file.create_time.strftime("%Y-%m-%d %H:%M:%S"),
|
uploadTime=file.create_time.strftime("%Y-%m-%d %H:%M:%S"),
|
||||||
questions=[],
|
|
||||||
)
|
)
|
||||||
for file in files
|
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:
|
async def add_file(db: AsyncSession, data: LibraryFileRequest) -> bool:
|
||||||
"""
|
"""
|
||||||
创建题库文件及其题目
|
创建题库文件
|
||||||
"""
|
"""
|
||||||
file = LibraryFile(
|
file = LibraryFile(
|
||||||
subject=data.subject,
|
subject=data.subject,
|
||||||
@@ -40,18 +38,6 @@ async def add_file(db: AsyncSession, data: LibraryFileRequest) -> bool:
|
|||||||
)
|
)
|
||||||
|
|
||||||
db.add(file)
|
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()
|
await db.commit()
|
||||||
|
|
||||||
return True
|
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:
|
async def edit_file(db: AsyncSession, file_id: int, data: LibraryFileRequest) -> bool:
|
||||||
"""
|
"""
|
||||||
编辑题库文件及其题目
|
编辑题库文件
|
||||||
"""
|
"""
|
||||||
|
|
||||||
result = await db.execute(
|
result = await db.execute(
|
||||||
@@ -76,33 +62,13 @@ async def edit_file(db: AsyncSession, file_id: int, data: LibraryFileRequest) ->
|
|||||||
file.type = data.type
|
file.type = data.type
|
||||||
file.content = data.content
|
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()
|
await db.commit()
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
async def get_file(db: AsyncSession, file_id: int) -> LibraryFileResponse:
|
async def get_file(db: AsyncSession, file_id: int) -> LibraryFileResponse:
|
||||||
stmt = (
|
stmt = (select(LibraryFile).where(LibraryFile.id == file_id))
|
||||||
select(LibraryFile)
|
|
||||||
.options(selectinload(LibraryFile.questions))
|
|
||||||
.where(LibraryFile.id == file_id)
|
|
||||||
)
|
|
||||||
result = await db.execute(stmt)
|
result = await db.execute(stmt)
|
||||||
file = result.scalar_one_or_none()
|
file = result.scalar_one_or_none()
|
||||||
|
|
||||||
@@ -115,14 +81,4 @@ async def get_file(db: AsyncSession, file_id: int) -> LibraryFileResponse:
|
|||||||
size=file.size,
|
size=file.size,
|
||||||
content=file.content,
|
content=file.content,
|
||||||
uploadTime=file.create_time.strftime("%Y-%m-%d %H:%M:%S"),
|
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
|
|
||||||
],
|
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,68 +1,51 @@
|
|||||||
from sqlalchemy import select
|
from sqlalchemy import select, delete
|
||||||
from sqlalchemy.ext.asyncio import AsyncSession
|
from sqlalchemy.ext.asyncio import AsyncSession
|
||||||
|
|
||||||
from models.library import Mistake, LibraryFile, LibraryFileQuestion
|
from models.library import Mistake
|
||||||
from schemas.mistake import MistakeResponse
|
from schemas.mistake import MistakeResponse, MistakeRequest
|
||||||
|
|
||||||
|
|
||||||
async def list_mistakes(db: AsyncSession) -> list[MistakeResponse]:
|
async def list_mistakes(db: AsyncSession) -> list[MistakeResponse]:
|
||||||
stmt = (
|
stmt = select(Mistake).order_by(Mistake.id.desc())
|
||||||
select(
|
mistakes = (await db.execute(stmt)).scalars().all()
|
||||||
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()
|
|
||||||
|
|
||||||
return [
|
return [
|
||||||
MistakeResponse(
|
MistakeResponse(
|
||||||
id=row["id"],
|
id=mistake.id,
|
||||||
subject=row["subject"],
|
subject=mistake.subject,
|
||||||
module=row["module"],
|
module=mistake.module,
|
||||||
name=row["name"],
|
name=mistake.name,
|
||||||
type=row["type"],
|
type=mistake.type,
|
||||||
question=row["question"],
|
question=mistake.question,
|
||||||
options=row["options"],
|
options=mistake.options,
|
||||||
answer=row["answer"],
|
answer=mistake.answer
|
||||||
wrongCount=row["wrong_count"],
|
|
||||||
)
|
)
|
||||||
for row in rows
|
for mistake in mistakes
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
async def update_mistake(db: AsyncSession, library_file_id: int, question_id: int):
|
async def add_mistakes(db: AsyncSession, data: list[MistakeRequest]):
|
||||||
stmt = select(Mistake).where(
|
db.add_all(
|
||||||
Mistake.library_file_id == library_file_id,
|
[
|
||||||
Mistake.question_id == question_id,
|
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:
|
await db.commit()
|
||||||
wrong.wrong_count += 1
|
return True
|
||||||
else:
|
|
||||||
wrong = Mistake(
|
|
||||||
library_file_id=library_file_id,
|
|
||||||
question_id=question_id,
|
|
||||||
wrong_count=1
|
|
||||||
)
|
|
||||||
db.add(wrong)
|
|
||||||
|
|
||||||
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
|
||||||
|
|||||||
@@ -2,18 +2,13 @@ from typing import List
|
|||||||
|
|
||||||
from sqlalchemy import select
|
from sqlalchemy import select
|
||||||
from sqlalchemy.ext.asyncio import AsyncSession
|
from sqlalchemy.ext.asyncio import AsyncSession
|
||||||
from sqlalchemy.orm import selectinload
|
|
||||||
|
|
||||||
from models.library import LibraryFile, PracticeRecord
|
from models.library import PracticeRecord
|
||||||
from schemas.practice import PracticeQuestionResponse, PracticeRecordRequest, PracticeCheckResult, \
|
from schemas.practice import PracticeRecordRequest, PracticeRecordResponse
|
||||||
PracticeRecordResponse
|
|
||||||
from service.library_service import get_file
|
|
||||||
from service.mistake_service import update_mistake
|
|
||||||
|
|
||||||
|
|
||||||
async def get_record(db: AsyncSession, library_file_id: int) -> List[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(
|
stmt = select(PracticeRecord).where(PracticeRecord.library_file_id == library_file_id).order_by(PracticeRecord.create_time.desc())
|
||||||
PracticeRecord.create_time.desc())
|
|
||||||
records = (await db.execute(stmt)).scalars().all()
|
records = (await db.execute(stmt)).scalars().all()
|
||||||
|
|
||||||
return [
|
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]:
|
async def add_record(db: AsyncSession, data: PracticeRecordRequest):
|
||||||
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):
|
|
||||||
record = PracticeRecord(
|
record = PracticeRecord(
|
||||||
library_file_id=data.libraryFileId,
|
library_file_id=data.libraryFileId,
|
||||||
total_count=data.totalCount,
|
total_count=data.totalCount,
|
||||||
|
|||||||
Reference in New Issue
Block a user