1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
|
'use server';
import db from '@/db/db';
import { buyerSignatures } from '@/db/schema';
import { eq } from 'drizzle-orm';
import { revalidatePath } from 'next/cache';
import { writeFile, mkdir } from 'fs/promises';
import path from 'path';
import { v4 as uuidv4 } from 'uuid';
export async function uploadBuyerSignature(formData: FormData) {
try {
const file = formData.get('file') as File;
if (!file) {
return { success: false, error: '파일이 없습니다.' };
}
// 파일 크기 체크 (5MB)
if (file.size > 5 * 1024 * 1024) {
return { success: false, error: '파일 크기는 5MB 이하여야 합니다.' };
}
// 파일 타입 체크
if (!file.type.startsWith('image/')) {
return { success: false, error: '이미지 파일만 업로드 가능합니다.' };
}
const bytes = await file.arrayBuffer();
const buffer = Buffer.from(bytes);
// Base64 변환
const base64 = `data:${file.type};base64,${buffer.toString('base64')}`;
// 파일 저장 경로
const fileName = `${uuidv4()}-${file.name}`;
const uploadDir = path.join(process.cwd(), 'public', 'uploads', 'signatures');
// 디렉토리 생성
await mkdir(uploadDir, { recursive: true });
const filePath = path.join(uploadDir, fileName);
await writeFile(filePath, buffer);
// 기존 활성 서명 비활성화
await db.update(buyerSignatures)
.set({ isActive: false })
.where(eq(buyerSignatures.isActive, true));
// 새 서명 저장
const [newSignature] = await db.insert(buyerSignatures)
.values({
name: '삼성중공업',
imageUrl: `/uploads/signatures/${fileName}`,
dataUrl: base64,
mimeType: file.type,
fileSize: file.size,
isActive: true,
})
.returning();
revalidatePath('/admin/buyer-signature');
return { success: true, signature: newSignature };
} catch (error) {
console.error('서명 업로드 실패:', error);
return { success: false, error: '서명 업로드에 실패했습니다.' };
}
}
export async function getActiveSignature() {
try {
const [signature] = await db
.select()
.from(buyerSignatures)
.where(eq(buyerSignatures.isActive, true))
.limit(1);
return signature;
} catch (error) {
console.error('활성 서명 조회 실패:', error);
return null;
}
}
export async function getAllSignatures() {
try {
const signatures = await db
.select()
.from(buyerSignatures)
.orderBy(buyerSignatures.createdAt);
return signatures;
} catch (error) {
console.error('서명 목록 조회 실패:', error);
return [];
}
}
export async function setActiveSignature(id: number) {
try {
// 모든 서명 비활성화
await db.update(buyerSignatures)
.set({ isActive: false })
.where(eq(buyerSignatures.isActive, true));
// 선택한 서명 활성화
await db.update(buyerSignatures)
.set({ isActive: true })
.where(eq(buyerSignatures.id, id));
revalidatePath('/admin/buyer-signature');
return { success: true };
} catch (error) {
console.error('활성 서명 설정 실패:', error);
return { success: false, error: '활성 서명 설정에 실패했습니다.' };
}
}
export async function deleteSignature(id: number) {
try {
await db.delete(buyerSignatures)
.where(eq(buyerSignatures.id, id));
revalidatePath('/admin/buyer-signature');
return { success: true };
} catch (error) {
console.error('서명 삭제 실패:', error);
return { success: false, error: '서명 삭제에 실패했습니다.' };
}
}
// 클라이언트에서 직접 호출할 수 있는 서버 액션
export async function getBuyerSignatureFile() {
try {
const [signature] = await db
.select()
.from(buyerSignatures)
.where(eq(buyerSignatures.isActive, true))
.limit(1);
if (!signature || !signature.dataUrl) {
console.log('활성화된 구매자 서명이 없습니다.');
return null;
}
return {
data: {
dataUrl: signature.dataUrl,
imageUrl: signature.imageUrl,
mimeType: signature.mimeType
}
};
} catch (error) {
console.error('구매자 서명 조회 실패:', error);
return null;
}
}
// 대체 서명이나 기본 서명이 필요한 경우
export async function getBuyerSignatureFileWithFallback() {
try {
// 먼저 DB에서 활성 서명 조회
const signature = await getBuyerSignatureFile();
if (signature) {
return signature;
}
// DB에 서명이 없으면 기본 서명 반환 (선택사항)
const defaultSignature = {
data: {
dataUrl: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==', // 1x1 투명 픽셀 또는 실제 기본 서명
imageUrl: '/images/default-buyer-signature.png',
mimeType: 'image/png'
}
};
return defaultSignature;
} catch (error) {
console.error('서명 조회 실패 (fallback 포함):', error);
return null;
}
}
|