diff options
Diffstat (limited to 'app/api/compliance/files/download')
| -rw-r--r-- | app/api/compliance/files/download/route.ts | 90 |
1 files changed, 90 insertions, 0 deletions
diff --git a/app/api/compliance/files/download/route.ts b/app/api/compliance/files/download/route.ts new file mode 100644 index 00000000..7bcb59cd --- /dev/null +++ b/app/api/compliance/files/download/route.ts @@ -0,0 +1,90 @@ +import { NextRequest, NextResponse } from "next/server"; +import { getServerSession } from "next-auth"; +import { authOptions } from "@/lib/auth"; +import db from "@/db/db"; +import { complianceResponseFiles } from "@/db/schema/compliance"; +import { eq } from "drizzle-orm"; +import fs from "fs/promises"; +import path from "path"; + +// MIME 타입 매핑 (기존 API와 동일) +const getMimeType = (filePath: string): string => { + const ext = path.extname(filePath).toLowerCase(); + const mimeTypes: Record<string, string> = { + '.pdf': 'application/pdf', + '.doc': 'application/msword', + '.docx': 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', + '.xls': 'application/vnd.ms-excel', + '.xlsx': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', + '.jpg': 'image/jpeg', + '.jpeg': 'image/jpeg', + '.png': 'image/png', + '.gif': 'image/gif', + '.txt': 'text/plain', + '.zip': 'application/zip', + }; + + return mimeTypes[ext] || 'application/octet-stream'; +}; + +export async function GET(request: NextRequest) { + try { + // 인증 확인 + const session = await getServerSession(authOptions); + if (!session?.user) { + return NextResponse.json({ error: "인증이 필요합니다." }, { status: 401 }); + } + + // 쿼리 파라미터에서 fileId 추출 + const { searchParams } = new URL(request.url); + const fileId = searchParams.get("fileId"); + + if (!fileId) { + return NextResponse.json({ error: "파일 ID가 필요합니다." }, { status: 400 }); + } + + // 파일 정보 조회 + const [file] = await db + .select() + .from(complianceResponseFiles) + .where(eq(complianceResponseFiles.id, parseInt(fileId))); + + if (!file) { + return NextResponse.json({ error: "파일을 찾을 수 없습니다." }, { status: 404 }); + } + + // 파일 경로 구성 (public 폴더 기준) + const filePath = path.join(process.cwd(), "public", file.filePath); + + // 파일 존재 확인 + try { + await fs.access(filePath); + } catch { + return NextResponse.json({ error: "파일이 서버에 존재하지 않습니다." }, { status: 404 }); + } + + // 파일 읽기 + const fileBuffer = await fs.readFile(filePath); + + // 파일 타입 결정 + const mimeType = file.mimeType || getMimeType(file.filePath); + + // 응답 헤더 설정 + const headers = new Headers(); + headers.set("Content-Type", mimeType); + headers.set("Content-Disposition", `attachment; filename="${encodeURIComponent(file.fileName)}"`); + headers.set("Content-Length", file.fileSize?.toString() || fileBuffer.length.toString()); + + return new NextResponse(fileBuffer, { + status: 200, + headers, + }); + + } catch (error) { + console.error("파일 다운로드 오류:", error); + return NextResponse.json( + { error: "파일 다운로드 중 오류가 발생했습니다." }, + { status: 500 } + ); + } +} |
