feat:增加知识库文件字段

This commit is contained in:
2026-07-28 22:58:32 +08:00
parent 0e9bde9a14
commit 613eed541f
7 changed files with 93 additions and 43 deletions

6
.env
View File

@@ -7,8 +7,8 @@ OCR_API_URL=https://paddleocr.aistudio-app.com/api/v2/ocr/jobs
OCR_API_TOKEN=df7dcc85a5c3c9d64e421f353d11d13ec45512f6 OCR_API_TOKEN=df7dcc85a5c3c9d64e421f353d11d13ec45512f6
OCR_MODEL=PaddleOCR-VL-1.6 OCR_MODEL=PaddleOCR-VL-1.6
MODEL_NAME="glm-5.2" MODEL_NAME=deepseek-v4-flash
MODEL_BASE_URL="https://dashscope.aliyuncs.com/compatible-mode/v1" MODEL_BASE_URL=https://api.deepseek.com
MODEL_API_KEY="sk-52bcd98e9c1d45908437c4e8706eefff" MODEL_API_KEY=sk-0b237d41f6bc44fc9732ea66bd7eade0
DATABASE_URL=postgresql+asyncpg://agent:medical%402019@60.247.145.200:5432/study DATABASE_URL=postgresql+asyncpg://agent:medical%402019@60.247.145.200:5432/study

View File

@@ -15,3 +15,7 @@ model = init_chat_model(
# MODEL_NAME=deepseek-v4-flash # MODEL_NAME=deepseek-v4-flash
# MODEL_BASE_URL=https://api.deepseek.com # MODEL_BASE_URL=https://api.deepseek.com
# MODEL_API_KEY=sk-0b237d41f6bc44fc9732ea66bd7eade0 # MODEL_API_KEY=sk-0b237d41f6bc44fc9732ea66bd7eade0
# MODEL_NAME="glm-5.2"
# MODEL_BASE_URL="https://dashscope.aliyuncs.com/compatible-mode/v1"
# MODEL_API_KEY="sk-52bcd98e9c1d45908437c4e8706eefff"

36
main.py
View File

@@ -9,7 +9,7 @@ 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 service.agent_service import query_agent from service.agent_service import query_agent
from service.library_service import add_file, get_file, list_files from service.library_service import add_file, get_file, list_files, edit_file
from storage import upload_rustfs from storage import upload_rustfs
from ocr import ocr_from_url from ocr import ocr_from_url
@@ -23,17 +23,13 @@ app.add_middleware(
) )
@app.post("/upload") @app.post("/library/upload")
def upload(file: UploadFile = File(...)): def upload(file: UploadFile = File(...)):
url = upload_rustfs(file.file, file.filename) url = upload_rustfs(file.file, file.filename)
text = ocr_from_url(url) return ocr_from_url(url)
return {
"text": text,
}
@app.post("/generate") @app.post("/library/question")
def generate(query: QueryRequest): def generate(query: QueryRequest):
"""流式对话""" """流式对话"""
return StreamingResponse( return StreamingResponse(
@@ -42,17 +38,21 @@ def generate(query: QueryRequest):
) )
@app.post("/files", response_model=bool) @app.get("/library/files", response_model=List[LibraryFileResponse])
async def add_library_file(data: LibraryFileRequest, db: AsyncSession = Depends(get_db)):
await add_file(db, data)
return True
@app.get("/files", response_model=List[LibraryFileResponse])
async def list_library_file(db: AsyncSession = Depends(get_db)): async def list_library_file(db: AsyncSession = Depends(get_db)):
return await list_files(db) return await list_files(db)
@app.get("/files/{file_id}", response_model=LibraryFileResponse) @app.get("/library/files/{id}", response_model=LibraryFileResponse)
async def get_library_file(file_id: int, db: AsyncSession = Depends(get_db)): async def get_library_file(id: int, db: AsyncSession = Depends(get_db)):
return await get_file(db, file_id) return await get_file(db, id)
@app.post("/library/files", response_model=bool)
async def add_library_file(data: LibraryFileRequest, db: AsyncSession = Depends(get_db)):
return await add_file(db, data)
@app.put("/library/files/{id}", response_model=bool)
async def edit_library_file(id: int, data: LibraryFileRequest, db: AsyncSession = Depends(get_db)):
return await edit_file(db, id, data)

