728x90
public String signInsert(@ModelAttribute("searchVO") UserVO vo,Model model, HttpServletRequest request) throws Exception {
logger.info("CALL /signInsert.do");
//pdf생성
String base64Code = "";
// 현재 시간
String currentTime = DateUtil.getCurrentDateTime();
String signKeyNm="";
String pdfNm = "_sign_".concat(currentTime);
//이미지없이 데이터만 넣은 pdf파일
String SRC = "";
//firstPdf + 이미지 합쳐진 최종 pdf파일
String DESC = "";
UserMembershipVO resultList = new UserMembershipVO();
String message = "";
String returnUrl = "/sign.do";
Document document = new Document(PageSize.A4, 50, 50, 50, 50); // 용지 및 여백 설정
String storePathString = "";
try {
//계약서에 입력될 회원정보 select
UserMembershipVO mVO = new UserMembershipVO();
mVO.setSignKey(vo.getSignKey());
mVO.setSign(vo.getSign());
mVO.setMembershipNo(vo.getMembershipNo());
resultList = signService.selectPdfSignInfo(mVO); //membershipNo , signKey
if(null != resultList && "S3".equals(resultList.getStep())) {
message = "이미 서명한 계약서입니다.";
model.addAttribute("message", message);
return "reservation/sign/result";
}
vo.setStep("S3"); // 서명완료
// 사인 이미지 base64 insert (USER_INFO_MEMBERSHIP_SIGN)
int resultCnt = signService.signInsert(vo);
logger.info("resultCnt={}",resultCnt);
if (resultCnt == 1) {
message = "서명 완료되었습니다.";
PdfWriter writer = null;
XMLWorker worker = null;
XMLParser xmlParser = null;
StringReader strReader = null;
try {
// 사인 완료된 계약서 pdf로 저장
String signType = resultList.getSignType();
logger.info("signType={}", signType);
vo.setOrderId(resultList.getOrderId());
UserVO orderMasterResult = signService.orderMasterResult(vo); //orderId
// 회원권정보
List<UserVO> orderDetailList = signService.orderDetailList(vo);
String memberTicket = "";
for (UserVO orderDetail : orderDetailList) {
memberTicket += orderDetail.getCategoryNm() + " ";
memberTicket += orderDetail.getTicketNm() + " ";
memberTicket += orderDetail.getStartDate() + " ~ ";
memberTicket += orderDetail.getEndDate() + "";
}
logger.info("memberTicket={}", memberTicket);
// groupId 로 Code조회
GroupVO gvo = new GroupVO();
gvo.setGroupId(vo.getGroupId());
GroupVO groupInfo = groupService.selectInfo(gvo);
String groupNm = groupInfo.getGroupNm();
logger.info("groupNm={}",groupNm);
// 회원권정보
Map reservationMap = signService.selectOrderInfo(vo);
List<Map> itemList = (List) reservationMap.get("select_item_info_list");
//파일저장경로 fileStorePath = file.upload-dir =/home/reservation/uploads/
signKeyNm = vo.getSignKey();
logger.info("signKeyNm={}", signKeyNm);
// pdf 파일 이름
// 파일이 저장될 폴더경로
storePathString = groupInfo.getGroupCode() + "/" +signType;
logger.info("storePathString={}",storePathString);
SRC = fileStorePath + storePathString+"/"+pdfNm+".pdf";
logger.info("SRC = {}",SRC);
File saveFolder = new File(WebUtil.filePathBlackList(fileStorePath + storePathString));
if (!saveFolder.exists() || saveFolder.isFile()) {
logger.info("saveFolder create");
saveFolder.mkdirs();
}
File signFile = new File(WebUtil.filePathBlackList(SRC));
if (signFile.exists()) {
logger.info("################## SLEEP #################");
Thread.sleep(3);
}
String gender = "";
if(resultList.getMemberGender().equals("W")) {
gender = "여";
}else if(resultList.getMemberGender().equals("M")) {
gender = "남";
}
logger.info("MemberGender={}", resultList.getMemberGender());
logger.info("gender={}", gender);
base64Code = vo.getSign();
logger.info("base64Code={}", base64Code);
writer = PdfWriter.getInstance(document, new FileOutputStream(SRC)); //현재상대경로에 first.pdf 생성
writer.setInitialLeading(12.5f);
document.open(); //생성된 파일을 오픈
logger.info("document.open");
logger.info("document.isOpen()={}", document.isOpen());
XMLWorkerHelper helper = XMLWorkerHelper.getInstance();
// 사용할 CSS 를 준비한다.
CSSResolver cssResolver = new StyleAttrCSSResolver();
String cssPath = fileStorePath+"pdf.css";
File cssFilePath = new File(WebUtil.filePathBlackList(cssPath));
if(!cssFilePath.exists()) {
logger.info("NOT FOUND cssPath={}", cssPath);
}
CssFile cssFile = helper.getCSS(new FileInputStream(cssPath));
cssResolver.addCss(cssFile);
// HTML 과 폰트준비
XMLWorkerFontProvider fontProvider = new XMLWorkerFontProvider(XMLWorkerFontProvider.DONTLOOKFORFONTS);
fontProvider.register(fileStorePath+"malgun.ttf","MalgunGothic"); // MalgunGothic 은 alias,
CssAppliers cssAppliers = new CssAppliersImpl(fontProvider);
HtmlPipelineContext htmlContext = new HtmlPipelineContext(cssAppliers);
htmlContext.setTagFactory(Tags.getHtmlTagProcessorFactory());
// Pipelines
PdfWriterPipeline pdf = new PdfWriterPipeline(document, writer);
HtmlPipeline html = new HtmlPipeline(htmlContext, pdf);
CssResolverPipeline css = new CssResolverPipeline(cssResolver, html);
worker = new XMLWorker(css, true);
xmlParser = new XMLParser(worker, Charset.forName("UTF-8"));
// 폰트 설정에서 별칭으로 줬던 "MalgunGothic"을 html 안에 폰트로 지정한다.
String htmlStr = "<html><head><body style='font-family: MalgunGothic;'>"
+ "<div id='popupDiv'>"
+ "<div class='popup' id='popup' style='display:block'>"
+ "<div class='wrapper popupwrap'>"
+ "<div class='contents' id='contents'>"
+ "<div class='sign-form'>"
+ "<div class='title'>"
+ "<h1>CLUB breex 회원가입 신청완료</h1>"
+ "<div class='form'>"
+ "<section>"
+ "<h2 class='info-h2'>회원 정보</h2>"
+ "<div class='table'>"
+ "<table class='sign-table'>"
+ "<tbody>"
+ "<tr>"
+ "<th>회원성명</th>"
+ "<td>"+resultList.getMemberName()+"</td>"
+ "<th>연락처</th>"
+ "<td>"+resultList.getMemberTel()+"</td>"
+ "</tr>"
+ "<tr>"
+ "<th>성별</th>"
+ "<td>"+gender+"</td>"
+ "<th>생년월일</th>"
+ "<td>"+resultList.getMemberBirthday()+"</td>"
+ "</tr></tbody></table></div></section>"
+"<section>"
+ "<h2 class='ticket-info-h2'>회원권 정보</h2>"
+ "<div class='table'>"
+ "<table class='sign-table'>"
+ "<tbody>"
+ "<tr>"
+ "<th style='width:5.5%;'>결제일</th>"
+ "<td colspan='3'>"+ orderMasterResult.getPaymentDate() +"</td>"
+ "</tr>"
+ "<tr>"
+ "<th style='width:5.5%;'>회원권</th>"
+ "<td colspan='3'>";
for(Map item : itemList) {
Map map = (Map) item.get("item_ticket_info");
String pageNm = SF_StringUtil.isNullToString(item.get("page_nm"));
String categoryNm = SF_StringUtil.isNullToString(item.get("category_nm"));
String itemNm = SF_StringUtil.isNullToString(item.get("item_nm"));
String ticketNm = SF_StringUtil.isNullToString(map.get("ticket_nm"));
String startDate = "";
String endDate = "";
String lessonYn = SF_StringUtil.isNullToString(map.get("lesson_yn"));
if(lessonYn.equals("Y")) {
Map lessonMap = (Map) item.get("lesson_info");
startDate = SF_StringUtil.isNullToString(lessonMap.get("lesson_start_date"));
endDate = SF_StringUtil.isNullToString(lessonMap.get("lesson_end_date"));
} else {
startDate = SF_StringUtil.isNullToString(item.get("start_date"));
endDate = SF_StringUtil.isNullToString(item.get("end_date"));
}
htmlStr += "<p>"
+ pageNm;
if(!pageNm.equals(categoryNm)) {
htmlStr += " "+categoryNm;
}
htmlStr += " "+itemNm +" "+ ticketNm +" "
+ startDate+"~"+endDate
+ "</p>";
}
DecimalFormat formatter = new DecimalFormat("###,###,###,###");
String totalPrice = formatter.format(SF_Utils.convertInteger(resultList.getTotalPrice()));
htmlStr+=""
+ "</td>"
+ "</tr>"
+ "<tr>"
+ "<th style='width:5.5%;'>메모</th>"
+ "<td colspan='3'>"+reservationMap.get("memo")
+ "</td>"
+ "</tr>"
+ "</tbody>"
+ "</table>"
+ "<div class='total-price'>"
+ "<span class='total-title'>총 결제 금액</span>"
+ "<span class='space'>...</span>"
+ "<span class='price'>"+totalPrice+"</span>"
+ "</div></div>"
+"</section>"
+"<section>"
+ "<h2>이용 약관</h2>"
+ "<div class='agreement'>"
+ "<h2>제 1조(목적)</h2>"
+ "<p>본 회칙은 "+groupNm+"의 효율적인 관리를 목적으로 한다.</p>"
+ "<h2>제 2조(운영시간)</h2>"
+ "<p>주중 오전 6시부터 오후 11시까지 / 토요일 오전 9시부터 오후 6시까지 / 일요일 및 법정 공휴일은 휴무일로 정함.</p>"
+ "<p>대체공휴일 등 운영에 대한 변동이 있을 경우, 회원관리 앱 또는 게시판을 통해 별도 공지.</p>"
+ "<h2>제 3조(이용 요금 및 입장 제한)</h2>"
+ "<p>1. 일일입장권 : 44,000원/ 1개월: 200.000원 / 3개월 : 480.000원 / 6개월 : 900.000원/ 12개월 : 1.680.000원 (모든 상품 VAT포함)</p>"
+ "<p>2. 1일 1회 입장. 3시간 이용 원칙 (2024년 1월 1일부터)</p>"
+ "<h2>제 4조(환불)</h2>"
+ "<p class='red underline'>1. 회원권은 위약금 10% 차감 후 사용 일수 X 1일 6,666원씩을 공제 후 환불 (14일 이내 환불금 처리 / 일 회권은 제외)</p>"
+ "<p class='red underline'>2. 양도받은 회원권은 환불과 휴회 불가.</p>"
+ "<p class='red underline'>3. 개인 사물함 미사용 일수는 1개월 단위로 환불 가능</p>"
+ "<p class='red underline'>4. 결제일로부터 10일 이후 또는 회원권 개시 이후에는 위약금 10% 발생.</p>"
+ "<p>5. 가입 최초 1회 제공되는 OT 수업은 회원권을 유지하는 회원에 한해서 제공되는 특별 제공 세션으로, 회원권을 한 달 이상 유지하지 않고 환불 시 정상가로(44.000원) 차감 후 환불된다.</p>"
+ "<h2>제 5조(명의 변경 및 휴회 신청)</h2>"
+ "<p class='red underline'>1. 휴회 신청은 회원권 등록자에 한해 회원권 상품에 따라 최소 14일~70일까지 사전 신청이 가능하다. (당일 휴회 신청 불가)</p>"
+ "<p class='red underline'>2. 명의변경 및 양도는 상품을 등록한 회원에 한하며 1회만 가능 (양도비용 100.000원. 재양도 및 중지 불가. 보유 포인트 양도 불가)</p>"
+ "<p class='red underline'>3. 1개월권 : 해당 없음 / 3개월권 : 14일 / 6개월권 : 30일 / 12개월권 : 60일</p>"
+ "<p>*기본 제공 휴회 일을 다 소진한 후, 불가피한 상황 발생 시 증빙자료 제출을 통해 추가 휴회 가능(단, 총 휴회 일이 기본 제공 휴회 일의 2배를 넘길 수 없다)</p>"
+ "<h2>제 6조(손해배상 책임)</h2>"
+ "<p>1.귀중품은 CCTV 확인 가능한 개인사물함(락커룸 제외) 또는 카운터에 보관한다. CCTV 확인 신청은 15일 이내로 가능하며 센터 책임자를 통해 확인 및 피드백을 받는다.</p>"
+ "<p>2. 본인 부주의로 인한 개인 물품 손상 및 도난은 본인에게 책임이 있으며 본 센터의 책임은 없다.</p>"
+ "<p>3. 센터 내의 서비스 시설 및 운동 장비의 결함으로 인하여 입은 피해는 센터에서 손해배상해 준다.</p>"
+ "<p>4. 개인 사물함 갱신 기간이 일주일 경시 물품을 회수하여 보관하며, 보관 1개월 경과 후에는 자체 폐기처리 한다.<br />(앱에서 기간확인 가능하며 폐기직전 본 센터에서는 개별 연락을 취하지 않는다.)</p>"
+ "<h2>제 7조(회원 의무 준수)</h2>"
+ "<p>1. 센터에서 정하는 회원 출입관리 절차를 준수한다 (회원번호 체크인 후 센터 및 락커룸 이용)</p>"
+ "<p>2. 회원권 만료 후 시설 무단 이용. 비회원 동반 입장. 회원간 다툼. 건전한 운동 문화를 저해하는 행위 등 센터의 규율에 어긋나는 행위 적발시 강제 달회 조치 및 법적 책임을 물을 수 있다.(재가입 및 환불 불가)</p>"
+ "<h2>제 8조(효력 발생)</h2>"
+ "<p>본 회칙의 효력은 입장 시작일로부터 발생된다.</p>"
+ "</div>"
+"</section>"
+"<div class='sign-area' id='sign2'>"
+ "<div class='info'>"
+ "<h3>"+groupNm+" 운영회칙 준수 동의서</h3>"
+ "<p>상기 본인은 "+groupNm+" 회원으로 가입함에 있어 회칙, 세칙, 규정 등 준수사항을 충분히 숙지하고 이해하였습니다.</p>"
+ "</div>"
+ "<div class='signature'>"
+ "<span class='year'>"+vo.getSignYear()+"년</span> <span class='space'>.</span>"
+ "<span class='month'>"+vo.getSignMonth()+"월</span> <span class='space'>.</span>"
+ "<span class='day'>"+vo.getSignDay()+"일</span> <span class='space'>.</span>"
+ "<span class='name'>회원명<span class='space'>.</span>"+resultList.getSignName()+"</span>"
+ "</div>"
+"</div>"
+ "</div></div></div></div></div></div></div>"
+ "</body></head></html>";
logger.info("htmlStr={}", htmlStr);
strReader = new StringReader(htmlStr);
xmlParser.parse(strReader);
// if(writer != null) {
// writer.flush();
// }
// if(xmlParser != null) {
// xmlParser.flush();
// }
logger.info("document.isOpen()={}", document.isOpen());
if(document.isOpen()) {
logger.info("document.close()");
document.close();
}
// document.close();
// writer.close();
} catch (DocumentException e) {
logger.error(e.getMessage(), e);
} catch (FileNotFoundException e) {
logger.error(e.getMessage(), e);
} catch (IOException e) {
logger.error(e.getMessage(), e);
} finally {
logger.info("finally");
if(strReader != null) {
logger.info("strReader.close()");
strReader.close();
}
if(worker != null) {
logger.info("worker.close()");
worker.close();
}
if(writer != null) {
logger.info("writer.close()");
writer.close();
}
logger.info("document.isOpen()={}", document.isOpen());
if(document != null && document.isOpen()) {
logger.info("document.close()");
document.close();
}
}
//PFD 파일에 이미지를 넣어본다.
PdfReader reader = null;
PdfStamper stamper = null;
try {
//첫번째 만들어진 PDF
logger.info("SRC={}", SRC);
File srcFolder = new File(WebUtil.filePathBlackList(SRC));
logger.info("srcFolder.exists()={}", srcFolder.exists());
logger.info("srcFolder.isFile()={}", srcFolder.isFile());
reader = new PdfReader(SRC);
//이미지랑 합쳐질 PDF
DESC = fileStorePath + storePathString+ "/" +signKeyNm + ".pdf";
logger.info("DESC={}", DESC);
File descFolder = new File(WebUtil.filePathBlackList(DESC));
logger.info("descFolder.exists()={}", descFolder.exists());
logger.info("descFolder.isFile()={}", descFolder.isFile());
stamper = new PdfStamper(reader, new FileOutputStream(descFolder));
logger.info("이미지를 읽습니다");
PdfContentByte over = stamper.getOverContent(1);
// base64 이미지변환
logger.info("base64Code(B)={}", base64Code);
base64Code = base64Code.replace("data:image/png;base64,", "");
logger.info("base64Code(A)={}", base64Code);
Image image = Image.getInstance(Base64.getDecoder().decode(base64Code));
float newWidth = 100;
float newHeight = 60;
image.scaleAbsolute(newWidth, newHeight);
image.setAbsolutePosition(300, 180);
over.addImage(image);
// stamper.close();
// reader.close();
model.addAttribute("resultList", resultList);
message = "서명이 완료되었습니다.";
// model.addAttribute("message", message);
// model.addAttribute("returnUrl", returnUrl);
} catch (BadElementException e) {
logger.error(e.getMessage(), e);
} catch (IOException e) {
logger.error(e.getMessage(), e);
} catch (BadPdfFormatException e) {
logger.error(e.getMessage(), e);
} catch (DocumentException e) {
logger.error(e.getMessage(), e);
} finally {
logger.info("finally");
if(stamper != null) {
stamper.close();
}
if(reader != null) {
reader.close();
}
}
} else {
message = "서명 중 오류가 발생하였습니다1.";
}
} catch (Exception | Error e) {
logger.error(e.getMessage(), e);
message = "서명 중 오류가 발생하였습니다2.";
} finally {
logger.info("message={}", message);
logger.info("returnUrl={}", returnUrl);
model.addAttribute("message", message);
model.addAttribute("returnUrl", returnUrl);
}
return "reservation/sign/result";
}
728x90
'Java' 카테고리의 다른 글
[java] java로 xml 다운로드 (0) | 2024.07.01 |
---|---|
[java] xml 생성 (1) | 2024.06.19 |
[java] xsl+xml 을 pdf파일로 변환하기 (0) | 2024.06.19 |
Java 타입 (0) | 2023.09.22 |
[Java] 객체지향언어 / 클래스, 객체, 인스턴스, 참조변수, 메서드 (0) | 2023.06.11 |