diff options
Diffstat (limited to 'app/api/upload/basicContract/chunk/route.ts')
| -rw-r--r-- | app/api/upload/basicContract/chunk/route.ts | 71 |
1 files changed, 71 insertions, 0 deletions
diff --git a/app/api/upload/basicContract/chunk/route.ts b/app/api/upload/basicContract/chunk/route.ts new file mode 100644 index 00000000..7100988b --- /dev/null +++ b/app/api/upload/basicContract/chunk/route.ts @@ -0,0 +1,71 @@ +import { NextRequest, NextResponse } from 'next/server'; +import { mkdir, writeFile, appendFile } from 'fs/promises'; +import path from 'path'; +import crypto from 'crypto'; + +export async function POST(request: NextRequest) { + try { + const formData = await request.formData(); + + const chunk = formData.get('chunk') as File; + const filename = formData.get('filename') as string; + const chunkIndex = parseInt(formData.get('chunkIndex') as string); + const totalChunks = parseInt(formData.get('totalChunks') as string); + const fileId = formData.get('fileId') as string; + + if (!chunk || !filename || isNaN(chunkIndex) || isNaN(totalChunks) || !fileId) { + return NextResponse.json({ success: false, error: '필수 매개변수가 누락되었습니다' }, { status: 400 }); + } + + // 임시 디렉토리 생성 + const tempDir = path.join(process.cwd(), 'temp', fileId); + await mkdir(tempDir, { recursive: true }); + + // 청크 파일 저장 + const chunkPath = path.join(tempDir, `chunk-${chunkIndex}`); + const buffer = Buffer.from(await chunk.arrayBuffer()); + await writeFile(chunkPath, buffer); + + // 마지막 청크인 경우 모든 청크를 합쳐 최종 파일 생성 + if (chunkIndex === totalChunks - 1) { + const uploadDir = path.join(process.cwd(), "public", "basicContract", "template"); + await mkdir(uploadDir, { recursive: true }); + + // 파일명 생성 + const timestamp = Date.now(); + const randomHash = crypto.createHash('md5') + .update(`${filename}-${timestamp}`) + .digest('hex') + .substring(0, 8); + const hashedFileName = `${timestamp}-${randomHash}${path.extname(filename)}`; + const finalPath = path.join(uploadDir, hashedFileName); + + // 모든 청크 병합 + await writeFile(finalPath, Buffer.alloc(0)); // 빈 파일 생성 + for (let i = 0; i < totalChunks; i++) { + const chunkData = await require('fs/promises').readFile(path.join(tempDir, `chunk-${i}`)); + await appendFile(finalPath, chunkData); + } + + // 임시 파일 정리 (비동기로 처리) + require('fs/promises').rm(tempDir, { recursive: true, force: true }) + .catch((e: unknown) => console.error('청크 정리 오류:', e)); + + return NextResponse.json({ + success: true, + fileName: filename, + filePath: `/basicContract/template/${hashedFileName}` + }); + } + + return NextResponse.json({ + success: true, + chunkIndex, + message: `청크 ${chunkIndex + 1}/${totalChunks} 업로드 완료` + }); + + } catch (error) { + console.error('청크 업로드 오류:', error); + return NextResponse.json({ success: false, error: '서버 오류' }, { status: 500 }); + } +}
\ No newline at end of file |
