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:
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user