summaryrefslogtreecommitdiff
path: root/lib/tbe-last/service.ts
diff options
context:
space:
mode:
Diffstat (limited to 'lib/tbe-last/service.ts')
-rw-r--r--lib/tbe-last/service.ts132
1 files changed, 132 insertions, 0 deletions
diff --git a/lib/tbe-last/service.ts b/lib/tbe-last/service.ts
index d9046524..32d5a5f5 100644
--- a/lib/tbe-last/service.ts
+++ b/lib/tbe-last/service.ts
@@ -11,6 +11,10 @@ import { filterColumns } from "@/lib/filter-columns";
import { GetTBELastSchema } from "./validations";
import { getServerSession } from "next-auth"
import { authOptions } from "@/app/api/auth/[...nextauth]/route"
+import path from "path"
+import fs from "fs/promises"
+import { sendEmail } from "../mail/sendEmail";
+
// ==========================================
// 1. TBE 세션 목록 조회
// ==========================================
@@ -415,4 +419,132 @@ function mapReviewStatus(status: string | null): string {
}
return status ? (statusMap[status] || status) : "미검토"
+}
+
+
+interface DocumentInfo {
+ documentId: number
+ documentReviewId: number
+ documentName: string
+ filePath: string
+ documentType: string
+ documentSource: string
+ reviewStatus?: string
+}
+
+interface SessionInfo {
+ sessionId: number
+ sessionTitle: string
+ buyerName: string
+ vendorName: string
+}
+
+interface SendDocumentsEmailParams {
+ to: string[]
+ cc?: string[]
+ documents: DocumentInfo[]
+ comments?: string
+ sessionInfo: SessionInfo
+}
+
+export async function sendDocumentsEmail({
+ to,
+ cc,
+ documents,
+ comments,
+ sessionInfo
+}: SendDocumentsEmailParams) {
+ try {
+ // 사용자 인증 확인
+ const session = await getServerSession(authOptions)
+ if (!session?.user) {
+ return { success: false, error: "인증이 필요합니다" }
+ }
+
+
+ // 첨부 파일 준비
+ const attachments = await Promise.all(
+ documents.map(async (doc) => {
+ try {
+ // 실제 파일 경로 구성 (프로젝트 구조에 맞게 조정 필요)
+
+ const isDev = process.env.NODE_ENV === 'development';
+
+ const filePath = isDev ? path.join(process.cwd(), 'public', doc.filePath)
+ :path.join(`${process.env.NAS_PATH}`, doc.filePath)
+
+ // 파일 존재 확인
+ await fs.access(filePath)
+
+ // 파일 읽기
+ const content = await fs.readFile(filePath)
+
+ return {
+ filename: doc.documentName,
+ content: content,
+ encoding: 'base64'
+ }
+ } catch (error) {
+ console.error(`Failed to attach file: ${doc.documentName}`, error)
+ // 파일을 찾을 수 없는 경우 건너뛰기
+ return null
+ }
+ })
+ )
+
+ // null 값 필터링
+ const validAttachments = attachments.filter(att => att !== null)
+
+ // 이메일 전송
+ const result = await sendEmail({
+ to: to.join(", "),
+ cc: cc?.join(", "),
+ template: "document-share", // 템플릿 이름
+ context: {
+ senderName: session.user.name || "TBE User",
+ senderEmail: session.user.email,
+ sessionTitle: sessionInfo.sessionTitle,
+ sessionId: sessionInfo.sessionId,
+ buyerName: sessionInfo.buyerName,
+ vendorName: sessionInfo.vendorName,
+ documentCount: documents.length,
+ documents: documents.map(doc => ({
+ name: doc.documentName,
+ type: doc.documentType,
+ source: doc.documentSource,
+ reviewStatus: doc.reviewStatus || "미검토",
+ reviewStatusClass: getReviewStatusClass(doc.reviewStatus),
+ })),
+ comments: comments || "",
+ hasComments: !!comments,
+ language: "ko", // 한국어로 설정
+ year: new Date().getFullYear(),
+ },
+ attachments: validAttachments as any
+ })
+
+ return { success: true, data: result }
+ } catch (error) {
+ console.error("Failed to send documents email:", error)
+ return {
+ success: false,
+ error: error instanceof Error ? error.message : "Failed to send email"
+ }
+ }
+}
+
+// 리뷰 상태에 따른 CSS 클래스 반환
+function getReviewStatusClass(status?: string): string {
+ switch (status) {
+ case "승인":
+ return "approved"
+ case "반려":
+ return "rejected"
+ case "보류":
+ return "pending"
+ case "검토중":
+ return "reviewing"
+ default:
+ return "unreviewed"
+ }
} \ No newline at end of file