View File

@@ -11,6 +11,7 @@ class LibraryFile(AuditBase):
name = Column(String(45), nullable=False) name = Column(String(45), nullable=False)
type = Column(String(45), nullable=False) type = Column(String(45), nullable=False)
size = Column(Integer, nullable=False) size = Column(Integer, nullable=False)
content = Column(Text, nullable=False)
questions = relationship( questions = relationship(
"LibraryFileQuestion", "LibraryFileQuestion",

View File

@@ -9,3 +9,4 @@ langchain-openai~=1.4.1
starlette~=1.3.1 starlette~=1.3.1
pydantic~=2.13.4 pydantic~=2.13.4
SQLAlchemy~=2.0.51 SQLAlchemy~=2.0.51
asyncpg~=0.31.0

View File

@@ -24,6 +24,7 @@ class LibraryFileRequest(BaseModel):
name: str name: str
size: int size: int
type: str type: str
content: str
questions: List[QuestionRequest] = [] questions: List[QuestionRequest] = []

View File

@@ -1,4 +1,4 @@
from sqlalchemy import select from sqlalchemy import select, delete
from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy.orm import selectinload from sqlalchemy.orm import selectinload
@@ -6,6 +6,26 @@ from models.library import LibraryFile, LibraryFileQuestion
from schemas.library import LibraryFileRequest, LibraryFileResponse, QuestionResponse from schemas.library import LibraryFileRequest, LibraryFileResponse, QuestionResponse
async def list_files(db: AsyncSession) -> list[LibraryFileResponse]:
stmt = select(LibraryFile).order_by(LibraryFile.create_time.desc())
files = (await db.execute(stmt)).scalars().all()
return [
LibraryFileResponse(
id=file.id,
subject=file.subject,
module=file.module,
name=file.name,
type=file.type,
size=file.size,
content=file.content,
uploadTime=file.create_time.strftime("%Y-%m-%d %H:%M:%S"),
questions=[],
)
for file in files
]
async def add_file(db: AsyncSession, data: LibraryFileRequest) -> bool: async def add_file(db: AsyncSession, data: LibraryFileRequest) -> bool:
""" """
创建题库文件及其题目 创建题库文件及其题目
@@ -15,7 +35,8 @@ async def add_file(db: AsyncSession, data: LibraryFileRequest) -> bool:
module=data.module, module=data.module,
name=data.name, name=data.name,
size=data.size, size=data.size,
type=data.type type=data.type,
content=data.content,
) )
db.add(file) db.add(file)
@@ -36,6 +57,46 @@ async def add_file(db: AsyncSession, data: LibraryFileRequest) -> bool:
return True return True
async def edit_file(db: AsyncSession, file_id: int, data: LibraryFileRequest) -> bool:
"""
编辑题库文件及其题目
"""
result = await db.execute(
select(LibraryFile).where(LibraryFile.id == file_id)
)
file = result.scalar_one_or_none()
if not file:
return False
file.subject = data.subject
file.module = data.module
file.name = data.name
file.size = data.size
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: async def get_file(db: AsyncSession, file_id: int) -> LibraryFileResponse:
stmt = ( stmt = (
select(LibraryFile) select(LibraryFile)
@@ -52,6 +113,7 @@ async def get_file(db: AsyncSession, file_id: int) -> LibraryFileResponse:
name=file.name, name=file.name,
type=file.type, type=file.type,
size=file.size, size=file.size,
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=[ questions=[
QuestionResponse( QuestionResponse(
@@ -64,22 +126,3 @@ async def get_file(db: AsyncSession, file_id: int) -> LibraryFileResponse:
for q in file.questions for q in file.questions
], ],
) )
async def list_files(db: AsyncSession) -> list[LibraryFileResponse]:
stmt = select(LibraryFile).order_by(LibraryFile.create_time.desc())
files = (await db.execute(stmt)).scalars().all()
return [
LibraryFileResponse(
id=f.id,
subject=f.subject,
module=f.module,
name=f.name,
type=f.type,
size=f.size,
uploadTime=f.create_time.strftime("%Y-%m-%d %H:%M:%S"),
questions=[],
)
for f in files
]