메일작성 변경
This commit is contained in:
@@ -190,19 +190,8 @@ $(document).ready(function(){
|
||||
return false;
|
||||
}
|
||||
|
||||
// 메일 발송 확인
|
||||
Swal.fire({
|
||||
title: '견적서 메일 발송',
|
||||
text: "최종 차수의 견적서를 발송하시겠습니까?",
|
||||
icon: 'question',
|
||||
showCancelButton: true,
|
||||
confirmButtonText: '발송',
|
||||
cancelButtonText: '취소'
|
||||
}).then((result) => {
|
||||
if(result.isConfirmed){
|
||||
fn_sendEstimateMail(objId);
|
||||
}
|
||||
});
|
||||
// 메일 작성 팝업 열기
|
||||
fn_openMailFormPopup(objId);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -683,309 +672,42 @@ function fn_showSerialNoPopup(serialNoString){
|
||||
});
|
||||
}
|
||||
|
||||
// 견적서 메일 발송
|
||||
function fn_sendEstimateMail(contractObjId){
|
||||
// 메일 작성 팝업 열기
|
||||
function fn_openMailFormPopup(contractObjId){
|
||||
if(!contractObjId || contractObjId === ''){
|
||||
Swal.fire("잘못된 요청입니다.");
|
||||
return;
|
||||
}
|
||||
|
||||
// 1단계: 견적서 템플릿 정보 조회
|
||||
Swal.fire({
|
||||
title: '견적서 조회 중...',
|
||||
text: '잠시만 기다려주세요.',
|
||||
allowOutsideClick: false,
|
||||
onOpen: () => {
|
||||
Swal.showLoading();
|
||||
}
|
||||
});
|
||||
var popup_width = 950;
|
||||
var popup_height = 800;
|
||||
var url = "/contractMgmt/estimateMailFormPopup.do?contractObjId=" + contractObjId;
|
||||
|
||||
$.ajax({
|
||||
url: "/contractMgmt/getEstimateTemplateList.do",
|
||||
type: "POST",
|
||||
data: { objId: contractObjId },
|
||||
dataType: "json",
|
||||
success: function(data){
|
||||
if(data.result === "success" && data.list && data.list.length > 0){
|
||||
// 최종 차수 견적서 찾기
|
||||
var latestEstimate = data.list[0]; // 이미 차수 내림차순으로 정렬되어 있음
|
||||
var templateObjId = latestEstimate.OBJID || latestEstimate.objid;
|
||||
var templateType = latestEstimate.TEMPLATE_TYPE || latestEstimate.template_type || latestEstimate.templateType;
|
||||
|
||||
// 2단계: 견적서 페이지를 새 창으로 열고 PDF 생성
|
||||
fn_generatePdfAndSendMail(contractObjId, templateObjId, templateType);
|
||||
} else {
|
||||
Swal.close();
|
||||
Swal.fire({
|
||||
title: '오류',
|
||||
text: '견적서를 찾을 수 없습니다.',
|
||||
icon: 'error'
|
||||
});
|
||||
}
|
||||
},
|
||||
error: function(xhr, status, error){
|
||||
Swal.close();
|
||||
console.error("견적서 조회 오류:", xhr, status, error);
|
||||
Swal.fire({
|
||||
title: '오류',
|
||||
text: '견적서 조회 중 오류가 발생했습니다.',
|
||||
icon: 'error'
|
||||
});
|
||||
}
|
||||
});
|
||||
window.open(url, "estimateMailForm", "width="+popup_width+",height="+popup_height+",menubar=no,scrollbars=yes,resizable=yes");
|
||||
}
|
||||
|
||||
// PDF 생성 및 메일 발송
|
||||
/*
|
||||
* 아래 함수들은 자동 메일 발송 기능을 위한 것입니다.
|
||||
* 현재는 메일 작성 팝업을 사용하므로 주석 처리합니다.
|
||||
* 필요시 참고용으로 남겨둡니다.
|
||||
*/
|
||||
|
||||
/*
|
||||
// PDF 생성 및 메일 발송 (자동)
|
||||
function fn_generatePdfAndSendMail(contractObjId, templateObjId, templateType){
|
||||
Swal.fire({
|
||||
title: 'PDF 생성 중...',
|
||||
text: '견적서를 PDF로 변환하고 있습니다.',
|
||||
allowOutsideClick: false,
|
||||
onOpen: () => {
|
||||
Swal.showLoading();
|
||||
}
|
||||
});
|
||||
|
||||
// 견적서 페이지 URL 생성
|
||||
var url = "";
|
||||
if(templateType === "1"){
|
||||
url = "/contractMgmt/estimateTemplate1.do?templateObjId=" + templateObjId;
|
||||
} else if(templateType === "2"){
|
||||
url = "/contractMgmt/estimateTemplate2.do?templateObjId=" + templateObjId;
|
||||
}
|
||||
|
||||
// 숨겨진 iframe으로 페이지 로드
|
||||
var iframe = $('<iframe>', {
|
||||
id: 'pdfGeneratorFrame',
|
||||
src: url,
|
||||
style: 'position:absolute;width:0;height:0;border:none;'
|
||||
}).appendTo('body');
|
||||
|
||||
// iframe 로드 완료 대기
|
||||
iframe.on('load', function(){
|
||||
try {
|
||||
var iframeWindow = this.contentWindow;
|
||||
|
||||
// 데이터 로딩 완료를 기다림 (최대 10초)
|
||||
var checkDataLoaded = function(attempts) {
|
||||
if(attempts > 100) { // 10초 (100ms * 100)
|
||||
$('#pdfGeneratorFrame').remove();
|
||||
Swal.close();
|
||||
Swal.fire({
|
||||
title: '타임아웃',
|
||||
text: '견적서 데이터 로딩 시간이 초과되었습니다.',
|
||||
icon: 'error'
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if(iframeWindow.dataLoaded === true) {
|
||||
console.log('데이터 로딩 완료 확인, PDF 생성 시작');
|
||||
|
||||
// iframe 내의 PDF 생성 함수 호출
|
||||
if(typeof iframeWindow.fn_generateAndUploadPdf === 'function'){
|
||||
iframeWindow.fn_generateAndUploadPdf(function(pdfBase64){
|
||||
// iframe 제거
|
||||
$('#pdfGeneratorFrame').remove();
|
||||
|
||||
if(pdfBase64){
|
||||
// PDF Base64와 함께 메일 발송 요청
|
||||
fn_sendMailWithPdf(contractObjId, pdfBase64);
|
||||
} else {
|
||||
Swal.close();
|
||||
Swal.fire({
|
||||
title: '오류',
|
||||
text: 'PDF 생성에 실패했습니다.',
|
||||
icon: 'error'
|
||||
});
|
||||
}
|
||||
});
|
||||
} else {
|
||||
// iframe 제거
|
||||
$('#pdfGeneratorFrame').remove();
|
||||
|
||||
Swal.close();
|
||||
Swal.fire({
|
||||
title: '오류',
|
||||
text: '견적서 페이지 로드에 실패했습니다.',
|
||||
icon: 'error'
|
||||
});
|
||||
}
|
||||
} else {
|
||||
// 아직 로딩 중이면 100ms 후 다시 확인
|
||||
setTimeout(function() {
|
||||
checkDataLoaded(attempts + 1);
|
||||
}, 100);
|
||||
}
|
||||
};
|
||||
|
||||
// 데이터 로딩 체크 시작
|
||||
checkDataLoaded(0);
|
||||
} catch(e) {
|
||||
console.error('PDF 생성 오류:', e);
|
||||
$('#pdfGeneratorFrame').remove();
|
||||
|
||||
Swal.close();
|
||||
Swal.fire({
|
||||
title: '오류',
|
||||
text: 'PDF 생성 중 오류가 발생했습니다.',
|
||||
icon: 'error'
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// 타임아웃 설정 (30초)
|
||||
setTimeout(function(){
|
||||
if($('#pdfGeneratorFrame').length > 0){
|
||||
$('#pdfGeneratorFrame').remove();
|
||||
Swal.close();
|
||||
Swal.fire({
|
||||
title: '타임아웃',
|
||||
text: 'PDF 생성 시간이 초과되었습니다.',
|
||||
icon: 'error'
|
||||
});
|
||||
}
|
||||
}, 30000);
|
||||
// ... (생략)
|
||||
}
|
||||
|
||||
// PDF Base64와 함께 메일 발송 (청크 방식)
|
||||
function fn_sendMailWithPdf(contractObjId, pdfBase64){
|
||||
console.log('===== 메일 발송 시작 =====');
|
||||
console.log('contractObjId:', contractObjId);
|
||||
console.log('PDF Base64 길이:', pdfBase64 ? pdfBase64.length : 0);
|
||||
console.log('========================');
|
||||
|
||||
Swal.fire({
|
||||
title: '메일 발송 중...',
|
||||
text: 'PDF 업로드 중...',
|
||||
allowOutsideClick: false,
|
||||
onOpen: () => {
|
||||
Swal.showLoading();
|
||||
}
|
||||
});
|
||||
|
||||
// 청크 크기: 100KB (Base64) - POST 크기 제한 고려
|
||||
var chunkSize = 100 * 1024;
|
||||
var totalChunks = Math.ceil(pdfBase64.length / chunkSize);
|
||||
var uploadedChunks = 0;
|
||||
var sessionId = 'pdf_' + contractObjId + '_' + new Date().getTime();
|
||||
|
||||
console.log('PDF Base64 전체 길이:', pdfBase64.length);
|
||||
console.log('청크 크기:', chunkSize);
|
||||
console.log('총 청크 수:', totalChunks);
|
||||
|
||||
// 청크 업로드 함수
|
||||
function uploadChunk(chunkIndex) {
|
||||
var start = chunkIndex * chunkSize;
|
||||
var end = Math.min(start + chunkSize, pdfBase64.length);
|
||||
var chunk = pdfBase64.substring(start, end);
|
||||
|
||||
console.log('청크 ' + (chunkIndex + 1) + '/' + totalChunks + ' 업로드 중...');
|
||||
|
||||
$.ajax({
|
||||
url: "/contractMgmt/uploadPdfChunk.do",
|
||||
type: "POST",
|
||||
data: {
|
||||
sessionId: sessionId,
|
||||
chunkIndex: chunkIndex,
|
||||
totalChunks: totalChunks,
|
||||
chunk: chunk
|
||||
},
|
||||
dataType: "json",
|
||||
timeout: 30000,
|
||||
success: function(data){
|
||||
if(data.result === "success"){
|
||||
uploadedChunks++;
|
||||
|
||||
// 진행률 업데이트
|
||||
var progress = Math.round((uploadedChunks / totalChunks) * 100);
|
||||
Swal.update({
|
||||
text: 'PDF 업로드 중... ' + progress + '%'
|
||||
});
|
||||
|
||||
// 다음 청크 업로드
|
||||
if(chunkIndex + 1 < totalChunks){
|
||||
uploadChunk(chunkIndex + 1);
|
||||
} else {
|
||||
// 모든 청크 업로드 완료, 메일 발송 요청
|
||||
console.log('모든 청크 업로드 완료, 메일 발송 시작');
|
||||
sendMailWithUploadedPdf(contractObjId, sessionId);
|
||||
}
|
||||
} else {
|
||||
Swal.close();
|
||||
Swal.fire({
|
||||
title: '업로드 실패',
|
||||
text: 'PDF 업로드 중 오류가 발생했습니다.',
|
||||
icon: 'error',
|
||||
confirmButtonText: '확인'
|
||||
});
|
||||
}
|
||||
},
|
||||
error: function(xhr, status, error){
|
||||
Swal.close();
|
||||
console.error("청크 업로드 오류:", xhr, status, error);
|
||||
Swal.fire({
|
||||
title: '오류',
|
||||
text: 'PDF 업로드 중 시스템 오류가 발생했습니다.',
|
||||
icon: 'error',
|
||||
confirmButtonText: '확인'
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 첫 번째 청크부터 시작
|
||||
uploadChunk(0);
|
||||
// ... (생략)
|
||||
}
|
||||
|
||||
// 업로드된 PDF로 메일 발송
|
||||
function sendMailWithUploadedPdf(contractObjId, sessionId){
|
||||
Swal.update({
|
||||
text: '메일 발송 중...'
|
||||
});
|
||||
|
||||
$.ajax({
|
||||
url: "/contractMgmt/sendEstimateMail.do",
|
||||
type: "POST",
|
||||
data: {
|
||||
objId: contractObjId,
|
||||
pdfSessionId: sessionId
|
||||
},
|
||||
dataType: "json",
|
||||
timeout: 60000,
|
||||
success: function(data){
|
||||
console.log('메일 발송 응답:', data);
|
||||
Swal.close();
|
||||
if(data.result === "success"){
|
||||
Swal.fire({
|
||||
title: '발송 완료',
|
||||
text: '견적서가 성공적으로 발송되었습니다.',
|
||||
icon: 'success',
|
||||
confirmButtonText: '확인'
|
||||
}).then(() => {
|
||||
fn_search();
|
||||
});
|
||||
} else {
|
||||
Swal.fire({
|
||||
title: '발송 실패',
|
||||
text: data.message || '견적서 발송 중 오류가 발생했습니다.',
|
||||
icon: 'error',
|
||||
confirmButtonText: '확인'
|
||||
});
|
||||
}
|
||||
},
|
||||
error: function(xhr, status, error){
|
||||
Swal.close();
|
||||
console.error("메일 발송 오류:", xhr, status, error);
|
||||
Swal.fire({
|
||||
title: '오류',
|
||||
text: '메일 발송 중 시스템 오류가 발생했습니다.',
|
||||
icon: 'error',
|
||||
confirmButtonText: '확인'
|
||||
});
|
||||
}
|
||||
});
|
||||
// ... (생략)
|
||||
}
|
||||
*/
|
||||
|
||||
//코드값을 받아와서 동적으로 selectbox 생성
|
||||
function optionJobGroup(code){
|
||||
|
||||
652
WebContent/WEB-INF/view/contractMgmt/estimateMailFormPopup.jsp
Normal file
652
WebContent/WEB-INF/view/contractMgmt/estimateMailFormPopup.jsp
Normal file
@@ -0,0 +1,652 @@
|
||||
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
|
||||
<%@ page import="com.pms.common.utils.*"%>
|
||||
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>
|
||||
<%@ page import="java.util.*" %>
|
||||
<%@include file= "/init.jsp" %>
|
||||
<%
|
||||
PersonBean person = (PersonBean)session.getAttribute(Constants.PERSON_BEAN);
|
||||
String connector = person.getUserId();
|
||||
String contractObjId = request.getParameter("contractObjId");
|
||||
%>
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<title>견적서 메일 발송</title>
|
||||
<style>
|
||||
body {
|
||||
font-family: 'Malgun Gothic', sans-serif;
|
||||
margin: 20px;
|
||||
background-color: #f5f5f5;
|
||||
}
|
||||
.mail-form-container {
|
||||
background: white;
|
||||
padding: 30px;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
|
||||
max-width: 900px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
.form-title {
|
||||
font-size: 24px;
|
||||
font-weight: bold;
|
||||
margin-bottom: 30px;
|
||||
color: #333;
|
||||
border-bottom: 2px solid #3085d6;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
.form-group {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.form-group label {
|
||||
display: block;
|
||||
font-weight: bold;
|
||||
margin-bottom: 8px;
|
||||
color: #555;
|
||||
}
|
||||
.form-group label.required:after {
|
||||
content: " *";
|
||||
color: red;
|
||||
}
|
||||
.form-group input[type="text"],
|
||||
.form-group input[type="email"],
|
||||
.form-group textarea {
|
||||
width: 100%;
|
||||
padding: 10px;
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 4px;
|
||||
font-size: 14px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.form-group textarea {
|
||||
min-height: 200px;
|
||||
resize: vertical;
|
||||
}
|
||||
.manager-list {
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 4px;
|
||||
padding: 15px;
|
||||
background-color: #fafafa;
|
||||
max-height: 200px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
.manager-item {
|
||||
padding: 8px;
|
||||
margin-bottom: 5px;
|
||||
background: white;
|
||||
border-radius: 4px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
.manager-item input[type="checkbox"] {
|
||||
margin-right: 10px;
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.manager-item label {
|
||||
cursor: pointer;
|
||||
margin: 0;
|
||||
flex: 1;
|
||||
}
|
||||
.no-managers {
|
||||
color: #999;
|
||||
text-align: center;
|
||||
padding: 20px;
|
||||
}
|
||||
.button-group {
|
||||
text-align: center;
|
||||
margin-top: 30px;
|
||||
padding-top: 20px;
|
||||
border-top: 1px solid #eee;
|
||||
}
|
||||
.btn {
|
||||
padding: 12px 30px;
|
||||
margin: 0 5px;
|
||||
border: none;
|
||||
border-radius: 4px;
|
||||
font-size: 16px;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s;
|
||||
}
|
||||
.btn-primary {
|
||||
background-color: #3085d6;
|
||||
color: white;
|
||||
}
|
||||
.btn-primary:hover {
|
||||
background-color: #2874c5;
|
||||
}
|
||||
.btn-secondary {
|
||||
background-color: #6c757d;
|
||||
color: white;
|
||||
}
|
||||
.btn-secondary:hover {
|
||||
background-color: #5a6268;
|
||||
}
|
||||
.info-text {
|
||||
font-size: 12px;
|
||||
color: #666;
|
||||
margin-top: 5px;
|
||||
}
|
||||
.pdf-status {
|
||||
padding: 10px;
|
||||
background-color: #e7f3ff;
|
||||
border-left: 4px solid #3085d6;
|
||||
border-radius: 4px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.pdf-status i {
|
||||
color: #3085d6;
|
||||
margin-right: 5px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="mail-form-container">
|
||||
<div class="form-title">견적서 메일 발송</div>
|
||||
|
||||
<div class="pdf-status">
|
||||
<i class="fa fa-file-pdf-o"></i>
|
||||
<strong>PDF 첨부:</strong> 최종 차수 견적서가 자동으로 첨부됩니다.
|
||||
</div>
|
||||
|
||||
<form id="mailForm">
|
||||
<input type="hidden" id="contractObjId" name="contractObjId" value="<%=contractObjId%>"/>
|
||||
<input type="hidden" id="pdfSessionId" name="pdfSessionId" value=""/>
|
||||
|
||||
<!-- 고객사 담당자 선택 -->
|
||||
<div class="form-group">
|
||||
<label>고객사 담당자 선택</label>
|
||||
<div id="managerListContainer" class="manager-list">
|
||||
<div class="no-managers">담당자 정보를 불러오는 중...</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 수신인 이메일 -->
|
||||
<div class="form-group">
|
||||
<label for="toEmails" class="required">수신인 (To)</label>
|
||||
<input type="text" id="toEmails" name="toEmails" placeholder="이메일 주소를 입력하세요 (여러 개는 쉼표로 구분)"/>
|
||||
<div class="info-text">예: email1@example.com, email2@example.com</div>
|
||||
</div>
|
||||
|
||||
<!-- 참조 이메일 -->
|
||||
<div class="form-group">
|
||||
<label for="ccEmails">참조 (CC)</label>
|
||||
<input type="text" id="ccEmails" name="ccEmails" placeholder="참조 이메일 주소 (선택사항)"/>
|
||||
<div class="info-text">작성자 이메일이 자동으로 참조에 추가됩니다.</div>
|
||||
</div>
|
||||
|
||||
<!-- 메일 제목 -->
|
||||
<div class="form-group">
|
||||
<label for="subject" class="required">제목</label>
|
||||
<input type="text" id="subject" name="subject" placeholder="메일 제목을 입력하세요"/>
|
||||
</div>
|
||||
|
||||
<!-- 메일 내용 -->
|
||||
<div class="form-group">
|
||||
<label for="contents" class="required">내용</label>
|
||||
<textarea id="contents" name="contents" placeholder="메일 내용을 입력하세요"></textarea>
|
||||
</div>
|
||||
|
||||
<!-- 버튼 -->
|
||||
<div class="button-group">
|
||||
<button type="button" class="btn btn-primary" onclick="fn_sendMail()">발송</button>
|
||||
<button type="button" class="btn btn-secondary" onclick="window.close()">취소</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
var contractInfo = null;
|
||||
var managerList = [];
|
||||
|
||||
$(document).ready(function(){
|
||||
// 계약 정보 및 담당자 목록 로드
|
||||
fn_loadContractInfo();
|
||||
});
|
||||
|
||||
// 계약 정보 로드
|
||||
function fn_loadContractInfo(){
|
||||
var contractObjId = $("#contractObjId").val();
|
||||
|
||||
$.ajax({
|
||||
url: "/contractMgmt/getContractInfoForMail.do",
|
||||
type: "POST",
|
||||
data: { objId: contractObjId },
|
||||
dataType: "json",
|
||||
success: function(data){
|
||||
if(data.result === "success" && data.contractInfo){
|
||||
contractInfo = data.contractInfo;
|
||||
|
||||
// 메일 제목 자동 생성
|
||||
var contractNo = fnc_checkNull(contractInfo.CONTRACT_NO);
|
||||
var customerName = fnc_checkNull(contractInfo.CUSTOMER_NAME);
|
||||
$("#subject").val("[" + customerName + "] " + contractNo + " 견적서");
|
||||
|
||||
// 메일 내용 템플릿 생성
|
||||
fn_generateMailTemplate();
|
||||
|
||||
// 고객사 담당자 목록 로드
|
||||
var customerObjId = fnc_checkNull(contractInfo.CUSTOMER_OBJID);
|
||||
if(customerObjId !== ""){
|
||||
fn_loadCustomerManagers(customerObjId);
|
||||
} else {
|
||||
$("#managerListContainer").html('<div class="no-managers">고객사 정보가 없습니다.</div>');
|
||||
}
|
||||
} else {
|
||||
Swal.fire({
|
||||
title: '오류',
|
||||
text: '계약 정보를 불러올 수 없습니다.',
|
||||
icon: 'error'
|
||||
}).then(() => {
|
||||
window.close();
|
||||
});
|
||||
}
|
||||
},
|
||||
error: function(){
|
||||
Swal.fire({
|
||||
title: '오류',
|
||||
text: '계약 정보 조회 중 오류가 발생했습니다.',
|
||||
icon: 'error'
|
||||
}).then(() => {
|
||||
window.close();
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 고객사 담당자 목록 로드
|
||||
function fn_loadCustomerManagers(customerObjId){
|
||||
$.ajax({
|
||||
url: "/contractMgmt/getCustomerManagerList.do",
|
||||
type: "POST",
|
||||
data: { customerObjId: customerObjId },
|
||||
dataType: "json",
|
||||
success: function(data){
|
||||
if(data.result === "success" && data.managers && data.managers.length > 0){
|
||||
managerList = data.managers;
|
||||
fn_renderManagerList();
|
||||
} else {
|
||||
$("#managerListContainer").html('<div class="no-managers">등록된 담당자가 없습니다. 수신인을 직접 입력해주세요.</div>');
|
||||
}
|
||||
},
|
||||
error: function(){
|
||||
$("#managerListContainer").html('<div class="no-managers">담당자 정보를 불러올 수 없습니다. 수신인을 직접 입력해주세요.</div>');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 담당자 목록 렌더링
|
||||
function fn_renderManagerList(){
|
||||
var html = '';
|
||||
|
||||
for(var i = 0; i < managerList.length; i++){
|
||||
var manager = managerList[i];
|
||||
var name = fnc_checkNull(manager.name);
|
||||
var email = fnc_checkNull(manager.email);
|
||||
|
||||
if(name !== ""){
|
||||
html += '<div class="manager-item">';
|
||||
html += '<input type="checkbox" id="manager_' + i + '" data-email="' + email + '" onchange="fn_updateRecipients()">';
|
||||
html += '<label for="manager_' + i + '">' + name;
|
||||
if(email !== ""){
|
||||
html += ' (' + email + ')';
|
||||
}
|
||||
html += '</label>';
|
||||
html += '</div>';
|
||||
}
|
||||
}
|
||||
|
||||
if(html === ''){
|
||||
html = '<div class="no-managers">등록된 담당자가 없습니다. 수신인을 직접 입력해주세요.</div>';
|
||||
}
|
||||
|
||||
$("#managerListContainer").html(html);
|
||||
}
|
||||
|
||||
// 담당자 선택 시 수신인 필드 업데이트
|
||||
function fn_updateRecipients(){
|
||||
var selectedEmails = [];
|
||||
|
||||
$("input[type='checkbox'][id^='manager_']:checked").each(function(){
|
||||
var email = $(this).attr("data-email");
|
||||
if(email && email !== ""){
|
||||
selectedEmails.push(email);
|
||||
}
|
||||
});
|
||||
|
||||
$("#toEmails").val(selectedEmails.join(", "));
|
||||
}
|
||||
|
||||
// 메일 내용 템플릿 생성
|
||||
function fn_generateMailTemplate(){
|
||||
var customerName = fnc_checkNull(contractInfo.CUSTOMER_NAME);
|
||||
var contractNo = fnc_checkNull(contractInfo.CONTRACT_NO);
|
||||
|
||||
var template = "안녕하세요.\n\n";
|
||||
template += customerName + " 귀하께서 요청하신 견적서를 첨부파일로 송부드립니다.\n\n";
|
||||
template += "영업번호: " + contractNo + "\n\n";
|
||||
template += "첨부된 견적서를 검토하신 후 문의사항이 있으시면 연락 주시기 바랍니다.\n\n";
|
||||
template += "감사합니다.\n";
|
||||
|
||||
$("#contents").val(template);
|
||||
}
|
||||
|
||||
// 메일 발송
|
||||
function fn_sendMail(){
|
||||
// 입력값 검증
|
||||
var toEmails = $("#toEmails").val().trim();
|
||||
var subject = $("#subject").val().trim();
|
||||
var contents = $("#contents").val().trim();
|
||||
|
||||
if(toEmails === ""){
|
||||
Swal.fire("수신인을 입력해주세요.");
|
||||
$("#toEmails").focus();
|
||||
return;
|
||||
}
|
||||
|
||||
// 이메일 형식 검증
|
||||
var emailPattern = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
||||
var emails = toEmails.split(",").map(function(e){ return e.trim(); });
|
||||
for(var i = 0; i < emails.length; i++){
|
||||
if(!emailPattern.test(emails[i])){
|
||||
Swal.fire("올바른 이메일 형식이 아닙니다: " + emails[i]);
|
||||
$("#toEmails").focus();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if(subject === ""){
|
||||
Swal.fire("제목을 입력해주세요.");
|
||||
$("#subject").focus();
|
||||
return;
|
||||
}
|
||||
|
||||
if(contents === ""){
|
||||
Swal.fire("내용을 입력해주세요.");
|
||||
$("#contents").focus();
|
||||
return;
|
||||
}
|
||||
|
||||
// 발송 확인
|
||||
Swal.fire({
|
||||
title: '메일 발송',
|
||||
text: "견적서를 발송하시겠습니까?",
|
||||
icon: 'question',
|
||||
showCancelButton: true,
|
||||
confirmButtonText: '발송',
|
||||
cancelButtonText: '취소'
|
||||
}).then((result) => {
|
||||
if(result.isConfirmed){
|
||||
// PDF 생성 및 발송 시작
|
||||
fn_generatePdfAndSend();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// PDF 생성 및 발송
|
||||
function fn_generatePdfAndSend(){
|
||||
var contractObjId = $("#contractObjId").val();
|
||||
|
||||
Swal.fire({
|
||||
title: 'PDF 생성 중...',
|
||||
text: '견적서를 PDF로 변환하고 있습니다.',
|
||||
allowOutsideClick: false,
|
||||
onOpen: () => {
|
||||
Swal.showLoading();
|
||||
}
|
||||
});
|
||||
|
||||
// 1. 최종 차수 견적서 정보 조회
|
||||
$.ajax({
|
||||
url: "/contractMgmt/getEstimateTemplateList.do",
|
||||
type: "POST",
|
||||
data: { objId: contractObjId },
|
||||
dataType: "json",
|
||||
success: function(data){
|
||||
if(data.result === "success" && data.list && data.list.length > 0){
|
||||
var latestEstimate = data.list[0];
|
||||
var templateObjId = latestEstimate.OBJID || latestEstimate.objid;
|
||||
var templateType = latestEstimate.TEMPLATE_TYPE || latestEstimate.template_type || latestEstimate.templateType;
|
||||
|
||||
// 2. PDF 생성
|
||||
fn_generatePdf(contractObjId, templateObjId, templateType);
|
||||
} else {
|
||||
Swal.close();
|
||||
Swal.fire({
|
||||
title: '오류',
|
||||
text: '견적서를 찾을 수 없습니다.',
|
||||
icon: 'error'
|
||||
});
|
||||
}
|
||||
},
|
||||
error: function(){
|
||||
Swal.close();
|
||||
Swal.fire({
|
||||
title: '오류',
|
||||
text: '견적서 조회 중 오류가 발생했습니다.',
|
||||
icon: 'error'
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// PDF 생성
|
||||
function fn_generatePdf(contractObjId, templateObjId, templateType){
|
||||
var url = "";
|
||||
if(templateType === "1"){
|
||||
url = "/contractMgmt/estimateTemplate1.do?templateObjId=" + templateObjId;
|
||||
} else if(templateType === "2"){
|
||||
url = "/contractMgmt/estimateTemplate2.do?templateObjId=" + templateObjId;
|
||||
}
|
||||
|
||||
// 숨겨진 iframe으로 페이지 로드
|
||||
var iframe = $('<iframe>', {
|
||||
id: 'pdfGeneratorFrame',
|
||||
src: url,
|
||||
style: 'position:absolute;width:0;height:0;border:none;'
|
||||
}).appendTo('body');
|
||||
|
||||
// iframe 로드 완료 대기
|
||||
iframe.on('load', function(){
|
||||
try {
|
||||
var iframeWindow = this.contentWindow;
|
||||
|
||||
// 데이터 로딩 완료 대기
|
||||
var checkDataLoaded = function(attempts) {
|
||||
if(attempts > 100) {
|
||||
$('#pdfGeneratorFrame').remove();
|
||||
Swal.close();
|
||||
Swal.fire({
|
||||
title: '타임아웃',
|
||||
text: '견적서 데이터 로딩 시간이 초과되었습니다.',
|
||||
icon: 'error'
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if(iframeWindow.dataLoaded === true) {
|
||||
// PDF 생성 함수 호출
|
||||
if(typeof iframeWindow.fn_generateAndUploadPdf === 'function'){
|
||||
iframeWindow.fn_generateAndUploadPdf(function(pdfBase64){
|
||||
$('#pdfGeneratorFrame').remove();
|
||||
|
||||
if(pdfBase64){
|
||||
// PDF 업로드 후 메일 발송
|
||||
fn_uploadPdfAndSendMail(contractObjId, pdfBase64);
|
||||
} else {
|
||||
Swal.close();
|
||||
Swal.fire({
|
||||
title: '오류',
|
||||
text: 'PDF 생성에 실패했습니다.',
|
||||
icon: 'error'
|
||||
});
|
||||
}
|
||||
});
|
||||
} else {
|
||||
$('#pdfGeneratorFrame').remove();
|
||||
Swal.close();
|
||||
Swal.fire({
|
||||
title: '오류',
|
||||
text: '견적서 페이지 로드에 실패했습니다.',
|
||||
icon: 'error'
|
||||
});
|
||||
}
|
||||
} else {
|
||||
setTimeout(function() {
|
||||
checkDataLoaded(attempts + 1);
|
||||
}, 100);
|
||||
}
|
||||
};
|
||||
|
||||
checkDataLoaded(0);
|
||||
} catch(e) {
|
||||
console.error('PDF 생성 오류:', e);
|
||||
$('#pdfGeneratorFrame').remove();
|
||||
Swal.close();
|
||||
Swal.fire({
|
||||
title: '오류',
|
||||
text: 'PDF 생성 중 오류가 발생했습니다.',
|
||||
icon: 'error'
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// 타임아웃 설정 (30초)
|
||||
setTimeout(function(){
|
||||
if($('#pdfGeneratorFrame').length > 0){
|
||||
$('#pdfGeneratorFrame').remove();
|
||||
Swal.close();
|
||||
Swal.fire({
|
||||
title: '타임아웃',
|
||||
text: 'PDF 생성 시간이 초과되었습니다.',
|
||||
icon: 'error'
|
||||
});
|
||||
}
|
||||
}, 30000);
|
||||
}
|
||||
|
||||
// PDF 업로드 및 메일 발송
|
||||
function fn_uploadPdfAndSendMail(contractObjId, pdfBase64){
|
||||
Swal.update({
|
||||
text: 'PDF 업로드 중...'
|
||||
});
|
||||
|
||||
// 청크 업로드 (기존 로직 활용)
|
||||
var chunkSize = 100 * 1024;
|
||||
var totalChunks = Math.ceil(pdfBase64.length / chunkSize);
|
||||
var uploadedChunks = 0;
|
||||
var sessionId = 'pdf_' + contractObjId + '_' + new Date().getTime();
|
||||
|
||||
function uploadChunk(chunkIndex) {
|
||||
var start = chunkIndex * chunkSize;
|
||||
var end = Math.min(start + chunkSize, pdfBase64.length);
|
||||
var chunk = pdfBase64.substring(start, end);
|
||||
|
||||
$.ajax({
|
||||
url: "/contractMgmt/uploadPdfChunk.do",
|
||||
type: "POST",
|
||||
data: {
|
||||
sessionId: sessionId,
|
||||
chunkIndex: chunkIndex,
|
||||
totalChunks: totalChunks,
|
||||
chunk: chunk
|
||||
},
|
||||
dataType: "json",
|
||||
timeout: 30000,
|
||||
success: function(data){
|
||||
if(data.result === "success"){
|
||||
uploadedChunks++;
|
||||
|
||||
var progress = Math.round((uploadedChunks / totalChunks) * 100);
|
||||
Swal.update({
|
||||
text: 'PDF 업로드 중... ' + progress + '%'
|
||||
});
|
||||
|
||||
if(chunkIndex + 1 < totalChunks){
|
||||
uploadChunk(chunkIndex + 1);
|
||||
} else {
|
||||
// 모든 청크 업로드 완료, 메일 발송
|
||||
$("#pdfSessionId").val(sessionId);
|
||||
fn_submitMailForm();
|
||||
}
|
||||
} else {
|
||||
Swal.close();
|
||||
Swal.fire({
|
||||
title: '업로드 실패',
|
||||
text: 'PDF 업로드 중 오류가 발생했습니다.',
|
||||
icon: 'error'
|
||||
});
|
||||
}
|
||||
},
|
||||
error: function(){
|
||||
Swal.close();
|
||||
Swal.fire({
|
||||
title: '오류',
|
||||
text: 'PDF 업로드 중 시스템 오류가 발생했습니다.',
|
||||
icon: 'error'
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
uploadChunk(0);
|
||||
}
|
||||
|
||||
// 메일 발송 요청
|
||||
function fn_submitMailForm(){
|
||||
Swal.update({
|
||||
text: '메일 발송 중...'
|
||||
});
|
||||
|
||||
var formData = {
|
||||
objId: $("#contractObjId").val(),
|
||||
pdfSessionId: $("#pdfSessionId").val(),
|
||||
toEmails: $("#toEmails").val(),
|
||||
ccEmails: $("#ccEmails").val(),
|
||||
subject: $("#subject").val(),
|
||||
contents: $("#contents").val()
|
||||
};
|
||||
|
||||
$.ajax({
|
||||
url: "/contractMgmt/sendEstimateMailCustom.do",
|
||||
type: "POST",
|
||||
data: formData,
|
||||
dataType: "json",
|
||||
timeout: 60000,
|
||||
success: function(data){
|
||||
Swal.close();
|
||||
if(data.result === "success"){
|
||||
Swal.fire({
|
||||
title: '발송 완료',
|
||||
text: '견적서가 성공적으로 발송되었습니다.',
|
||||
icon: 'success'
|
||||
}).then(() => {
|
||||
// 부모 창 새로고침
|
||||
if(window.opener && typeof window.opener.fn_search === 'function'){
|
||||
window.opener.fn_search();
|
||||
}
|
||||
window.close();
|
||||
});
|
||||
} else {
|
||||
Swal.fire({
|
||||
title: '발송 실패',
|
||||
text: data.message || '메일 발송 중 오류가 발생했습니다.',
|
||||
icon: 'error'
|
||||
});
|
||||
}
|
||||
},
|
||||
error: function(){
|
||||
Swal.close();
|
||||
Swal.fire({
|
||||
title: '오류',
|
||||
text: '메일 발송 중 시스템 오류가 발생했습니다.',
|
||||
icon: 'error'
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -2125,6 +2125,115 @@ public class ContractMgmtController {
|
||||
|
||||
return resultMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* 견적서 메일 작성 팝업
|
||||
* @param request
|
||||
* @param paramMap - contractObjId
|
||||
* @return
|
||||
*/
|
||||
@RequestMapping("/contractMgmt/estimateMailFormPopup.do")
|
||||
public String estimateMailFormPopup(HttpServletRequest request, @RequestParam Map paramMap){
|
||||
return "/contractMgmt/estimateMailFormPopup";
|
||||
}
|
||||
|
||||
/**
|
||||
* 계약 정보 조회 (메일 발송용) (AJAX)
|
||||
* @param request
|
||||
* @param paramMap - objId (CONTRACT_OBJID)
|
||||
* @return
|
||||
*/
|
||||
@ResponseBody
|
||||
@RequestMapping(value="/contractMgmt/getContractInfoForMail.do", method=RequestMethod.POST)
|
||||
public Map getContractInfoForMail(HttpServletRequest request, @RequestParam Map<String, Object> paramMap){
|
||||
Map resultMap = new HashMap();
|
||||
|
||||
try {
|
||||
String objId = CommonUtils.checkNull(paramMap.get("objId"));
|
||||
|
||||
if("".equals(objId)){
|
||||
resultMap.put("result", "error");
|
||||
resultMap.put("message", "계약 OBJID가 없습니다.");
|
||||
return resultMap;
|
||||
}
|
||||
|
||||
// 계약 정보 조회
|
||||
Map contractInfo = contractMgmtService.getContractInfoForMail(paramMap);
|
||||
|
||||
if(contractInfo != null && !contractInfo.isEmpty()){
|
||||
// Map 키를 대문자로 변환
|
||||
contractInfo = CommonUtils.toUpperCaseMapKey(contractInfo);
|
||||
|
||||
resultMap.put("result", "success");
|
||||
resultMap.put("contractInfo", contractInfo);
|
||||
} else {
|
||||
resultMap.put("result", "error");
|
||||
resultMap.put("message", "계약 정보를 찾을 수 없습니다.");
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
resultMap.put("result", "error");
|
||||
resultMap.put("message", "계약 정보 조회 중 오류가 발생했습니다: " + e.getMessage());
|
||||
}
|
||||
|
||||
return resultMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* 견적서 메일 발송 (커스텀) (AJAX)
|
||||
* @param request
|
||||
* @param paramMap - objId, pdfSessionId, toEmails, ccEmails, subject, contents
|
||||
* @return
|
||||
*/
|
||||
@ResponseBody
|
||||
@RequestMapping(value="/contractMgmt/sendEstimateMailCustom.do", method=RequestMethod.POST)
|
||||
public Map sendEstimateMailCustom(HttpServletRequest request,
|
||||
@RequestParam Map<String, Object> paramMap){
|
||||
Map resultMap = new HashMap();
|
||||
|
||||
try {
|
||||
String objId = CommonUtils.checkNull(paramMap.get("objId"));
|
||||
String toEmails = CommonUtils.checkNull(paramMap.get("toEmails"));
|
||||
String subject = CommonUtils.checkNull(paramMap.get("subject"));
|
||||
String contents = CommonUtils.checkNull(paramMap.get("contents"));
|
||||
|
||||
// 필수 파라미터 검증
|
||||
if("".equals(objId)){
|
||||
resultMap.put("result", "error");
|
||||
resultMap.put("message", "계약 OBJID가 없습니다.");
|
||||
return resultMap;
|
||||
}
|
||||
|
||||
if("".equals(toEmails)){
|
||||
resultMap.put("result", "error");
|
||||
resultMap.put("message", "수신인이 없습니다.");
|
||||
return resultMap;
|
||||
}
|
||||
|
||||
if("".equals(subject)){
|
||||
resultMap.put("result", "error");
|
||||
resultMap.put("message", "제목이 없습니다.");
|
||||
return resultMap;
|
||||
}
|
||||
|
||||
if("".equals(contents)){
|
||||
resultMap.put("result", "error");
|
||||
resultMap.put("message", "내용이 없습니다.");
|
||||
return resultMap;
|
||||
}
|
||||
|
||||
// 메일 발송 서비스 호출
|
||||
resultMap = contractMgmtService.sendEstimateMailCustom(request, paramMap);
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
resultMap.put("result", "error");
|
||||
resultMap.put("message", "메일 발송 중 오류가 발생했습니다: " + e.getMessage());
|
||||
}
|
||||
|
||||
return resultMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* 주문서관리 리스트
|
||||
|
||||
@@ -2694,4 +2694,177 @@ private String encodeImageToBase64(String imagePath) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 계약 정보 조회 (메일 발송용)
|
||||
* @param paramMap - objId (CONTRACT_OBJID)
|
||||
* @return
|
||||
*/
|
||||
public Map getContractInfoForMail(Map paramMap) {
|
||||
SqlSession sqlSession = null;
|
||||
Map contractInfo = null;
|
||||
|
||||
try {
|
||||
sqlSession = SqlMapConfig.getInstance().getSqlSession();
|
||||
contractInfo = (Map) sqlSession.selectOne("contractMgmt.getContractInfoForMail", paramMap);
|
||||
} catch(Exception e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
if(sqlSession != null) sqlSession.close();
|
||||
}
|
||||
|
||||
return contractInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* 견적서 메일 발송 (커스텀)
|
||||
* @param request
|
||||
* @param paramMap - objId, pdfSessionId, toEmails, ccEmails, subject, contents
|
||||
* @return
|
||||
*/
|
||||
public Map sendEstimateMailCustom(HttpServletRequest request, Map paramMap) {
|
||||
Map resultMap = new HashMap();
|
||||
SqlSession sqlSession = null;
|
||||
|
||||
try {
|
||||
sqlSession = SqlMapConfig.getInstance().getSqlSession(false);
|
||||
|
||||
String objId = CommonUtils.checkNull(paramMap.get("objId"));
|
||||
String toEmailsStr = CommonUtils.checkNull(paramMap.get("toEmails"));
|
||||
String ccEmailsStr = CommonUtils.checkNull(paramMap.get("ccEmails"));
|
||||
String subject = CommonUtils.checkNull(paramMap.get("subject"));
|
||||
String contents = CommonUtils.checkNull(paramMap.get("contents"));
|
||||
String pdfSessionId = CommonUtils.checkNull(paramMap.get("pdfSessionId"));
|
||||
|
||||
// 1. 계약 정보 조회
|
||||
Map contractInfo = (Map) sqlSession.selectOne("contractMgmt.getContractInfoForMail", paramMap);
|
||||
if(contractInfo == null || contractInfo.isEmpty()) {
|
||||
resultMap.put("result", "error");
|
||||
resultMap.put("message", "계약 정보를 찾을 수 없습니다.");
|
||||
return resultMap;
|
||||
}
|
||||
|
||||
// 2. 최종 차수 견적서 조회
|
||||
Map estimateTemplate = (Map) sqlSession.selectOne("contractMgmt.getLatestEstimateTemplate", paramMap);
|
||||
if(estimateTemplate == null || estimateTemplate.isEmpty()) {
|
||||
resultMap.put("result", "error");
|
||||
resultMap.put("message", "견적서를 찾을 수 없습니다.");
|
||||
return resultMap;
|
||||
}
|
||||
|
||||
// 3. 수신인 이메일 리스트 생성
|
||||
ArrayList<String> toEmailList = new ArrayList<String>();
|
||||
if(!"".equals(toEmailsStr)) {
|
||||
String[] toEmails = toEmailsStr.split(",");
|
||||
for(String email : toEmails) {
|
||||
String trimmedEmail = email.trim();
|
||||
if(!"".equals(trimmedEmail)) {
|
||||
toEmailList.add(trimmedEmail);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(toEmailList.isEmpty()) {
|
||||
resultMap.put("result", "error");
|
||||
resultMap.put("message", "수신인 이메일이 없습니다.");
|
||||
return resultMap;
|
||||
}
|
||||
|
||||
// 4. 참조 이메일 리스트 생성
|
||||
ArrayList<String> ccEmailList = new ArrayList<String>();
|
||||
|
||||
// 작성자 이메일 자동 추가
|
||||
String writerEmail = CommonUtils.checkNull(contractInfo.get("writer_email"));
|
||||
if("".equals(writerEmail)) writerEmail = CommonUtils.checkNull(contractInfo.get("WRITER_EMAIL"));
|
||||
if(!"".equals(writerEmail)) {
|
||||
ccEmailList.add(writerEmail);
|
||||
}
|
||||
|
||||
// 사용자가 입력한 참조 이메일 추가
|
||||
if(!"".equals(ccEmailsStr)) {
|
||||
String[] ccEmails = ccEmailsStr.split(",");
|
||||
for(String email : ccEmails) {
|
||||
String trimmedEmail = email.trim();
|
||||
if(!"".equals(trimmedEmail) && !ccEmailList.contains(trimmedEmail)) {
|
||||
ccEmailList.add(trimmedEmail);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 5. PDF 파일 처리
|
||||
ArrayList<HashMap> attachFileList = new ArrayList<HashMap>();
|
||||
if(!"".equals(pdfSessionId)) {
|
||||
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, 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 파일 첨부 완료: " + pdfFile.getAbsolutePath());
|
||||
} else {
|
||||
System.out.println("PDF 파일을 찾을 수 없습니다: " + pdfSessionId);
|
||||
}
|
||||
}
|
||||
|
||||
// 6. 메일 발송
|
||||
PersonBean person = (PersonBean)request.getSession().getAttribute(Constants.PERSON_BEAN);
|
||||
String fromUserId = person.getUserId();
|
||||
|
||||
System.out.println("===== 커스텀 메일 발송 시도 =====");
|
||||
System.out.println("From UserId: " + fromUserId);
|
||||
System.out.println("To Email: " + toEmailList);
|
||||
System.out.println("CC Email: " + ccEmailList);
|
||||
System.out.println("Subject: " + subject);
|
||||
System.out.println("첨부파일 개수: " + attachFileList.size());
|
||||
System.out.println("================================");
|
||||
|
||||
// HTML 형식으로 내용 변환 (줄바꿈 처리)
|
||||
String htmlContents = contents.replace("\n", "<br/>");
|
||||
|
||||
boolean mailSent = false;
|
||||
try {
|
||||
mailSent = MailUtil.sendMailWithAttachFileUTF8(
|
||||
fromUserId,
|
||||
null, // fromEmail (자동으로 SMTP 설정 사용)
|
||||
new ArrayList<String>(), // toUserIdList (빈 리스트)
|
||||
toEmailList,
|
||||
ccEmailList,
|
||||
new ArrayList<String>(), // bccEmailList (빈 리스트)
|
||||
null, // important
|
||||
subject,
|
||||
htmlContents,
|
||||
attachFileList.size() > 0 ? attachFileList : null,
|
||||
"CONTRACT_ESTIMATE"
|
||||
);
|
||||
|
||||
System.out.println("메일 발송 결과: " + mailSent);
|
||||
|
||||
} catch(Exception mailEx) {
|
||||
System.out.println("메일 발송 중 예외 발생: " + mailEx.getMessage());
|
||||
mailEx.printStackTrace();
|
||||
resultMap.put("result", "error");
|
||||
resultMap.put("message", "메일 발송 중 예외가 발생했습니다: " + mailEx.getMessage());
|
||||
return resultMap;
|
||||
}
|
||||
|
||||
if(mailSent) {
|
||||
resultMap.put("result", "success");
|
||||
resultMap.put("message", "견적서가 성공적으로 발송되었습니다.");
|
||||
} else {
|
||||
resultMap.put("result", "error");
|
||||
resultMap.put("message", "메일 발송에 실패했습니다.");
|
||||
}
|
||||
|
||||
} catch(Exception e) {
|
||||
resultMap.put("result", "error");
|
||||
resultMap.put("message", "메일 발송 중 오류가 발생했습니다: " + e.getMessage());
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
if(sqlSession != null) sqlSession.close();
|
||||
}
|
||||
|
||||
return resultMap;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user