diff options
Diffstat (limited to 'app/api/vendors/attachments/download-all/route.ts')
| -rw-r--r-- | app/api/vendors/attachments/download-all/route.ts | 108 |
1 files changed, 108 insertions, 0 deletions
diff --git a/app/api/vendors/attachments/download-all/route.ts b/app/api/vendors/attachments/download-all/route.ts new file mode 100644 index 00000000..23f85786 --- /dev/null +++ b/app/api/vendors/attachments/download-all/route.ts @@ -0,0 +1,108 @@ +// /app/api/vendors/attachments/download-all/route.js +import { NextResponse,NextRequest } from 'next/server'; +import fs from 'fs'; +import path from 'path'; +import JSZip from 'jszip'; +import db from '@/db/db'; + +import { eq } from 'drizzle-orm'; +import { vendorAttachments, vendors } from '@/db/schema'; + +export async function GET(request: NextRequest) { + try { + const { searchParams } = new URL(request.url); + const vendorId = searchParams.get('vendorId'); + + if (!vendorId) { + return NextResponse.json( + { error: "필수 파라미터가 누락되었습니다." }, + { status: 400 } + ); + } + + // 협력업체 정보 조회 + const vendor = await db.query.vendors.findFirst({ + where: eq(vendors.id, parseInt(vendorId, 10)) + }); + + if (!vendor) { + return NextResponse.json( + { error: `협력업체 정보를 찾을 수 없습니다. (ID: ${vendorId})` }, + { status: 404 } + ); + } + + // 첨부파일 조회 + const attachments = await db.select() + .from(vendorAttachments) + .where(eq(vendorAttachments.vendorId, parseInt(vendorId, 10))); + + if (!attachments.length) { + return NextResponse.json( + { error: '다운로드할 첨부파일이 없습니다.' }, + { status: 404 } + ); + } + + // 업로드 기본 경로 + const basePath = process.env.UPLOAD_DIR || path.join(process.cwd(), 'public'); + + // ZIP 생성 + const zip = new JSZip(); + + // 파일 읽기 및 ZIP에 추가 + await Promise.all( + attachments.map(async (attachment) => { + const filePath = path.join(basePath, attachment.filePath); + + try { + // 파일 존재 확인 + try { + await fs.promises.access(filePath, fs.constants.F_OK); + } catch (e) { + console.warn(`파일이 존재하지 않습니다: ${filePath}`); + return; // 파일이 없으면 건너뜀 + } + + // 파일 읽기 + const fileData = await fs.promises.readFile(filePath); + + // ZIP에 파일 추가 + zip.file(attachment.fileName, fileData); + } catch (error) { + console.warn(`파일을 처리할 수 없습니다: ${filePath}`, error); + // 오류가 있더라도 계속 진행 + } + }) + ); + + // ZIP 생성 + const zipContent = await zip.generateAsync({ + type: 'nodebuffer', + compression: 'DEFLATE', + compressionOptions: { level: 9 } + }); + + // 파일명 생성 + const fileName = `${vendor.vendorName || `vendor-${vendorId}`}-attachments.zip`; + + // 응답 헤더 설정 + const headers = new Headers(); + headers.set('Content-Disposition', `attachment; filename="${fileName}"`); + headers.set('Content-Type', 'application/zip'); + headers.set('Content-Length', zipContent.length.toString()); + + // ZIP 파일 데이터와 함께 응답 + return new Response(zipContent, { + status: 200, + headers + }); + + } catch (error) { + console.error('첨부파일 다운로드 오류:', error); + return NextResponse.json( + { error: "첨부파일 다운로드 준비 중 오류가 발생했습니다." }, + { status: 500 } + ); + } +}
\ No newline at end of file |
