feat: 완전한 문서 관리 시스템 구현
✨ 주요 기능: - 문서 사라짐 문제 해결: API limit 제한으로 인한 문서 누락 해결 - 서적별 문서 관리: HTML과 PDF 통합 관리 시스템 - PDF 뷰어 개선: 인증, 네비게이션, 에러 처리 강화 - 서적 편집/삭제: 완전한 서적 관리 기능 🔧 기술적 개선: - /api/documents/all 엔드포인트 추가 (모든 문서 조회) - HTML/PDF 문서 타입별 아이콘 및 필터링 - 서적별 뷰에서 편집/삭제 버튼 추가 - PDF Manager와 서적 편집 페이지 연동 🎨 UI/UX 개선: - Devonthink 스타일 서적 그룹화 - HTML 문서 순서 관리와 PDF 관리 섹션 분리 - 문서 타입별 시각적 구분 (HTML: 파란색, PDF: 빨간색) - 2단계 확인을 통한 안전한 서적 삭제 �� 버그 수정: - PDF 삭제 시 undefined ID 전달 문제 해결 - 서적 편집 페이지 422 오류 해결 (URL 파라미터 문제) - PDF.js 워커 설정 및 인증 토큰 처리 개선
This commit is contained in:
@@ -83,12 +83,13 @@ router = APIRouter()
|
||||
@router.get("/", response_model=List[DocumentResponse])
|
||||
async def list_documents(
|
||||
skip: int = 0,
|
||||
limit: int = 50,
|
||||
limit: int = 50, # 기본값 복원
|
||||
tag: Optional[str] = None,
|
||||
search: Optional[str] = None,
|
||||
current_user: User = Depends(get_current_active_user),
|
||||
db: AsyncSession = Depends(get_db)
|
||||
):
|
||||
"""페이지네이션이 있는 문서 목록 조회"""
|
||||
"""문서 목록 조회"""
|
||||
query = select(Document).options(
|
||||
selectinload(Document.uploader),
|
||||
@@ -160,6 +161,70 @@ async def list_documents(
|
||||
return response_data
|
||||
|
||||
|
||||
@router.get("/all", response_model=List[DocumentResponse])
|
||||
async def list_all_documents(
|
||||
current_user: User = Depends(get_current_active_user),
|
||||
db: AsyncSession = Depends(get_db)
|
||||
):
|
||||
"""모든 문서 조회 (페이지네이션 없음) - 프론트엔드 전용"""
|
||||
|
||||
query = select(Document).options(
|
||||
selectinload(Document.uploader),
|
||||
selectinload(Document.tags),
|
||||
selectinload(Document.book), # 서적 정보 추가
|
||||
selectinload(Document.category) # 소분류 정보 추가
|
||||
)
|
||||
|
||||
# 권한 필터링 (관리자가 아니면 공개 문서 + 자신이 업로드한 문서만)
|
||||
if not current_user.is_admin:
|
||||
query = query.where(
|
||||
or_(
|
||||
Document.is_public == True,
|
||||
Document.uploaded_by == current_user.id
|
||||
)
|
||||
)
|
||||
|
||||
query = query.order_by(Document.created_at.desc())
|
||||
|
||||
result = await db.execute(query)
|
||||
documents = result.scalars().all()
|
||||
|
||||
# 응답 데이터 변환
|
||||
response_data = []
|
||||
for doc in documents:
|
||||
doc_data = DocumentResponse(
|
||||
id=str(doc.id),
|
||||
title=doc.title,
|
||||
description=doc.description,
|
||||
html_path=doc.html_path, # None 가능 (PDF만 업로드한 경우)
|
||||
pdf_path=doc.pdf_path,
|
||||
thumbnail_path=doc.thumbnail_path,
|
||||
file_size=doc.file_size,
|
||||
page_count=doc.page_count,
|
||||
language=doc.language,
|
||||
is_public=doc.is_public,
|
||||
is_processed=doc.is_processed,
|
||||
created_at=doc.created_at,
|
||||
updated_at=doc.updated_at,
|
||||
document_date=doc.document_date,
|
||||
uploader_name=doc.uploader.full_name or doc.uploader.email,
|
||||
tags=[tag.name for tag in doc.tags],
|
||||
# 서적 정보 추가
|
||||
book_id=str(doc.book.id) if doc.book else None,
|
||||
book_title=doc.book.title if doc.book else None,
|
||||
book_author=doc.book.author if doc.book else None,
|
||||
# 소분류 정보 추가
|
||||
category_id=str(doc.category.id) if doc.category else None,
|
||||
category_name=doc.category.name if doc.category else None,
|
||||
sort_order=doc.sort_order,
|
||||
# PDF 매칭 정보 추가
|
||||
matched_pdf_id=str(doc.matched_pdf_id) if doc.matched_pdf_id else None
|
||||
)
|
||||
response_data.append(doc_data)
|
||||
|
||||
return response_data
|
||||
|
||||
|
||||
@router.get("/hierarchy/structured", response_model=dict)
|
||||
async def get_documents_by_hierarchy(
|
||||
current_user: User = Depends(get_current_active_user),
|
||||
@@ -375,10 +440,14 @@ async def upload_document(
|
||||
|
||||
await db.commit()
|
||||
|
||||
# 문서 정보를 다시 로드 (태그 포함)
|
||||
# 문서 정보를 다시 로드 (태그, 서적, 카테고리 포함)
|
||||
result = await db.execute(
|
||||
select(Document)
|
||||
.options(selectinload(Document.tags))
|
||||
.options(
|
||||
selectinload(Document.tags),
|
||||
selectinload(Document.book),
|
||||
selectinload(Document.category)
|
||||
)
|
||||
.where(Document.id == document.id)
|
||||
)
|
||||
document_with_tags = result.scalar_one()
|
||||
@@ -401,6 +470,14 @@ async def upload_document(
|
||||
document_date=document_with_tags.document_date,
|
||||
uploader_name=current_user.full_name or current_user.email,
|
||||
tags=[tag.name for tag in document_with_tags.tags],
|
||||
# 서적 정보 추가
|
||||
book_id=str(document_with_tags.book.id) if document_with_tags.book else None,
|
||||
book_title=document_with_tags.book.title if document_with_tags.book else None,
|
||||
book_author=document_with_tags.book.author if document_with_tags.book else None,
|
||||
# 소분류 정보 추가
|
||||
category_id=str(document_with_tags.category.id) if document_with_tags.category else None,
|
||||
category_name=document_with_tags.category.name if document_with_tags.category else None,
|
||||
sort_order=document_with_tags.sort_order,
|
||||
matched_pdf_id=str(document_with_tags.matched_pdf_id) if document_with_tags.matched_pdf_id else None
|
||||
)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user