메일관련된거 커밋

This commit is contained in:
leeheejin
2025-11-28 11:34:48 +09:00
parent ab734268a4
commit 8dcffa8927
33 changed files with 1244 additions and 812 deletions

View File

@@ -4,13 +4,35 @@ import path from "path";
// MailComponent 인터페이스 정의
export interface MailComponent {
id: string;
type: "text" | "button" | "image" | "spacer";
type: "text" | "button" | "image" | "spacer" | "header" | "infoTable" | "alertBox" | "divider" | "footer" | "numberedList";
content?: string;
text?: string;
url?: string;
src?: string;
height?: number;
styles?: Record<string, string>;
// 헤더 컴포넌트용
logoSrc?: string;
brandName?: string;
sendDate?: string;
headerBgColor?: string;
// 정보 테이블용
rows?: Array<{ label: string; value: string }>;
tableTitle?: string;
// 강조 박스용
alertType?: "info" | "warning" | "danger" | "success";
alertTitle?: string;
// 푸터용
companyName?: string;
ceoName?: string;
businessNumber?: string;
address?: string;
phone?: string;
email?: string;
copyright?: string;
// 번호 리스트용
listItems?: string[];
listTitle?: string;
}
// QueryConfig 인터페이스 정의 (사용하지 않지만 타입 호환성 유지)
@@ -236,6 +258,89 @@ class MailTemplateFileService {
case "spacer":
html += `<div style="height: ${comp.height || 20}px;"></div>`;
break;
case "header":
html += `
<div style="padding: 20px; background-color: ${comp.headerBgColor || '#f8f9fa'}; border-radius: 8px; margin-bottom: 20px;">
<table style="width: 100%;">
<tr>
<td style="vertical-align: middle;">
${comp.logoSrc ? `<img src="${comp.logoSrc}" alt="로고" style="height: 40px; margin-right: 12px;">` : ''}
<span style="font-size: 18px; font-weight: bold;">${comp.brandName || ''}</span>
</td>
<td style="text-align: right; color: #6b7280; font-size: 14px;">
${comp.sendDate || ''}
</td>
</tr>
</table>
</div>
`;
break;
case "infoTable":
html += `
<div style="border: 1px solid #e5e7eb; border-radius: 8px; overflow: hidden; margin: 16px 0;">
${comp.tableTitle ? `<div style="background-color: #f9fafb; padding: 12px 16px; font-weight: 600; border-bottom: 1px solid #e5e7eb;">${comp.tableTitle}</div>` : ''}
<table style="width: 100%; border-collapse: collapse;">
${(comp.rows || []).map((row, i) => `
<tr style="background-color: ${i % 2 === 0 ? '#ffffff' : '#f9fafb'};">
<td style="padding: 12px 16px; font-weight: 500; color: #4b5563; width: 35%; border-right: 1px solid #e5e7eb;">${row.label}</td>
<td style="padding: 12px 16px;">${row.value}</td>
</tr>
`).join('')}
</table>
</div>
`;
break;
case "alertBox":
const alertColors: Record<string, { bg: string; border: string; text: string }> = {
info: { bg: '#eff6ff', border: '#3b82f6', text: '#1e40af' },
warning: { bg: '#fffbeb', border: '#f59e0b', text: '#92400e' },
danger: { bg: '#fef2f2', border: '#ef4444', text: '#991b1b' },
success: { bg: '#ecfdf5', border: '#10b981', text: '#065f46' }
};
const colors = alertColors[comp.alertType || 'info'];
html += `
<div style="padding: 16px; background-color: ${colors.bg}; border-left: 4px solid ${colors.border}; border-radius: 4px; margin: 16px 0; color: ${colors.text};">
${comp.alertTitle ? `<div style="font-weight: bold; margin-bottom: 8px;">${comp.alertTitle}</div>` : ''}
<div>${comp.content || ''}</div>
</div>
`;
break;
case "divider":
html += `<hr style="border: none; border-top: ${comp.height || 1}px solid #e5e7eb; margin: 20px 0;">`;
break;
case "footer":
html += `
<div style="text-align: center; padding: 24px 16px; background-color: #f9fafb; border-top: 1px solid #e5e7eb; font-size: 14px; color: #6b7280;">
${comp.companyName ? `<div style="font-weight: 600; color: #374151; margin-bottom: 8px;">${comp.companyName}</div>` : ''}
${(comp.ceoName || comp.businessNumber) ? `
<div style="margin-bottom: 4px;">
${comp.ceoName ? `대표: ${comp.ceoName}` : ''}
${comp.ceoName && comp.businessNumber ? ' | ' : ''}
${comp.businessNumber ? `사업자등록번호: ${comp.businessNumber}` : ''}
</div>
` : ''}
${comp.address ? `<div style="margin-bottom: 4px;">${comp.address}</div>` : ''}
${(comp.phone || comp.email) ? `
<div style="margin-bottom: 4px;">
${comp.phone ? `Tel: ${comp.phone}` : ''}
${comp.phone && comp.email ? ' | ' : ''}
${comp.email ? `Email: ${comp.email}` : ''}
</div>
` : ''}
${comp.copyright ? `<div style="margin-top: 12px; font-size: 12px; color: #9ca3af;">${comp.copyright}</div>` : ''}
</div>
`;
break;
case "numberedList":
html += `
<div style="padding: 16px; ${styles}">
${comp.listTitle ? `<div style="font-weight: 600; margin-bottom: 12px;">${comp.listTitle}</div>` : ''}
<ol style="margin: 0; padding-left: 20px;">
${(comp.listItems || []).map(item => `<li style="margin-bottom: 8px;">${item}</li>`).join('')}
</ol>
</div>
`;
break;
}
});