package kcc.com.pdf.service.impl; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import java.util.stream.Collectors; import javax.annotation.Resource; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; import com.mashape.unirest.http.HttpResponse; import com.mashape.unirest.http.Unirest; import egovframework.rte.fdl.cmmn.EgovAbstractServiceImpl; import egovframework.rte.fdl.idgnr.EgovIdGnrService; import egovframework.rte.fdl.security.userdetails.util.EgovUserDetailsHelper; import kcc.com.cmm.LoginVO; import kcc.com.pdf.service.PdfService; import kcc.com.pdf.service.PdfVO; import kcc.com.utl.fcc.service.EgovStringUtil; /* * pg관리자페이지에서 해당 옵션 true로 설정 * pg.exec.merge.insertBookmark * * validation * - 변환 가능 확장자 * - dap, ppt, pptx, pptm, pps, ppsx, xls, xlsx, xlsm, xlsb, doc, docx, docm, dotx, rtf, odt, odp, ods, odg, hwp, hml, hwpx, dwg, dwf, dxf, dgn, url, mht, mhtml, htm, html, jpg, jpe, jpeg, tif, tiff, gif, png, bmp, j2k, psd * * 1. 표지pdf 생성 및 베이스로 사용 * - inputUri * 2. merge 파일들 추가 * - label 기능을 책갈피 기능으로 대체 * - * * 테이블 설계 * - 사건번호(pk), name(pk), 요청id,상태, 결과 파일 경로 * * https://fairnet.kofair.or.kr/clip/ClipReport4/ClipReportViewer/ClipReport4PdfDown2.do?CLIPDATA_CASENO=%EA%B0%80%EB%A7%B92025-0003&CLIPDATA_RCEPTNO=20250102-040&CLIPDATA_USERTYPE=&CLIPDATA_SEQNO=&crfNm=reqPrint * */ /* * ##############################################################pdf 병합############################################################## */ /* * step 1 * - caseNo에 따른 rceptNo정보 가져오기 */ /* * step 2 * - caseNo 또는 rceptNo 에 따른 첨부파일 가져오기 * - 변환 가능 확장자 * - dap, ppt, pptx, pptm, pps, ppsx, xls, xlsx, xlsm, xlsb, doc, docx, docm, dotx, rtf, odt, odp, ods, odg, hwp, hml, hwpx, dwg, dwf, dxf, dgn, url, mht, mhtml, htm, html, jpg, jpe, jpeg, tif, tiff, gif, png, bmp, j2k, psd * - label에 realFileNm 넣기 * ! 파일명에 따라 변환이 제대로 되는지 확인 */ /* * step 3 * - 신청서 clipreport 파일 가져오기 * - setHtmlUrlResource 옵션 false로 설정 */ /* * step 4 * - api call * - db에 responsse data 저장 */ /* * ##############################################################pdf 작업 callback############################################################## */ /* * step 1 * - callback 받은 데이터 db 저장(상태, 결과파일 경로) */ @Service("PdfService") public class PdfServiceImpl extends EgovAbstractServiceImpl implements PdfService { @Resource(name = "pdfIdgenService") private EgovIdGnrService pdfIdgenService; @Resource(name="pdfDAO") private PdfDAO pdfDAO; @Value("#{globalSettings['pdf.filePath']}") private String pdfFilePath; @Value("#{globalSettings['pdf.hostUri']}") private String hostUri; @Value("#{globalSettings['pdf.serverUrl']}") private String serverUrl; @Override public Map conversionPdf( String caseNo , String rceptNo ) throws Exception { //파일 방식 // PdfVO.SubTask mergeTask = new PdfVO.SubTask(); // mergeTask.setType("merge"); // // PdfVO.Options options1 = new PdfVO.Options(); // options1.setMergeSrcUri("file:/Z:/inputFile/2.pdf"); // PdfVO.Option option1 = new PdfVO.Option(); // option1.setLabel("2.pdf"); // options1.getOption().add(option1); // mergeTask.getOptions().add(options1); //html 다운로드 방식 // PdfVO.Options options4 = new PdfVO.Options(); // options4.setMergeSrcUri("https://fairnet.kofair.or.kr/clip/ClipReport4/ClipReportViewer/ClipReport4PdfDown2.do?CLIPDATA_CASENO=%EA%B0%80%EB%A7%B92025-0003&CLIPDATA_RCEPTNO=20250102-040&CLIPDATA_USERTYPE=&CLIPDATA_SEQNO=&crfNm=reqPrint"); // PdfVO.Option option4 = new PdfVO.Option(); // option4.setLabel("5.html"); // option4.setHtmlUrlResource(false); // options4.getOption().add(option4); // mergeTask.getOptions().add(options4); Map result = new HashMap(); try { LocalDateTime today = LocalDateTime.now(); DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmss"); String day = today.format(formatter); /* * 조정신청서는 항상 존재하므로 기본 파일로 설정 */ PdfVO pdfVO = new PdfVO(); pdfVO.setCaseNo(caseNo); //표지 pdfVO.setInputUri(hostUri + "/gtm/case/pdfSubjectPop.do?caseNo=" + caseNo); pdfVO.getOption().setHtmlUrlResource(true); pdfVO.getOption().setLabel("표지"); //글로벌 변경해야함 pdfVO.setOutputUri("file:/Z:/resultFile/" + caseNo + "_"+ day +".pdf"); //글로벌 변경해야함 pdfVO.setCallbackUri(hostUri + "/gtm/case/pdfCallBack.do"); pdfVO.setName(pdfIdgenService.getNextStringId()); pdfVO.setExternalId(caseNo); PdfVO.SubTask mergeTask = new PdfVO.SubTask(); mergeTask.setType("merge"); /* * 조정신청서는 항상 존재하므로 merge1번파일로 지정 */ PdfVO.Options options1 = new PdfVO.Options(); options1.setMergeSrcUri( hostUri + "/clip/ClipReport4/ClipReportViewer/ClipReport4PdfDown2.do" + "?CLIPDATA_CASENO=" + URLEncoder.encode(caseNo, StandardCharsets.UTF_8.toString()) + "&CLIPDATA_RCEPTNO=" + URLEncoder.encode(rceptNo, StandardCharsets.UTF_8.toString()) + "&CLIPDATA_USERTYPE=" + "&CLIPDATA_SEQNO=" + "&crfNm=reqPrint" ); PdfVO.Option option1 = new PdfVO.Option(); option1.setLabel("조정신청서"); option1.setHtmlUrlResource(false); options1.getOption().add(option1); mergeTask.getOptions().add(options1); /* * DB 테이블 조회 */ //첨부파일 경로, 원 파일명, 변환가능 확장자 체크 //대상 팡리 List processList = extensionCheck(pdfDAO.selectProcessList(pdfVO)); //pdf 포함파일 명들 StringBuilder fileNames = new StringBuilder("표지"); processList.stream().forEach(t -> { PdfVO.Options options = new PdfVO.Options(); if(t.getResultFilePath().startsWith("/usr/local/homepage/WEB-INF/views/site/case/upload/uploadFiles/case")) { ; options.setMergeSrcUri("file:/Z:" + t.getResultFilePath().substring("/usr/local/homepage/WEB-INF/views/site/case/upload/uploadFiles/case".length())); }else { options.setMergeSrcUri("file:/Z:" + pdfFilePath + t.getResultFilePath()); } PdfVO.Option option = new PdfVO.Option(); option.setLabel(t.getFileName()); options.getOption().add(option); mergeTask.getOptions().add(options); try { fileNames.append("%2C%20%3C%2Fbr%3E" + URLEncoder.encode(t.getFileName(), StandardCharsets.UTF_8.toString())); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } } ); /* * pdf 파일명들 */ PdfVO.Options options2 = new PdfVO.Options(); options2.setMergeSrcUri(hostUri + "/gtm/case/pdfSubjectPop.do?caseNo=" + fileNames); PdfVO.Option option2 = new PdfVO.Option(); option2.setLabel("파일 끝"); option2.setHtmlUrlResource(true); options2.getOption().add(option2); mergeTask.getOptions().add(options2); pdfVO.getSubtasks().add(mergeTask); pdfVO.setSubtask(null); // ObjectMapper를 사용하여 PdfVO 객체를 JSON 문자열로 변환 ObjectMapper objectMapper = new ObjectMapper(); String body = objectMapper.writeValueAsString(pdfVO); // PDF Gateway REST API 호출 HttpResponse response = Unirest.post(serverUrl + "/pdf-gateway/api/job/build") .header("Content-Type", "application/json") .body(body) .asString(); System.out.println(response.getBody()); String responseBody = response.getBody(); Map map = objectMapper.readValue(responseBody, new TypeReference>() {}); map.put("caseNo", caseNo); map.put("userId", getUserId()); pdfDAO.insertDocCallback(map); result.put("result", "변환 요청되었습니다."); } catch (Exception e) { result.put("fail", "변환 요청이 실패했습니다."); } return result; } /* * ##############################################################pdf 작업 상태 조회############################################################## */ /* * step 1 * - 사건번호로 DB조회 */ @Override public List selectDocList( PdfVO pdfVO ) throws Exception { return pdfDAO.selectDocList(pdfVO); } @Override public void updateDocCallback(Map map) throws Exception{ pdfDAO.updateDocCallback(map); } @Override public void insertDocCallback(Map map) throws Exception{ pdfDAO.insertDocCallback(map); } private List extensionCheck(List processList){ // 허용된 파일 확장자 목록을 Set으로 정의 Set allowedExtensions = new HashSet<>(Arrays.asList( "dap", "ppt", "pptx", "pptm", "pps", "ppsx", "xls", "xlsx", "xlsm", "xlsb", "doc", "docx", "docm", "dotx", "rtf", "odt", "odp", "ods", "odg", "hwp", "hml", "hwpx", "dwg", "dwf", "dxf", "dgn", "url", "mht", "mhtml", "htm", "html", "jpg", "jpe", "jpeg", "tif", "tiff", "gif", "png", "bmp", "j2k", "psd", "pdf" )); // 파일 확장자가 허용된 목록에 있는지 확인하고 필터링 return processList.stream() .filter(pdfVO -> { String extension = pdfVO.getFileExtension(); return extension != null && allowedExtensions.contains(extension.toLowerCase()); }) .collect(Collectors.toList()); } private String getUserId() { LoginVO loginVO = EgovUserDetailsHelper.isAuthenticated() ? (LoginVO) EgovUserDetailsHelper.getAuthenticatedUser() : null; String userId = loginVO == null ? "" : EgovStringUtil.isNullToString(loginVO.getUniqId()); return userId; } }