feat: PDF 매칭 필터링 및 서적 정보 UI 개선

- 서적 편집 페이지에서 PDF 매칭 드롭다운이 현재 서적의 PDF만 표시하도록 수정
- PDF 관리 페이지에 서적 정보 표시 UI 추가
- 타입 안전한 비교로 book_id 필터링 개선
- PDF 통계 카드에 서적별 분류 추가
- 필터 기능에 '서적 포함' 옵션 추가
- 디버깅 로그 추가로 문제 추적 개선

주요 변경사항:
- book-editor.js: String() 타입 변환으로 안전한 book_id 비교
- pdf-manager.html/js: 서적 정보 배지 및 통계 카드 추가
- book-documents.js: HTML 문서 필터링 로직 개선
This commit is contained in:
Hyungi Ahn
2025-08-26 15:32:46 +09:00
parent 04ae64fc4d
commit 8d7f4c04bb
17 changed files with 3398 additions and 400 deletions

View File

@@ -676,6 +676,97 @@ async def download_document(
)
@router.get("/{document_id}/navigation")
async def get_document_navigation(
document_id: str,
current_user: User = Depends(get_current_active_user),
db: AsyncSession = Depends(get_db)
):
"""문서 네비게이션 정보 조회 (이전/다음 문서)"""
# 현재 문서 조회
result = await db.execute(select(Document).where(Document.id == document_id))
current_doc = result.scalar_one_or_none()
if not current_doc:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="Document not found"
)
# 권한 확인
if not current_doc.is_public and current_doc.uploaded_by != current_user.id and not current_user.is_admin:
raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN,
detail="Access denied"
)
navigation_info = {
"current": {
"id": str(current_doc.id),
"title": current_doc.title,
"sort_order": current_doc.sort_order
},
"previous": None,
"next": None,
"book_info": None
}
# 서적에 속한 문서인 경우 이전/다음 문서 조회
if current_doc.book_id:
# 같은 서적의 HTML 문서들만 조회 (PDF 제외)
book_docs_result = await db.execute(
select(Document)
.where(
and_(
Document.book_id == current_doc.book_id,
Document.html_path.isnot(None), # HTML 문서만
or_(Document.is_public == True, Document.uploaded_by == current_user.id, current_user.is_admin == True)
)
)
.order_by(Document.sort_order.asc().nulls_last(), Document.created_at.asc())
)
book_docs = book_docs_result.scalars().all()
# 현재 문서의 인덱스 찾기
current_index = None
for i, doc in enumerate(book_docs):
if doc.id == current_doc.id:
current_index = i
break
if current_index is not None:
# 이전 문서
if current_index > 0:
prev_doc = book_docs[current_index - 1]
navigation_info["previous"] = {
"id": str(prev_doc.id),
"title": prev_doc.title,
"sort_order": prev_doc.sort_order
}
# 다음 문서
if current_index < len(book_docs) - 1:
next_doc = book_docs[current_index + 1]
navigation_info["next"] = {
"id": str(next_doc.id),
"title": next_doc.title,
"sort_order": next_doc.sort_order
}
# 서적 정보 추가
from ...models.book import Book
book_result = await db.execute(select(Book).where(Book.id == current_doc.book_id))
book = book_result.scalar_one_or_none()
if book:
navigation_info["book_info"] = {
"id": str(book.id),
"title": book.title,
"author": book.author
}
return navigation_info
@router.delete("/{document_id}")
async def delete_document(
document_id: str,