Files
study-agent-service/service/library_service.py
2026-08-09 14:02:20 +08:00

144 lines
3.8 KiB
Python

from fastapi import HTTPException
from sqlalchemy import select
from sqlalchemy.exc import SQLAlchemyError
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy.orm import joinedload
from models.library import LibraryFile, Subject, Module
from schemas.library import LibraryFileRequest, LibraryFileResponse
async def list_files(db: AsyncSession) -> list[LibraryFileResponse]:
stmt = (
select(LibraryFile)
.options(
joinedload(LibraryFile.subject),
joinedload(LibraryFile.module),
)
.order_by(LibraryFile.create_time.desc())
)
files = (await db.execute(stmt)).scalars().unique().all()
return [
LibraryFileResponse(
id=file.id,
subject=file.subject.name,
module=file.module.name,
name=file.name,
type=file.type,
size=file.size,
content=file.content,
uploadTime=file.create_time.strftime("%Y-%m-%d %H:%M:%S"),
)
for file in files
]
async def add_file(db: AsyncSession, data: LibraryFileRequest) -> bool:
try:
subject_id = await get_or_create_subject(db, data.subject)
module_id = await get_or_create_module(db, subject_id, data.module)
file = LibraryFile(
subject_id=subject_id,
module_id=module_id,
name=data.name,
size=data.size,
type=data.type,
content=data.content,
)
db.add(file)
await db.commit()
return True
except SQLAlchemyError:
await db.rollback()
raise
async def edit_file(db: AsyncSession, file_id: int, data: LibraryFileRequest) -> bool:
try:
result = await db.execute(
select(LibraryFile).where(LibraryFile.id == file_id)
)
file = result.scalar_one_or_none()
if not file:
return False
subject_id = await get_or_create_subject(db, data.subject)
module_id = await get_or_create_module(db, subject_id, data.module)
file.subject_id = subject_id
file.module_id = module_id
file.name = data.name
file.size = data.size
file.type = data.type
file.content = data.content
await db.commit()
return True
except SQLAlchemyError:
await db.rollback()
raise
async def get_file(db: AsyncSession, file_id: int) -> LibraryFileResponse:
stmt = (
select(LibraryFile)
.options(
joinedload(LibraryFile.subject),
joinedload(LibraryFile.module),
)
.where(LibraryFile.id == file_id)
)
file = (await db.execute(stmt)).scalar_one_or_none()
if not file:
raise HTTPException(status_code=404, detail="File not found")
return LibraryFileResponse(
id=file.id,
subject=file.subject.name,
module=file.module.name,
name=file.name,
type=file.type,
size=file.size,
content=file.content,
uploadTime=file.create_time.strftime("%Y-%m-%d %H:%M:%S"),
)
async def get_or_create_subject(db: AsyncSession, name: str) -> int:
stmt = select(Subject).where(Subject.name == name)
result = await db.execute(stmt)
subject = result.scalar_one_or_none()
if subject:
return subject.id
subject = Subject(name=name)
db.add(subject)
await db.flush()
return subject.id
async def get_or_create_module(db: AsyncSession, subject_id: int, name: str) -> int:
stmt = select(Module).where(
Module.subject_id == subject_id,
Module.name == name,
)
module = (await db.execute(stmt)).scalar_one_or_none()
if module:
return module.id
module = Module(subject_id=subject_id, name=name)
db.add(module)
await db.flush()
return module.id