feat: PDF/HTML 폴더 분리 및 필터링 개선
- 업로드 시 HTML과 PDF를 별도 폴더에 저장 (/documents/, /pdfs/) - 프론트엔드 필터링을 폴더 경로 기준으로 단순화 - PDF 삭제 시 외래키 참조 해제 로직 추가 - book-documents.js, book-editor.js 필터링 통일 - HTML 문서 목록에서 PDF 완전 분리
This commit is contained in:
@@ -261,8 +261,11 @@ window.uploadApp = () => ({
|
||||
console.log('📄 HTML 파일:', htmlFiles.length, '개');
|
||||
console.log('📕 PDF 파일:', pdfFiles.length, '개');
|
||||
|
||||
// HTML 파일 업로드 (백엔드 API에 맞게)
|
||||
const uploadPromises = htmlFiles.map(async (file, index) => {
|
||||
// 업로드할 파일들 처리
|
||||
const uploadPromises = [];
|
||||
|
||||
// HTML 파일 업로드 (PDF 파일이 있으면 함께 업로드)
|
||||
htmlFiles.forEach(async (file, index) => {
|
||||
const formData = new FormData();
|
||||
formData.append('html_file', file); // 백엔드가 요구하는 필드명
|
||||
formData.append('title', file.name.replace(/\.[^/.]+$/, "")); // 확장자 제거
|
||||
@@ -270,52 +273,96 @@ window.uploadApp = () => ({
|
||||
formData.append('language', 'ko');
|
||||
formData.append('is_public', 'false');
|
||||
|
||||
// 같은 이름의 PDF 파일이 있는지 확인
|
||||
const htmlBaseName = file.name.replace(/\.[^/.]+$/, "");
|
||||
const matchingPdf = pdfFiles.find(pdfFile => {
|
||||
const pdfBaseName = pdfFile.name.replace(/\.[^/.]+$/, "");
|
||||
return pdfBaseName === htmlBaseName;
|
||||
});
|
||||
|
||||
if (matchingPdf) {
|
||||
formData.append('pdf_file', matchingPdf);
|
||||
console.log('📎 매칭된 PDF 파일 함께 업로드:', matchingPdf.name);
|
||||
}
|
||||
|
||||
if (bookId) {
|
||||
formData.append('book_id', bookId);
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await window.api.uploadDocument(formData);
|
||||
console.log('✅ HTML 파일 업로드 완료:', file.name);
|
||||
return response;
|
||||
} catch (error) {
|
||||
console.error('❌ HTML 파일 업로드 실패:', file.name, error);
|
||||
throw error;
|
||||
const uploadPromise = (async () => {
|
||||
try {
|
||||
const response = await window.api.uploadDocument(formData);
|
||||
console.log('✅ HTML 파일 업로드 완료:', file.name);
|
||||
return response;
|
||||
} catch (error) {
|
||||
console.error('❌ HTML 파일 업로드 실패:', file.name, error);
|
||||
throw error;
|
||||
}
|
||||
})();
|
||||
|
||||
uploadPromises.push(uploadPromise);
|
||||
});
|
||||
|
||||
// HTML과 매칭되지 않은 PDF 파일들을 별도로 업로드
|
||||
const unmatchedPdfs = pdfFiles.filter(pdfFile => {
|
||||
const pdfBaseName = pdfFile.name.replace(/\.[^/.]+$/, "");
|
||||
return !htmlFiles.some(htmlFile => {
|
||||
const htmlBaseName = htmlFile.name.replace(/\.[^/.]+$/, "");
|
||||
return htmlBaseName === pdfBaseName;
|
||||
});
|
||||
});
|
||||
|
||||
unmatchedPdfs.forEach(async (file, index) => {
|
||||
const formData = new FormData();
|
||||
formData.append('html_file', file); // PDF도 html_file로 전송 (백엔드에서 처리)
|
||||
formData.append('title', file.name.replace(/\.[^/.]+$/, "")); // 확장자 제거
|
||||
formData.append('description', `PDF 파일: ${file.name}`);
|
||||
formData.append('language', 'ko');
|
||||
formData.append('is_public', 'false');
|
||||
|
||||
if (bookId) {
|
||||
formData.append('book_id', bookId);
|
||||
}
|
||||
|
||||
const uploadPromise = (async () => {
|
||||
try {
|
||||
const response = await window.api.uploadDocument(formData);
|
||||
console.log('✅ PDF 파일 업로드 완료:', file.name);
|
||||
return response;
|
||||
} catch (error) {
|
||||
console.error('❌ PDF 파일 업로드 실패:', file.name, error);
|
||||
throw error;
|
||||
}
|
||||
})();
|
||||
|
||||
uploadPromises.push(uploadPromise);
|
||||
});
|
||||
|
||||
// PDF 파일은 별도로 처리 (나중에 HTML과 매칭)
|
||||
const pdfUploadPromises = pdfFiles.map(async (file, index) => {
|
||||
// PDF 전용 업로드 로직 (임시로 HTML 파일로 처리하지 않음)
|
||||
console.log('📕 PDF 파일 대기 중:', file.name);
|
||||
return {
|
||||
id: `pdf-${Date.now()}-${index}`,
|
||||
title: file.name.replace(/\.[^/.]+$/, ""),
|
||||
original_filename: file.name,
|
||||
file_type: 'pdf',
|
||||
file: file // 실제 파일 객체 보관
|
||||
};
|
||||
});
|
||||
// 모든 업로드 완료 대기
|
||||
const uploadedDocs = await Promise.all(uploadPromises);
|
||||
|
||||
// HTML 파일 업로드 완료 대기
|
||||
const uploadedHtmlDocs = await Promise.all(uploadPromises);
|
||||
// HTML 문서와 PDF 문서 분리
|
||||
const htmlDocuments = uploadedDocs.filter(doc =>
|
||||
doc.html_path && doc.html_path !== null
|
||||
);
|
||||
|
||||
// PDF 파일 처리 (실제 업로드는 하지 않고 매칭용으로만 보관)
|
||||
const pdfDocs = await Promise.all(pdfUploadPromises);
|
||||
const pdfDocuments = uploadedDocs.filter(doc =>
|
||||
(doc.original_filename && doc.original_filename.toLowerCase().endsWith('.pdf')) ||
|
||||
(doc.pdf_path && !doc.html_path)
|
||||
);
|
||||
|
||||
// 업로드된 HTML 문서 정리
|
||||
this.uploadedDocuments = uploadedHtmlDocs.map((doc, index) => ({
|
||||
// 업로드된 HTML 문서들만 정리 (순서 조정용)
|
||||
this.uploadedDocuments = htmlDocuments.map((doc, index) => ({
|
||||
...doc,
|
||||
display_order: index + 1,
|
||||
matched_pdf_id: null,
|
||||
file_type: 'html'
|
||||
matched_pdf_id: null
|
||||
}));
|
||||
|
||||
// PDF 파일 목록 (매칭용)
|
||||
this.pdfFiles = pdfDocs;
|
||||
// PDF 파일들을 매칭용으로 저장
|
||||
this.pdfFiles = pdfDocuments;
|
||||
|
||||
console.log('🎉 모든 파일 업로드 완료!');
|
||||
console.log('📄 HTML 문서:', this.uploadedDocuments.filter(doc => doc.file_type === 'html').length, '개');
|
||||
console.log('📄 HTML 문서:', this.uploadedDocuments.length, '개');
|
||||
console.log('📕 PDF 문서:', this.pdfFiles.length, '개');
|
||||
|
||||
// 3단계로 이동
|
||||
|
||||
Reference in New Issue
Block a user