일반견적서 pdf 변환 메일 첨부 수정
This commit is contained in:
@@ -773,6 +773,142 @@ public class MailUtil {
|
||||
return sendMailNew("", toUserEmail, subject, contents, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* UTF-8 인코딩으로 메일 발송 (견적서 등 한글 내용이 많은 경우)
|
||||
* 기존 sendMailWithAttachFile과 동일하지만 UTF-8 인코딩 사용
|
||||
*/
|
||||
public static boolean sendMailWithAttachFileUTF8(String fromUserId, String fromEmail
|
||||
, ArrayList<String> toUserIdList, ArrayList<String> toEmailList, ArrayList<String> ccEmailList, ArrayList<String> bccEmailList
|
||||
, String important, String subject, String contents
|
||||
, ArrayList<HashMap> attachFileList
|
||||
, String mailType
|
||||
) {
|
||||
|
||||
if(Constants.Mail.sendMailSwitch == false){
|
||||
System.out.println("MailUtil.sendMailWithAttachFileUTF8 ::: Constants.Mail.sendMailSwitch is FALSE");
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
/*변수 초기화*/
|
||||
fromUserId = CommonUtils.checkNull(fromUserId, "admin");
|
||||
fromEmail = Constants.Mail.SMTP_USER;
|
||||
important = CommonUtils.checkNull(important);
|
||||
subject = CommonUtils.checkNull(subject , "empty subject" );
|
||||
contents = CommonUtils.checkNull(contents, "empty contents");
|
||||
mailType = CommonUtils.checkNull(mailType, "empty mailType");
|
||||
|
||||
System.out.println("MailUtil.sendMailWithAttachFileUTF8()..");
|
||||
System.out.println("MailUtil.sendMailWithAttachFileUTF8(fromUserId ):"+fromUserId);
|
||||
System.out.println("MailUtil.sendMailWithAttachFileUTF8(fromEmail ):"+fromEmail);
|
||||
System.out.println("MailUtil.sendMailWithAttachFileUTF8(toEmailList ):"+toEmailList);
|
||||
System.out.println("MailUtil.sendMailWithAttachFileUTF8(ccEmailList ):"+ccEmailList);
|
||||
System.out.println("MailUtil.sendMailWithAttachFileUTF8(subject ):"+subject);
|
||||
|
||||
if(toEmailList == null){ return false; }
|
||||
|
||||
//◆◆◆ 1. mail session ◆◆◆
|
||||
Properties prop = new Properties();
|
||||
prop.put("mail.smtp.host", Constants.Mail.SMTP_HOST);
|
||||
prop.put("mail.smtp.port", Constants.Mail.SMTP_PORT);
|
||||
prop.put("mail.smtp.auth" , "true");
|
||||
prop.put("mail.smtp.starttls.enable" , "true");
|
||||
prop.put("mail.smtps.checkserveridentity", "true");
|
||||
prop.put("mail.smtps.ssl.trust" , "*");
|
||||
prop.put("mail.debug" , "true");
|
||||
prop.put("mail.smtp.socketFactory.class" , "javax.net.ssl.SSLSocketFactory");
|
||||
prop.put("mail.smtp.ssl.enable" , "true");
|
||||
prop.put("mail.smtp.socketFactory.port" , Constants.Mail.SMTP_PORT);
|
||||
prop.put("mail.smtp.ssl.trust" , "smtp.gmail.com");
|
||||
prop.put("mail.transport.protocol", "smtp");
|
||||
prop.put("mail.smtp.ssl.protocols", "TLSv1.2");
|
||||
|
||||
Session mailSession = Session.getDefaultInstance(prop, new javax.mail.Authenticator() {
|
||||
protected PasswordAuthentication getPasswordAuthentication() {
|
||||
return new PasswordAuthentication(Constants.Mail.SMTP_USER, Constants.Mail.SMTP_USER_PW);
|
||||
}
|
||||
});
|
||||
mailSession.setDebug(true);
|
||||
mailSession.setDebugOut(new PrintStream(new ByteArrayOutputStream()));
|
||||
|
||||
//◆◆◆ 2. message ◆◆◆
|
||||
MimeMessage message = new MimeMessage(mailSession);
|
||||
message.setFrom(new InternetAddress( fromEmail ));
|
||||
|
||||
// 수신자
|
||||
if(toEmailList != null){
|
||||
for (String _mail : toEmailList) {
|
||||
if(CommonUtils.checkNull(_mail).equals("")){
|
||||
continue;
|
||||
}
|
||||
message.addRecipient(Message.RecipientType.TO, new InternetAddress(_mail));
|
||||
}
|
||||
}
|
||||
// 참조
|
||||
if(ccEmailList != null){
|
||||
for (String _mail : ccEmailList) {
|
||||
if(CommonUtils.checkNull(_mail).equals("")){
|
||||
continue;
|
||||
}
|
||||
message.addRecipient(Message.RecipientType.CC, new InternetAddress(_mail));
|
||||
}
|
||||
}
|
||||
// 숨은참조
|
||||
if(bccEmailList != null){
|
||||
for (String _mail : bccEmailList) {
|
||||
if(CommonUtils.checkNull(_mail).equals("")){
|
||||
continue;
|
||||
}
|
||||
message.addRecipient(Message.RecipientType.BCC, new InternetAddress(_mail));
|
||||
}
|
||||
}
|
||||
// 중요도
|
||||
if("".equals(important)){
|
||||
message.setHeader("Importance", "Normal");
|
||||
}else{
|
||||
message.setHeader("Importance", important);
|
||||
}
|
||||
// 제목 (UTF-8)
|
||||
message.setSubject(subject, "UTF-8");
|
||||
|
||||
Multipart multipart = new MimeMultipart();
|
||||
// 내용 (UTF-8)
|
||||
MimeBodyPart mbp_content = new MimeBodyPart();
|
||||
mbp_content.setContent(contents, "text/html;charset=UTF-8");
|
||||
mbp_content.setHeader("Content-Transfer-Encoding", "base64");
|
||||
multipart.addBodyPart(mbp_content);
|
||||
|
||||
// 첨부파일
|
||||
if(attachFileList != null){
|
||||
for(HashMap hmFile : attachFileList){
|
||||
String filepath = CommonUtils.checkNull(hmFile.get(Constants.Db.COL_FILE_PATH)) + File.separator + CommonUtils.checkNull(hmFile.get(Constants.Db.COL_FILE_SAVED_NAME));
|
||||
File attach_file = new File(filepath);
|
||||
String attach_fileName = CommonUtils.checkNull(hmFile.get(Constants.Db.COL_FILE_REAL_NAME));
|
||||
|
||||
MimeBodyPart mbp_attachFile = new MimeBodyPart();
|
||||
mbp_attachFile.setFileName(MimeUtility.encodeText(attach_fileName, "UTF-8", "B"));
|
||||
mbp_attachFile.setDataHandler(new DataHandler(new FileDataSource(attach_file)));
|
||||
mbp_attachFile.setHeader("Content-Type", Files.probeContentType(Paths.get(attach_file.getCanonicalPath())));
|
||||
mbp_attachFile.setDescription(attach_fileName.split("\\.")[0], "UTF-8");
|
||||
multipart.addBodyPart(mbp_attachFile);
|
||||
}
|
||||
}
|
||||
message.setContent(multipart);
|
||||
message.setSentDate(new Date());
|
||||
|
||||
// 메일 발송
|
||||
Transport.send(message);
|
||||
System.out.println("메일 발송 성공 (UTF-8)");
|
||||
|
||||
return true;
|
||||
|
||||
} catch (Exception e) {
|
||||
System.out.println("메일 발송 실패 (UTF-8): " + e.getMessage());
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 첨부파일 목록을 파일하나로 압축해서 반환
|
||||
* @param zipFileName 압축파일명
|
||||
|
||||
@@ -2071,34 +2071,49 @@ public class ContractMgmtController {
|
||||
}
|
||||
|
||||
/**
|
||||
* 견적서 메일 발송 (AJAX) - PDF 파일 업로드 방식
|
||||
* PDF 청크 업로드 (AJAX)
|
||||
* @param request
|
||||
* @param paramMap - objId (CONTRACT_OBJID)
|
||||
* @param pdfFile - PDF 파일 (MultipartFile)
|
||||
* @param paramMap - sessionId, chunkIndex, totalChunks, chunk
|
||||
* @return
|
||||
*/
|
||||
@ResponseBody
|
||||
@RequestMapping(value="/contractMgmt/uploadPdfChunk.do", method=RequestMethod.POST)
|
||||
public Map uploadPdfChunk(HttpServletRequest request,
|
||||
@RequestParam Map<String, Object> paramMap){
|
||||
Map resultMap = new HashMap();
|
||||
|
||||
try {
|
||||
resultMap = contractMgmtService.uploadPdfChunk(request, paramMap);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
resultMap.put("result", "error");
|
||||
resultMap.put("message", "청크 업로드 중 오류가 발생했습니다: " + e.getMessage());
|
||||
}
|
||||
|
||||
return resultMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* 견적서 메일 발송 (AJAX) - PDF 세션 ID 방식
|
||||
* @param request
|
||||
* @param paramMap - objId (CONTRACT_OBJID), pdfSessionId (업로드된 PDF 세션 ID)
|
||||
* @return
|
||||
*/
|
||||
@ResponseBody
|
||||
@RequestMapping(value="/contractMgmt/sendEstimateMail.do", method=RequestMethod.POST)
|
||||
public Map sendEstimateMail(HttpServletRequest request,
|
||||
@RequestParam Map<String, Object> paramMap,
|
||||
@RequestParam(value="pdfFile", required=false) org.springframework.web.multipart.MultipartFile pdfFile){
|
||||
@RequestParam Map<String, Object> paramMap){
|
||||
Map resultMap = new HashMap();
|
||||
|
||||
try {
|
||||
String objId = CommonUtils.checkNull(paramMap.get("objId"));
|
||||
|
||||
|
||||
if("".equals(objId) || "-1".equals(objId)){
|
||||
resultMap.put("result", "error");
|
||||
resultMap.put("message", "잘못된 요청입니다.");
|
||||
return resultMap;
|
||||
}
|
||||
|
||||
// PDF 파일을 paramMap에 추가
|
||||
if(pdfFile != null && !pdfFile.isEmpty()) {
|
||||
paramMap.put("pdfFile", pdfFile);
|
||||
}
|
||||
|
||||
// 메일 발송 서비스 호출
|
||||
resultMap = contractMgmtService.sendEstimateMail(request, paramMap);
|
||||
|
||||
|
||||
@@ -1572,62 +1572,23 @@ public class ContractMgmtService {
|
||||
ccEmailList.add(writerEmail);
|
||||
}
|
||||
|
||||
// 7-1. PDF 파일 처리 (MultipartFile로 전송된 경우)
|
||||
// 7-1. PDF 파일 처리 (세션 ID로 업로드된 경우)
|
||||
ArrayList<HashMap> attachFileList = new ArrayList<HashMap>();
|
||||
org.springframework.web.multipart.MultipartFile pdfFile =
|
||||
(org.springframework.web.multipart.MultipartFile) paramMap.get("pdfFile");
|
||||
String pdfSessionId = CommonUtils.checkNull(paramMap.get("pdfSessionId"));
|
||||
|
||||
System.out.println("===== PDF 파일 수신 확인 =====");
|
||||
System.out.println("pdfFile 존재 여부: " + (pdfFile != null));
|
||||
if(pdfFile != null) {
|
||||
System.out.println("pdfFile 크기: " + pdfFile.getSize() + " bytes");
|
||||
System.out.println("pdfFile 이름: " + pdfFile.getOriginalFilename());
|
||||
}
|
||||
System.out.println("==============================");
|
||||
|
||||
if(pdfFile != null && !pdfFile.isEmpty()) {
|
||||
// MultipartFile을 임시 파일로 저장
|
||||
try {
|
||||
System.out.println("PDF 파일 저장 시작...");
|
||||
|
||||
// 견적번호를 파일명으로 사용
|
||||
String estimateNo = CommonUtils.checkNull(estimateTemplate.get("estimate_no"));
|
||||
if("".equals(estimateNo)) estimateNo = CommonUtils.checkNull(estimateTemplate.get("ESTIMATE_NO"));
|
||||
if("".equals(estimateNo)) estimateNo = "견적서";
|
||||
|
||||
System.out.println("견적번호: " + estimateNo);
|
||||
|
||||
// 임시 디렉토리에 파일 저장
|
||||
String tempDir = System.getProperty("java.io.tmpdir");
|
||||
java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyyMMddHHmmss");
|
||||
String timestamp = sdf.format(new java.util.Date());
|
||||
String fileName = estimateNo + "_" + timestamp + ".pdf";
|
||||
String filePath = tempDir + File.separator + fileName;
|
||||
|
||||
File tempFile = new File(filePath);
|
||||
pdfFile.transferTo(tempFile);
|
||||
|
||||
// JVM 종료 시 자동 삭제
|
||||
tempFile.deleteOnExit();
|
||||
|
||||
System.out.println("PDF 파일 저장 성공: " + tempFile.getAbsolutePath());
|
||||
|
||||
// File 객체를 HashMap으로 변환 (MailUtil이 요구하는 형식)
|
||||
if(!"".equals(pdfSessionId)) {
|
||||
// 세션 ID로 저장된 PDF 파일 가져오기
|
||||
File pdfFile = getPdfFromSession(pdfSessionId, estimateTemplate);
|
||||
if(pdfFile != null && pdfFile.exists()) {
|
||||
HashMap<String, String> fileMap = new HashMap<String, String>();
|
||||
fileMap.put(Constants.Db.COL_FILE_REAL_NAME, tempFile.getName());
|
||||
fileMap.put(Constants.Db.COL_FILE_SAVED_NAME, tempFile.getName());
|
||||
fileMap.put(Constants.Db.COL_FILE_PATH, tempFile.getParent());
|
||||
fileMap.put(Constants.Db.COL_FILE_REAL_NAME, pdfFile.getName());
|
||||
fileMap.put(Constants.Db.COL_FILE_SAVED_NAME, pdfFile.getName());
|
||||
fileMap.put(Constants.Db.COL_FILE_PATH, pdfFile.getParent());
|
||||
attachFileList.add(fileMap);
|
||||
|
||||
System.out.println("===== PDF 파일 처리 완료 =====");
|
||||
System.out.println("PDF 파일 경로: " + tempFile.getAbsolutePath());
|
||||
System.out.println("PDF 파일 크기: " + tempFile.length() + " bytes");
|
||||
System.out.println("=============================");
|
||||
|
||||
} catch(Exception pdfEx) {
|
||||
System.out.println("PDF 처리 중 오류 발생: " + pdfEx.getMessage());
|
||||
pdfEx.printStackTrace();
|
||||
// PDF 처리 실패해도 메일은 발송 (첨부 없이)
|
||||
System.out.println("PDF 파일 첨부 완료: " + pdfFile.getAbsolutePath());
|
||||
} else {
|
||||
System.out.println("PDF 파일을 찾을 수 없습니다: " + pdfSessionId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1645,7 +1606,8 @@ public class ContractMgmtService {
|
||||
|
||||
boolean mailSent = false;
|
||||
try {
|
||||
mailSent = MailUtil.sendMailWithAttachFile(
|
||||
// UTF-8 인코딩 메서드 사용 (견적서는 한글 내용이 많음)
|
||||
mailSent = MailUtil.sendMailWithAttachFileUTF8(
|
||||
fromUserId,
|
||||
null, // fromEmail (자동으로 SMTP 설정 사용)
|
||||
new ArrayList<String>(), // toUserIdList (빈 리스트)
|
||||
@@ -2487,4 +2449,143 @@ private String encodeImageToBase64(String imagePath) {
|
||||
|
||||
return itemList;
|
||||
}
|
||||
|
||||
/**
|
||||
* PDF 청크 업로드 처리
|
||||
* @param request
|
||||
* @param paramMap - sessionId, chunkIndex, totalChunks, chunk
|
||||
* @return
|
||||
*/
|
||||
public Map uploadPdfChunk(HttpServletRequest request, Map<String, Object> paramMap) {
|
||||
Map resultMap = new HashMap();
|
||||
|
||||
try {
|
||||
System.out.println("===== uploadPdfChunk 호출 =====");
|
||||
System.out.println("전달된 파라미터: " + paramMap);
|
||||
System.out.println("==============================");
|
||||
|
||||
String sessionId = CommonUtils.checkNull(paramMap.get("sessionId"));
|
||||
String chunkIndexStr = CommonUtils.checkNull(paramMap.get("chunkIndex"));
|
||||
String totalChunksStr = CommonUtils.checkNull(paramMap.get("totalChunks"));
|
||||
String chunk = CommonUtils.checkNull(paramMap.get("chunk"));
|
||||
|
||||
if("".equals(sessionId) || "".equals(chunkIndexStr) || "".equals(totalChunksStr) || "".equals(chunk)) {
|
||||
System.out.println("필수 파라미터 누락");
|
||||
resultMap.put("result", "error");
|
||||
resultMap.put("message", "필수 파라미터가 누락되었습니다.");
|
||||
return resultMap;
|
||||
}
|
||||
|
||||
int chunkIndex = Integer.parseInt(chunkIndexStr);
|
||||
int totalChunks = Integer.parseInt(totalChunksStr);
|
||||
|
||||
System.out.println("청크 업로드: " + sessionId + " [" + (chunkIndex + 1) + "/" + totalChunks + "]");
|
||||
System.out.println("청크 크기: " + chunk.length() + " bytes");
|
||||
|
||||
// 임시 디렉토리에 청크 저장
|
||||
String tempDir = System.getProperty("java.io.tmpdir");
|
||||
String chunkDir = tempDir + File.separator + "pdf_chunks" + File.separator + sessionId;
|
||||
File chunkDirFile = new File(chunkDir);
|
||||
if(!chunkDirFile.exists()) {
|
||||
chunkDirFile.mkdirs();
|
||||
}
|
||||
|
||||
// 청크 파일 저장
|
||||
String chunkFileName = "chunk_" + chunkIndex + ".txt";
|
||||
File chunkFile = new File(chunkDir + File.separator + chunkFileName);
|
||||
java.io.FileWriter fw = new java.io.FileWriter(chunkFile);
|
||||
fw.write(chunk);
|
||||
fw.close();
|
||||
|
||||
// 마지막 청크인 경우 모든 청크를 합쳐서 PDF 파일 생성
|
||||
if(chunkIndex == totalChunks - 1) {
|
||||
System.out.println("모든 청크 수신 완료, PDF 파일 생성 시작");
|
||||
|
||||
// 모든 청크 읽어서 합치기
|
||||
StringBuilder fullBase64 = new StringBuilder();
|
||||
for(int i = 0; i < totalChunks; i++) {
|
||||
File cf = new File(chunkDir + File.separator + "chunk_" + i + ".txt");
|
||||
java.io.BufferedReader br = new java.io.BufferedReader(new java.io.FileReader(cf));
|
||||
String line;
|
||||
while((line = br.readLine()) != null) {
|
||||
fullBase64.append(line);
|
||||
}
|
||||
br.close();
|
||||
}
|
||||
|
||||
// Base64 디코딩하여 PDF 파일 생성 (Apache Commons Codec 사용)
|
||||
byte[] pdfBytes = org.apache.commons.codec.binary.Base64.decodeBase64(fullBase64.toString());
|
||||
|
||||
String pdfFileName = sessionId + ".pdf";
|
||||
File pdfFile = new File(tempDir + File.separator + pdfFileName);
|
||||
java.io.FileOutputStream fos = new java.io.FileOutputStream(pdfFile);
|
||||
fos.write(pdfBytes);
|
||||
fos.close();
|
||||
|
||||
pdfFile.deleteOnExit();
|
||||
|
||||
System.out.println("PDF 파일 생성 완료: " + pdfFile.getAbsolutePath());
|
||||
|
||||
// 청크 파일들 삭제
|
||||
for(int i = 0; i < totalChunks; i++) {
|
||||
File cf = new File(chunkDir + File.separator + "chunk_" + i + ".txt");
|
||||
cf.delete();
|
||||
}
|
||||
chunkDirFile.delete();
|
||||
}
|
||||
|
||||
resultMap.put("result", "success");
|
||||
|
||||
} catch(Exception e) {
|
||||
System.out.println("청크 업로드 중 오류: " + e.getMessage());
|
||||
e.printStackTrace();
|
||||
resultMap.put("result", "error");
|
||||
resultMap.put("message", e.getMessage());
|
||||
}
|
||||
|
||||
return resultMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* 세션 ID로 저장된 PDF 파일 가져오기
|
||||
* @param sessionId
|
||||
* @param estimateTemplate
|
||||
* @return
|
||||
*/
|
||||
private File getPdfFromSession(String sessionId, Map estimateTemplate) {
|
||||
try {
|
||||
String tempDir = System.getProperty("java.io.tmpdir");
|
||||
File pdfFile = new File(tempDir + File.separator + sessionId + ".pdf");
|
||||
|
||||
if(pdfFile.exists()) {
|
||||
// 견적번호로 파일명 변경
|
||||
String estimateNo = CommonUtils.checkNull(estimateTemplate.get("estimate_no"));
|
||||
if("".equals(estimateNo)) estimateNo = CommonUtils.checkNull(estimateTemplate.get("ESTIMATE_NO"));
|
||||
if("".equals(estimateNo)) estimateNo = "견적서";
|
||||
|
||||
java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyyMMddHHmmss");
|
||||
String timestamp = sdf.format(new java.util.Date());
|
||||
String newFileName = estimateNo + "_" + timestamp + ".pdf";
|
||||
File renamedFile = new File(tempDir + File.separator + newFileName);
|
||||
|
||||
// 파일 복사
|
||||
java.nio.file.Files.copy(pdfFile.toPath(), renamedFile.toPath(),
|
||||
java.nio.file.StandardCopyOption.REPLACE_EXISTING);
|
||||
|
||||
renamedFile.deleteOnExit();
|
||||
|
||||
// 원본 파일 삭제
|
||||
pdfFile.delete();
|
||||
|
||||
return renamedFile;
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
} catch(Exception e) {
|
||||
System.out.println("PDF 파일 가져오기 중 오류: " + e.getMessage());
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user