diff options
Diffstat (limited to 'app/api/upload')
| -rw-r--r-- | app/api/upload/basicContract/chunk/route.ts | 71 | ||||
| -rw-r--r-- | app/api/upload/basicContract/complete/route.ts | 37 | ||||
| -rw-r--r-- | app/api/upload/signed-contract/route.ts | 57 |
3 files changed, 165 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 diff --git a/app/api/upload/basicContract/complete/route.ts b/app/api/upload/basicContract/complete/route.ts new file mode 100644 index 00000000..6398c5eb --- /dev/null +++ b/app/api/upload/basicContract/complete/route.ts @@ -0,0 +1,37 @@ +import { NextRequest, NextResponse } from 'next/server'; +import { createBasicContractTemplate } from '@/lib/basic-contract/service'; +import { revalidatePath ,revalidateTag} from 'next/cache'; + +export async function POST(request: NextRequest) { + try { + const { templateName,validityPeriod, status, fileName, filePath } = await request.json(); + + if (!templateName || !fileName || !filePath) { + return NextResponse.json({ success: false, error: '필수 정보가 누락되었습니다' }, { status: 400 }); + } + + // DB에 저장 + const { data, error } = await createBasicContractTemplate({ + templateName, + validityPeriod, + status, + fileName, + filePath + }); + + + revalidatePath('/evcp/basic-contract-templates'); + revalidatePath('/'); // 루트 경로 무효화도 시도 + revalidateTag("basic-contract-templates"); + + if (error) { + throw new Error(error); + } + + return NextResponse.json({ success: true, data }); + + } catch (error) { + console.error('템플릿 저장 오류:', error); + return NextResponse.json({ success: false, error: '서버 오류' }, { status: 500 }); + } +}
\ No newline at end of file diff --git a/app/api/upload/signed-contract/route.ts b/app/api/upload/signed-contract/route.ts new file mode 100644 index 00000000..f26e20ba --- /dev/null +++ b/app/api/upload/signed-contract/route.ts @@ -0,0 +1,57 @@ +// app/api/upload/signed-contract/route.ts +import { NextRequest, NextResponse } from 'next/server'; +import fs from 'fs/promises'; +import path from 'path'; +import { v4 as uuidv4 } from 'uuid'; +import db from "@/db/db"; +import { basicContract } from '@/db/schema'; +import { eq } from 'drizzle-orm'; +import { revalidateTag } from 'next/cache'; + +export async function POST(request: NextRequest) { + try { + const formData = await request.formData(); + const file = formData.get('file') as File; + const tableRowId = parseInt(formData.get('tableRowId') as string); + const templateName = formData.get('templateName') as string; + + if (!file || !tableRowId || !templateName) { + return NextResponse.json({ result: false, error: '필수 파라미터가 누락되었습니다.' }, { status: 400 }); + } + + const originalName = `${tableRowId}_${templateName}`; + const ext = path.extname(originalName); + const uniqueName = uuidv4() + ext; + + const publicDir = path.join(process.cwd(), "public", "basicContract"); + const relativePath = `/basicContract/${uniqueName}`; + const absolutePath = path.join(publicDir, uniqueName); + const buffer = Buffer.from(await file.arrayBuffer()); + + await fs.mkdir(publicDir, { recursive: true }); + await fs.writeFile(absolutePath, buffer); + + await db.transaction(async (tx) => { + await tx + .update(basicContract) + .set({ + status: "COMPLETED", + fileName: originalName, + filePath: relativePath, + updatedAt: new Date(), + completedAt: new Date() + }) + .where(eq(basicContract.id, tableRowId)); + }); + + // 캐시 무효화 + revalidateTag("basic-contract-requests"); + revalidateTag("basicContractView-vendor"); + + return NextResponse.json({ result: true }); + } catch (error) { + console.error('서명된 계약서 저장 오류:', error); + const errorMessage = error instanceof Error ? error.message : "알 수 없는 오류"; + return NextResponse.json({ result: false, error: errorMessage }, { status: 500 }); + } +}
\ No newline at end of file |
