이수증,메인화면 작업중

This commit is contained in:
leejunho 2025-11-03 14:08:51 +09:00
parent 19763eb412
commit 5bca6f3752
17 changed files with 1052 additions and 655 deletions

View File

@ -696,8 +696,9 @@ public class CmdTrgtController {
vEEduAplctVO.setUserId(loginVO.getUniqId());
vEEduAplctVO.setPrcsOrd(vEPrcsDetailVO.getPrcsAplctPrdOrd());
vEEduAplctVO.setTrgtNm(vEPrcsDetailVO.getTrgtNm());
vEEduAplctVO.setChrgNm(vEPrcsDetailVO.getTrgtNm());
vEEduAplctVO.setdBirth(vEPrcsDetailVO.getdBirth());
vEEduAplctVO.setPhone(egovCryptoUtil.encrypt(vEPrcsDetailVO.getPhone()));
vEEduAplctVO.setPhone(vEPrcsDetailVO.getPhone());
vEEduAplctVO.setEmail(vEPrcsDetailVO.getEmail());
String result = "";

View File

@ -1,5 +1,7 @@
package kcc.ve.aplct.cpyrgExprnClsrm.exprnClsrmAplct.web;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.List;
import javax.annotation.Resource;
@ -28,6 +30,8 @@ import kcc.ve.cmm.VeConstants;
import kcc.ve.instr.tngrVisitEdu.eduInfo.service.VEEduAplctVO;
import kcc.ve.instr.tngrVisitEdu.eduInfo.service.VEEduChasiVO;
import kcc.ve.instr.tngrVisitEdu.eduInfo.service.VEEduMIXService;
import kcc.ve.instr.tngrVisitEdu.prcsInfo.service.VEPrcsAplctPrdService;
import kcc.ve.instr.tngrVisitEdu.prcsInfo.service.VEPrcsDetailVO;
import kcc.ve.oprtn.qestnr.service.VEALettnQestnrMIXService;
/**
@ -92,6 +96,9 @@ public class ScholInfoController {
@Resource(name = "vEALettnQestnrMIXService")
private VEALettnQestnrMIXService vEALettnQestnrMIXService;
@Resource(name = "vEPrcsAplctPrdService")
private VEPrcsAplctPrdService vEPrcsAplctPrdService;
/**
* 학교정보 검색 팝업 리스트
*/
@ -448,71 +455,23 @@ public class ScholInfoController {
*/
@RequestMapping("popup/certPopList.do")
public String certPopList(
@ModelAttribute("vEEduChasiVO") VEEduChasiVO vEEduChasiVO
@ModelAttribute("vEPrcsDetailVO") VEPrcsDetailVO vEPrcsDetailVO
, QustnrRespondInfoVO qustnrRespondInfoVO
, ModelMap model
, HttpServletRequest request
) throws Exception {
String s_action = request.getParameter("action"); //insert or select
System.out.println("s_action");
System.out.println(s_action);
System.out.println(vEEduChasiVO.getQustnrTmplatId());
System.out.println(vEEduChasiVO.getQestnrId());
System.out.println(vEEduChasiVO.getQustnrRespondId());
vEPrcsDetailVO = vEPrcsAplctPrdService.selectCompleteDocDetail(vEPrcsDetailVO);
vEPrcsDetailVO.setTrgtNm(egovCryptoUtil.decrypt(vEPrcsDetailVO.getTrgtNm()));
System.out.println(qustnrRespondInfoVO.getQustnrTmplatId());
System.out.println(qustnrRespondInfoVO.getQestnrId());
System.out.println(qustnrRespondInfoVO.getQustnrRespondId());
//차시 정보
/*
try {
vEEduChasiVO.setInstrDiv(VeConstants.LCTR_DIV_CD_10); //10-청소년 강사, 20-성인강사 VE0001
VEEduChasiVO ChasiInfo = vEEduMIXService.selectChasiInfo(vEEduChasiVO);
ChasiInfo.setInstrNm(egovCryptoUtil.decrypt(ChasiInfo.getInstrNm()));
ChasiInfo.setStrtTm(ChasiInfo.getStrtTm().substring(0,2)+":"+ChasiInfo.getStrtTm().substring(2,4));
ChasiInfo.setEndTm(ChasiInfo.getEndTm().substring(0,2)+":"+ChasiInfo.getEndTm().substring(2,4));
model.addAttribute("chasiInfo", ChasiInfo);
}catch(Exception ex) {
System.out.println("Exception vEEduAplctOnlnService.updateBulk");
}
*/
//참석 답변 정보
try {
List<QustnrRespondInfoVO> chasiSrvyList = egovQustnrRespondInfoService.selectChasiSrvyFndtnList202312(qustnrRespondInfoVO);
//model.addAttribute("qestnrRespondent", chasiSrvyList.get(0).getQestnrRespondent());
//model.addAttribute("qestnrParticipant", chasiSrvyList.get(0).getQestnrParticipant());
System.out.println("chasiSrvyList.get(0).getPrcsAplctPrdOrd()");
System.out.println(chasiSrvyList.get(0).getPrcsAplctPrdOrd());
System.out.println(chasiSrvyList.get(0).getPrcsAplctPrdOrd());
model.addAttribute("chasiSrvyList", chasiSrvyList);
model.addAttribute("chasiSrvyListCnt", chasiSrvyList.size());
}catch(Exception ex) {
System.out.println("Exception vEEduAplctOnlnService.updateBulk");
}
//기본정보
model.addAttribute("completeDocDetail", vEPrcsDetailVO);
//설문 참여 정보
/*
try {
model = qustnrCommonUtil._qustnrQesItm(
model
, VeConstants.LCTR_DIV_CD_10 //청소년 -10, 성인-20, ...VE0012
, "10" //10-기본설문, 20-신청자설문, 30-강사설문 VEA012
, "QTMPLA_0000000000001"
, vEALettnQestnrMIXService
, egovQustnrRespondInfoService
);
}catch(Exception ex) {
ex.printStackTrace();
}
*/
LocalDate today = LocalDate.now();
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy년 M월 d일");
String todayStr = today.format(formatter);
model.addAttribute("todayStr", todayStr);
return "/web/ve/aplct/cpyrgExprnClsrm/exprnClsrmInfo/popup/certPopList";
}

View File

@ -697,7 +697,7 @@ public class PreventController {
vEEduAplctVO.setChrgNm(vEPrcsDetailVO.getTrgtNm());
vEEduAplctVO.setTrgtNm(vEPrcsDetailVO.getTrgtNm());
vEEduAplctVO.setdBirth(vEPrcsDetailVO.getdBirth());
vEEduAplctVO.setPhone(egovCryptoUtil.encrypt(vEPrcsDetailVO.getPhone()));
vEEduAplctVO.setPhone(vEPrcsDetailVO.getPhone());
vEEduAplctVO.setEmail(vEPrcsDetailVO.getEmail());
String result = "";

View File

@ -686,8 +686,9 @@ public class SspnIdtmtController {
vEEduAplctVO.setUserId(loginVO.getUniqId());
vEEduAplctVO.setPrcsOrd(vEPrcsDetailVO.getPrcsAplctPrdOrd());
vEEduAplctVO.setTrgtNm(vEPrcsDetailVO.getTrgtNm());
vEEduAplctVO.setChrgNm(vEPrcsDetailVO.getTrgtNm());
vEEduAplctVO.setdBirth(vEPrcsDetailVO.getdBirth());
vEEduAplctVO.setPhone(egovCryptoUtil.encrypt(vEPrcsDetailVO.getPhone()));
vEEduAplctVO.setPhone(vEPrcsDetailVO.getPhone());
vEEduAplctVO.setEmail(vEPrcsDetailVO.getEmail());
String result = "";

View File

@ -95,4 +95,6 @@ public interface VEPrcsAplctPrdService {
//신청목록-실무역량강화, 기소유예 new -설문조사, 이수증 처리용
List<VEPrcsDetailVO> findByAprvlQustnrAllList(VEPrcsDetailVO vEPrcsDetailVO);
public VEPrcsDetailVO selectCompleteDocDetail(VEPrcsDetailVO vEPrcsDetailVO);
}

View File

@ -174,4 +174,8 @@ public class VEPrcsAplctPrdDAO extends EgovAbstractDAO {
return (List<VEPrcsDetailVO>) list("VEPrcsAplctPrdDAO.findByAprvlQustnrAllList", vEPrcsDetailVO);
}
public VEPrcsDetailVO selectCompleteDocDetail(VEPrcsDetailVO vEPrcsDetailVO) {
return (VEPrcsDetailVO) select("VEPrcsAplctPrdDAO.selectCompleteDocDetail", vEPrcsDetailVO);
}
}

View File

@ -389,5 +389,10 @@ public class VEPrcsAplctPrdServiceImpl implements VEPrcsAplctPrdService {
return vEPrcsAplctPrdDAO.findByAprvlQustnrAllList(vEPrcsDetailVO);
}
@Override
public VEPrcsDetailVO selectCompleteDocDetail(VEPrcsDetailVO vEPrcsDetailVO) {
return vEPrcsAplctPrdDAO.selectCompleteDocDetail(vEPrcsDetailVO);
}
}

View File

@ -2404,8 +2404,9 @@ public class CmdPrcsInfoMngController {
vEEduAplctVO.setUserId(loginVO.getUniqId());
vEEduAplctVO.setPrcsOrd(vEPrcsDetailVO.getPrcsAplctPrdOrd());
vEEduAplctVO.setTrgtNm(vEPrcsDetailVO.getTrgtNm());
vEEduAplctVO.setChrgNm(vEPrcsDetailVO.getTrgtNm());
vEEduAplctVO.setdBirth(vEPrcsDetailVO.getdBirth());
vEEduAplctVO.setPhone(egovCryptoUtil.encrypt(vEPrcsDetailVO.getPhone()));
vEEduAplctVO.setPhone(vEPrcsDetailVO.getPhone());
vEEduAplctVO.setEmail(vEPrcsDetailVO.getEmail());
String result = "";

View File

@ -2574,8 +2574,9 @@ public class CndtnPrcsInfoMngController {
vEEduAplctVO.setUserId(loginVO.getUniqId());
vEEduAplctVO.setPrcsOrd(vEPrcsDetailVO.getPrcsAplctPrdOrd());
vEEduAplctVO.setTrgtNm(vEPrcsDetailVO.getTrgtNm());
vEEduAplctVO.setChrgNm(vEPrcsDetailVO.getTrgtNm());
vEEduAplctVO.setdBirth(vEPrcsDetailVO.getdBirth());
vEEduAplctVO.setPhone(egovCryptoUtil.encrypt(vEPrcsDetailVO.getPhone()));
vEEduAplctVO.setPhone(vEPrcsDetailVO.getPhone());
vEEduAplctVO.setEmail(vEPrcsDetailVO.getEmail());
String result = "";

View File

@ -7,6 +7,7 @@ import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
@ -388,91 +389,29 @@ public class MainController {
try {
String referer = (String)request.getHeader("REFERER");
LoginVO loginVO = EgovUserDetailsHelper.isAuthenticated()? (LoginVO)EgovUserDetailsHelper.getAuthenticatedUser():null;
String userAuthority = loginVO == null ? "" : EgovStringUtil.isNullToString(loginVO.getAuthority());
model.addAttribute("userAuthority", userAuthority); //권한 - 강사일 메인의 청소년, 성인, 체험교실, 콘텐츠 메뉴 링크이동 막기 위해 추가
// LoginVO loginVO = EgovUserDetailsHelper.isAuthenticated()? (LoginVO)EgovUserDetailsHelper.getAuthenticatedUser():null;
// String userAuthority = loginVO == null ? "" : EgovStringUtil.isNullToString(loginVO.getAuthority());
// model.addAttribute("userAuthority", userAuthority); //권한 - 강사일 메인의 청소년, 성인, 체험교실, 콘텐츠 메뉴 링크이동 막기 위해 추가
/** EgovPropertyService.sample */
MainzoneVO mainzoneVO = new MainzoneVO();
mainzoneVO.setPageUnit(propertiesService.getInt("pageUnit"));
mainzoneVO.setPageSize(propertiesService.getInt("pageSize"));
/** pageing */
PaginationInfo paginationInfo = new PaginationInfo();
paginationInfo.setCurrentPageNo(mainzoneVO.getPageIndex());
paginationInfo.setRecordCountPerPage(mainzoneVO.getPageUnit());
paginationInfo.setPageSize(mainzoneVO.getPageSize());
mainzoneVO.setFirstIndex(paginationInfo.getFirstRecordIndex());
mainzoneVO.setLastIndex(paginationInfo.getLastRecordIndex());
mainzoneVO.setRecordCountPerPage(paginationInfo.getRecordCountPerPage());
mainzoneVO.setUseYn("Y"); //사용하는것만
mainzoneVO.setDeviceType("P"); //PC
//디자인이 슬라이드가 아닌 한개의 메인화면으로 변경되어 수정
mainzoneVO.setRecordCountPerPage(1);
List<?> mainzoneList = egovPopupManageService.selectMainzoneList(mainzoneVO); //상단메인 이미지
// mainzoneVO.setDeviceType("M"); //모바일
// List<?> mainzoneListM = egovPopupManageService.selectMainzoneList(mainzoneVO); //상단메인 이미지
model.addAttribute("mainzoneList", mainzoneList); //PC
// model.addAttribute("mainzoneListM", mainzoneListM); //모바일
/** 메인존 */
model.addAttribute("mainzoneList", mainZone()); //PC
/** 팝업 알림창괸리 */
//if(!isMobile(request)){ //PC인경우만
PopupManageVO popupManageVO = new PopupManageVO();
popupManageVO.setRecordCountPerPage(10); //10개만
popupManageVO.setNtceAt("Y"); //사용만
popupManageVO.setMainPageFlag("Y") ; //메인화면의 용도(시작일 종료일 사이 조회)
List<?> popupList = egovPopupManageService.selectPopupMainList(popupManageVO);
model.addAttribute("popupList", popupList);
//}
model.addAttribute("popupList", popupList());
/** 팝업존 알림창괸리 */
//if(!isMobile(request)){
PopupzoneVO popupzoneVo = new PopupzoneVO();
popupzoneVo.setFirstIndex(0);
popupzoneVo.setSeCd("02"); //좌측팝업
popupzoneVo.setUseYn("Y");
List<?> popupzoneList = egovPopupManageService.selectPopupzoneList(popupzoneVo);
model.addAttribute("popupzoneList", popupzoneList);
//popupzoneVo.setSeCd("03");
//List<?> popupzoneTopList = egovPopupManageService.selectPopupzoneList(popupzoneVo);
//model.addAttribute("popupzoneTopList", popupzoneTopList);
//}
model.addAttribute("popupzoneList", popupzoneList());
/** 게시판 조회 - 공지사항 */
BoardVO boardVO = new BoardVO();
boardVO.setRecordCountPerPage(5); //게시글
boardVO.setFirstIndex(0); //
boardVO.setBbsId("BBSMSTR_000000000010");
List<BoardVO> vo = bbsMngService.selectMainBoardRecent(boardVO);
//게시글 내용 html 태그 삭제
for(int i=0; i<vo.size(); i++) {
vo.get(i).setNttCn(vo.get(i).getNttCn().replaceAll("<(/)?([a-zA-Z]*)(\\s[a-zA-Z]*=[^>]*)?(\\s)*(/)?>", "").split("<")[0]);
}
model.addAttribute("bbsList", vo);
Map<String, Object> noticeBbsList = noticeBbsList();
model.addAttribute("noticeBbsList", noticeBbsList.get("noticeBbsList"));
model.addAttribute("noticeBbsUrl", noticeBbsList.get("noticeBbsUrl"));
/** 게시판 조회 - 교육자료실 */
BoardVO boardVO_2 = new BoardVO();
boardVO_2.setRecordCountPerPage(5); //게시글
boardVO_2.setFirstIndex(0); //
boardVO_2.setBbsId("BBSMSTR_000000000000");
List<BoardVO> vo_2 = bbsMngService.selectMainBoardRecent(boardVO_2);
//게시글 내용 html 태그 삭제
for(int i=0; i<vo_2.size(); i++) {
vo_2.get(i).setNttCn(vo_2.get(i).getNttCn().replaceAll("<(/)?([a-zA-Z]*)(\\s[a-zA-Z]*=[^>]*)?(\\s)*(/)?>", "").split("<")[0]);
}
Map<String, Object> atchBbsList = atchBbsList();
model.addAttribute("atchBbsList", atchBbsList.get("atchBbsList"));
model.addAttribute("atchBbsUrl", atchBbsList.get("atchBbsUrl"));
model.addAttribute("bbsList_2", vo_2);
System.out.println("zzzzzzzzzzzzzzzzzzzzzzzzzzzzzz");
System.out.println("zzzzzzzzzzzzzzzzzzzzzzzzzzzzzz");
}catch(Exception ex) {
ex.printStackTrace();
System.out.println(ex.getMessage());
@ -2078,5 +2017,87 @@ public class MainController {
//mbp.setContent(html.replaceAll("(\r\n|\n)", "<br />"), "text/html; charset=utf-8"); //줄바꿈이 필요해서
return mbp;
}
private List<?> mainZone() throws Exception{
/** EgovPropertyService.sample */
MainzoneVO mainzoneVO = new MainzoneVO();
mainzoneVO.setPageUnit(propertiesService.getInt("pageUnit"));
mainzoneVO.setPageSize(propertiesService.getInt("pageSize"));
/** pageing */
PaginationInfo paginationInfo = new PaginationInfo();
paginationInfo.setCurrentPageNo(mainzoneVO.getPageIndex());
paginationInfo.setRecordCountPerPage(mainzoneVO.getPageUnit());
paginationInfo.setPageSize(mainzoneVO.getPageSize());
mainzoneVO.setFirstIndex(paginationInfo.getFirstRecordIndex());
mainzoneVO.setLastIndex(paginationInfo.getLastRecordIndex());
mainzoneVO.setRecordCountPerPage(paginationInfo.getRecordCountPerPage());
mainzoneVO.setUseYn("Y"); //사용하는것만
mainzoneVO.setDeviceType("P"); //PC
//디자인이 슬라이드가 아닌 한개의 메인화면으로 변경되어 수정
mainzoneVO.setRecordCountPerPage(1);
List<?> mainzoneList = egovPopupManageService.selectMainzoneList(mainzoneVO); //상단메인 이미지
return mainzoneList;
}
private List<?> popupList() throws Exception{
PopupManageVO popupManageVO = new PopupManageVO();
popupManageVO.setRecordCountPerPage(10); //10개만
popupManageVO.setNtceAt("Y"); //사용만
popupManageVO.setMainPageFlag("Y") ; //메인화면의 용도(시작일 종료일 사이 조회)
List<?> popupList = egovPopupManageService.selectPopupMainList(popupManageVO);
return popupList;
}
private List<?> popupzoneList() throws Exception{
PopupzoneVO popupzoneVo = new PopupzoneVO();
popupzoneVo.setFirstIndex(0);
popupzoneVo.setSeCd("02"); //좌측팝업
popupzoneVo.setUseYn("Y");
List<?> popupzoneList = egovPopupManageService.selectPopupzoneList(popupzoneVo);
return popupzoneList;
}
private Map<String, Object> noticeBbsList() throws Exception{
Map<String, Object> returnMap = new HashMap<String, Object>();
BoardVO boardVO = new BoardVO();
boardVO.setRecordCountPerPage(5); //게시글
boardVO.setFirstIndex(0); //
boardVO.setBbsId("BBSMSTR_000000000010");
List<BoardVO> vo = bbsMngService.selectMainBoardRecent(boardVO);
//게시글 내용 html 태그 삭제
for(int i=0; i<vo.size(); i++) {
vo.get(i).setNttCn(vo.get(i).getNttCn().replaceAll("<(/)?([a-zA-Z]*)(\\s[a-zA-Z]*=[^>]*)?(\\s)*(/)?>", "").split("<")[0]);
}
returnMap.put("noticeBbsList", vo);
returnMap.put("noticeBbsUrl", boardVO.getBbsId());
return returnMap;
}
private Map<String, Object> atchBbsList() throws Exception{
Map<String, Object> returnMap = new HashMap<String, Object>();
BoardVO boardVO_2 = new BoardVO();
boardVO_2.setRecordCountPerPage(5); //게시글
boardVO_2.setFirstIndex(0); //
boardVO_2.setBbsId("BBSMSTR_000000000040");
List<BoardVO> vo_2 = bbsMngService.selectMainBoardRecent(boardVO_2);
//게시글 내용 html 태그 삭제
for(int i=0; i<vo_2.size(); i++) {
vo_2.get(i).setNttCn(vo_2.get(i).getNttCn().replaceAll("<(/)?([a-zA-Z]*)(\\s[a-zA-Z]*=[^>]*)?(\\s)*(/)?>", "").split("<")[0]);
}
returnMap.put("atchBbsList", vo_2);
returnMap.put("atchBbsUrl", boardVO_2.getBbsId());
return returnMap;
}
}

View File

@ -1943,4 +1943,24 @@
</select>
<select id="selectCompleteDocDetail" parameterClass="VEPrcsDetailVO" resultClass="VEPrcsDetailVO">
SELECT
a.prcs_aplct_prd_ord AS prcsAplctPdrOrd
, b.lctr_div_cd AS lctrDivCd
, a.edu_cmplt_crtfc_nmbr AS eduCmpltCrtfcNmbr
, b.title AS title
, b.edu_strt_pnttm AS eduStrtPnttm
, c.chrg_nm AS chrgNm
FROM
vea_aplct_detail_info a
LEFT JOIN ve_prcs_aplct_prd b
ON a.prcs_aplct_prd_ord = b.prcs_aplct_prd_ord
LEFT JOIN ve_edu_aplct c
ON a.prcs_aplct_prd_ord = c.prcs_ord
AND c.aprvl_cd = '60'
WHERE
a.prcs_aplct_prd_ord = #prcsAplctPrdOrd#
</select>
</sqlMap>

View File

@ -809,7 +809,8 @@
${status.count}
</td>
<td>
<c:out value="${list.trgtNm}"/><br/>(<c:out value="${list.mberId}"/>)
<%-- <c:out value="${list.trgtNm}"/><br/>(<c:out value="${list.mberId}"/>) --%>
<c:out value="${list.chrgNm}"/><br/>(<c:out value="${list.mberId}"/>)
<%-- <br/>(<c:out value="${list.cmdTrgtInfoOrd}"/>) --%>
</td>
<td>

View File

@ -24,12 +24,6 @@
//$(".btnSearch").keyup(function(e){if(e.keyCode == 13) linkPage('1');});
});
function fn_egov_addNotice(){
document.frm.method = "post";
document.frm.action = "<c:url value='/web/cop/bbs/addBoardArticle.do'/>";
document.frm.submit();
}
function linkPage(pageNo) {
if (pageNo != 1) {
document.frm.searchWrd.value = "";
@ -52,13 +46,6 @@
document.frm.submit();
}
function fn_egov_pdfView(atchFileId, fileSn){
window.open("/cmm/fms/pdfView.do?atchFileId=" + atchFileId + "&fileSn=" + fileSn);
}
function fn_egov_downFile(atchFileId, fileSn){
window.open("/cmm/fms/FileDown.do?atchFileId=" + atchFileId + "&fileSn=" + fileSn);
}
</script>
</head>
@ -228,14 +215,6 @@
</table>
</div>
<div class="btn_wrap btn_layout01">
<div class="btn_left"></div>
<div class="btn_center"></div>
<div class="btn_right">
<button type="button" class="btn fill blue large" onclick="javascript:fn_egov_addNotice(); return false;">글쓰기</button>
</div>
</div>
<c:if test="${!empty resultList}">
<div class="page">
<ui:pagination paginationInfo="${paginationInfo}" type="imageWeb" jsFunction="linkPage"/>

View File

@ -75,15 +75,7 @@ function fn_egov_inqire_notice(bbsId, nttId) {
document.frm.nttId.value = nttId;
document.frm.bbsId.value = bbsId;
document.frm.method = "post";
document.frm.action = "<c:url value='/web/cop/bbs/selectBoardDetail2024.do'/>?pubDetail=Y";
document.frm.submit();
}
function fn_egov_inqire_data(bbsId, nttId) {
document.frm.nttId.value = nttId;
document.frm.bbsId.value = bbsId;
document.frm.method = "get";
document.frm.action = "<c:url value='/web/cop/bbs/selectDataBoardDetail.do'/>";
document.frm.action = "<c:url value='/web/cop/bbsWeb/selectBoardDetail.do'/>";
document.frm.submit();
}
@ -346,14 +338,14 @@ function fn_egov_inqire_data(bbsId, nttId) {
</div>
<div class="banner_wrap">
<a href="#" class="banner green">
<a href="<c:url value="/web/my/myQnaMngRegist.do"/>" class="banner green">
<i></i>
<div class="text_area">
<p class="title">교육문의</p>
<span class="summary">교육에 관해 궁금하시다면 글을 남겨주세요.</span>
</div>
</a href="#">
<a href="#" class="banner blue">
<a href="<c:url value="/web/cop/bbsWeb/selectBoardList.do?bbsId=BBSMSTR_000000000030"/>" class="banner blue">
<i></i>
<div class="text_area">
<p class="title">자주 받는 질문</p>
@ -369,70 +361,34 @@ function fn_egov_inqire_data(bbsId, nttId) {
<div class="list_wrap">
<div class="main_title">
<h2 class="title">공지사항</h2>
<a href="#" class="btn btn_plus" title="공지사항 페이지 이동"><i></i></a>
<a href="<c:url value="/web/cop/bbsWeb/selectBoardList.do?bbsId="/><c:out value="${noticeBbsUrl}"/>" class="btn btn_plus" title="공지사항 페이지 이동"><i></i></a>
</div>
<ul class="list">
<c:forEach var="notiList" items="${bbsList}" varStatus="sts">
<c:forEach var="notiList" items="${noticeBbsList}" varStatus="sts">
<li>
<a href="#">
<strong class="title">2025 대전지역 도메인이름 분쟁조정(DNDR) 세미나 </strong>
<p class="date">2025.09.12</p>
<a href="#" onclick="javascript:fn_egov_inqire_notice('<c:out value="${notiList.bbsId}"/>', '<c:out value="${notiList.nttId}"/>');">
<strong class="title"><c:out value="${notiList.nttSj}"/></strong>
<p class="date"><c:out value="${notiList.frstRegisterPnttm}"/></p>
</a>
</li>
</c:forEach>
<li>
<a href="#">
<strong class="title">특허분쟁 위험경보 시스템 회원가입 이벤트(6/16~6/30) </strong>
<p class="date">2025.08.13</p>
</a>
</li>
<li>
<a href="#">
<strong class="title">[특허청/한국특허정보원] 제21회 국제특허정보박람회 개최(P </strong>
<p class="date">2025.08.01</p>
</a>
</li>
<li>
<a href="#">
<strong class="title">2025년 상반기 의약품 허가특허연계제도 교육 모집 공고 </strong>
<p class="date">2025.07.24</p>
</a>
</li>
</ul>
</div>
<div class="list_wrap">
<div class="main_title">
<h2 class="title">교육 자료실</h2>
<a href="#" class="btn btn_plus" title="교육 자료실 페이지 이동"><i></i></a>
<a href="<c:url value="/web/cop/bbsWeb/selectBoardList.do?bbsId="/><c:out value="${atchBbsUrl}"/>" class="btn btn_plus" title="교육 자료실 페이지 이동"><i></i></a>
</div>
<ul class="list">
<li>
<a href="#">
<strong class="title">[자료] 2025년 상표권 조건부 기소유예 교육자료</strong>
<p class="date">2025.09.12</p>
</a>
</li>
<li>
<a href="#">
<strong class="title">[보도자료] 반도체 등 국가 중요기술 해외유출 방지 성과 특허 </strong>
<p class="date">2025.08.13</p>
</a>
</li>
<li>
<a href="#">
<strong class="title">[자료] 상표권 침해 부정경쟁행위 예방교육 7차 자료</strong>
<p class="date">2025.08.01</p>
</a>
</li>
<li>
<a href="#">
<strong class="title">[자료] 시정명령 관련 자료</strong>
<p class="date">2025.07.24</p>
</a>
</li>
<c:forEach var="atchList" items="${atchBbsList}" varStatus="sts">
<li>
<a href="#" onclick="javascript:fn_egov_inqire_notice('<c:out value="${atchList.bbsId}"/>', '<c:out value="${atchList.nttId}"/>');">
<strong class="title"><c:out value="${atchList.nttSj}"/></strong>
<p class="date"><c:out value="${atchList.frstRegisterPnttm}"/></p>
</a>
</li>
</c:forEach>
</ul>
</div>
</div>
@ -469,8 +425,8 @@ function fn_egov_inqire_data(bbsId, nttId) {
<!-- //사이트 슬라이드 -->
<form name="frm" action="<c:url value='/web/cop/bbsWeb/selectBoardList.do'/>" method="post">
<input type="hidden" name="bbsId" value="" />
<input type="hidden" name="nttId" value="" />
<input type="hidden" name="pageIndex" value="1" />
<input type="hidden" name="bbsId" value="" />
<input type="hidden" name="nttId" value="0" />
<input type="hidden" name="pageIndex" value="1" />
</form>
</html>

View File

@ -151,26 +151,11 @@
//이수증 출력
function fncPrintCert(
id //aplctOrd
, chId //chasiOrd
, p_site_id_cd //10,20,30
, p_action //select, insert
, p_qustnrTmplatId //select, insert
, p_qestnrId //select, insert
, p_qustnrRespondId //select, insert
prcsAplctPrdOrd //aplctOrd
){
paramObj = {
"eduAplctOrd" : id
,"eduChasiOrd" : chId
,"siteIdCd" : p_site_id_cd
,"siteId" : "60" //설문정보를 위해서 설문지의 대상값을 넣는다. VE0011 10-청소년, 20-성인,30-체험, 40-외부, 50-기반, 60-기소
,"action" : p_action
,"qustnrTmplatId" : p_qustnrTmplatId
,"qestnrId" : p_qestnrId
,"qustnrRespondId" : p_qustnrRespondId
"prcsAplctPrdOrd" : prcsAplctPrdOrd
};
commonPopLayeropen(
@ -318,9 +303,7 @@
<c:choose>
<c:when test="${list.qestRsltExists }">
<button type="button" class="btn small mint line sur_bt" data-info="${list.eduAplctOrd}" data-tooltip="sub36_pop02"
onclick="fncPrintCert('${list.eduAplctOrd}','${list.eduChasiOrd}','10','insert'
,'${list.qustnrTmplatId}','${list.qestnrId10}',''
)" title="출력">출력</button>
onclick="fncPrintCert('${list.prcsAplctPrdOrd}')" title="출력">출력</button>
</c:when>
<c:when test="${list.dateChk eq 1 and not list.qestRsltExists}">
교육완료

View File

@ -25,60 +25,19 @@
<script type="text/javascript" src="${pageContext.request.contextPath}/kccadrPb/usr/script/popup.js"></script>
<link rel="stylesheet" href="${pageContext.request.contextPath}/publish/css/estimate.css">
<link rel="stylesheet" href="${pageContext.request.contextPath}/publish/css/font.css">
<link rel="stylesheet" href="${pageContext.request.contextPath}/publish/css/button.css">
<link rel="stylesheet" href="${pageContext.request.contextPath}/publish/css/estimate.css">
<link rel="stylesheet" href="${pageContext.request.contextPath}/publish/css/font.css">
<link rel="stylesheet" href="${pageContext.request.contextPath}/publish/css/button.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/1.4.1/html2canvas.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.5.1/jspdf.umd.min.js"></script>
<script type="text/javaScript" language="javascript">
/*
function fncGoScholList(){
linkPage(1);
}
function linkPage(pageNo){
var data = {
pageIndex : pageNo,
searchKeyword : $("#searchKeyword").val(),
searchCondition : $("#searchCondition").val(),
pageUnit : 5,
formId : $("#formId").val(),
}
fncScholList(data);
}
function fncScholList(paramObj) {
if(paramObj == undefined || paramObj == ''){
paramObj = {
pageIndex : 1,
searchKeyword : "",
searchCondition : "",
pageUnit : 5,
formId : $("#formId").val(),
};
}
// 학교 리스트 팝업 호출
commonPopLayeropen(
"${pageContext.request.contextPath}/web/ve/aplct/cpyrgExprnClsrm/scholInfo/popup/scholPopList.do"
, 500
, 600
, paramObj
, "N"
, "scholPop"
);
}
*/
function fncScholDataSlct_back(p_code, p_nm){
var fNm = "#"+$("#formId").val();
$(fNm + " #stndrdScholCd").val(p_code);
$(fNm + " #scholInsttNm").val(p_nm);
$(".btn_popup_close").click();
}
@ -94,118 +53,18 @@
}
function replyCalculation(){
/*
var qestnrParticipant = $("#qestnrParticipant").val(); //참석자 수량
var qestnrRespondent = $("#qestnrRespondent").val(); //응답자 수량
if(qestnrParticipant == "" || qestnrParticipant == null){
alert("참석자 수량을 넣어주세요");
$("#qestnrParticipant").focus();
return
}
if(qestnrRespondent == "" || qestnrRespondent == null){
alert("응답자 수량을 넣어주세요");
$("#qestnrParticipant").focus();
return
}
if(Number(qestnrParticipant) < Number(qestnrRespondent)){
alert("응답자 수량이 참석자 수량보다 많습니다.");
$("#qestnrParticipant").focus();
return
}
var responseRateTxt = (Number(qestnrRespondent) / Number(qestnrParticipant)*Number(100)).toFixed(1);
$("#responseRate").text(responseRateTxt + "%");
$("#noResponse").text(Number(qestnrParticipant) - Number(qestnrRespondent));
*/
/* 필요 시 사용 */
}
function popupSrvySendSubmit(){
var v_qestmSize = parseInt('${chasiSrvyListCnt}'); //평가문항 수량
var v_sum = 0;
//var qestmSize = parseInt($("#qestmInfoSize").val()); //평가문항 수량
//var qestnrParticipant = parseInt($("#qestnrParticipant").val()); //참석자 수량
//var qestnrRespondent = parseInt($("#qestnrRespondent").val()); //응답자 수량
/*
if(qestnrParticipant == null || qestnrParticipant == ""){
alert("참석자 수량을 넣어주세요");
$("#qestnrParticipant").focus();
return
}
if(qestnrRespondent == null || qestnrRespondent == ""){
alert("응답자 수량을 넣어주세요");
$("#qestnrRespondent").focus();
return
}
if(qestnrParticipant < qestnrRespondent){
alert("응답자 수량이 참석자 수보다 많습니다 확인해 주세요");
$("#qestnrRespondent").focus();
return
}
*/
for(var i=0; i < v_qestmSize; i++){
//var verySatisfied = $("#verySatisfied_"+i).val();
//var satisfied = $("#satisfied_"+i).val();
//var neither = $("#neither_"+i).val();
//var dissatisfied = $("#dissatisfied_"+i).val();
//var veryDissatisfied = $("#veryDissatisfied_"+i).val();
var radioNumber = $("input:radio[name='resultList["+i+"].responseRadio']:checked").val(); // 체크된 value
//alert(radioNumber);
/*
if(verySatisfied == null || verySatisfied == ""){
alert((i+1)+"번 [매우만족] 만족도를 정확히 넣어주세요");
$("#verySatisfied_"+i).focus();
return
}
if(satisfied == null || satisfied == ""){
alert((i+1)+"번 [만족] 만족도를 정확히 넣어주세요");
$("#satisfied_"+i).focus();
return
}
if(neither == null || neither == ""){
alert((i+1)+"번 [보통] 만족도를 정확히 넣어주세요");
$("#neither_"+i).focus();
return
}
if(dissatisfied == null || dissatisfied == ""){
alert((i+1)+"번 [불만족] 만족도를 정확히 넣어주세요");
$("#dissatisfied_"+i).focus();
return
}
if(veryDissatisfied == null || veryDissatisfied == ""){
alert((i+1)+"번 [매우불만족] 만족도를 정확히 넣어주세요");
$("#veryDissatisfied_"+i).focus();
return
}
*/
//var sum = Number(verySatisfied) + Number(satisfied) + Number(neither) + Number(dissatisfied) + Number(veryDissatisfied);
radioNumber = Number(radioNumber);
if (radioNumber){
v_sum = v_sum + 1;
}
if (radioNumber){ v_sum = v_sum + 1; }
}
//alert(v_sum);
//alert(v_qestmSize);
if(v_qestmSize != v_sum ){
alert("문항의 합계가 응답수량과 맞지 않습니다.");
@ -214,31 +73,26 @@
}
if(confirm("설문결과를 등록 하시겠습니까?")){
// var frm = document.newSrvyPopupForm;
var data = new FormData(document.getElementById("newSrvyPopupForm"));
$.ajax({
type:"POST"
//,url:"${pageContext.request.contextPath}/web/ve/aplct/tngrVisitEdu/eduEnd/insertNewSrvyInfoAjax.do"
,url:"${pageContext.request.contextPath}/web/ve/aplct/tngrVisitEdu/eduEnd/insertNewSrvyFndtnInfoEAAjax.do"
,data: data
,dataType:'json'
,async: false
,processData: false
,contentType: false
,cache: false
,success:function(returnData){
type:"POST",
url:"${pageContext.request.contextPath}/web/ve/aplct/tngrVisitEdu/eduEnd/insertNewSrvyFndtnInfoEAAjax.do",
data: data,
dataType:'json',
async: false,
processData: false,
contentType: false,
cache: false,
success:function(returnData){
if(returnData.result == 'success'){
//alert("설문결과가 등록 되었습니다.");
fn_statusChg();
//window.location.reload();
}else if(returnData.result == 'fail'){
alert(returnData.msg);
location.href="/web/user/login/ssoLogin.do?test=test";
}
}
,error:function(request , status, error){
},
error:function(request , status, error){
alert("code:"+request.status+"\n"+"message:"+request.responseText+"\n"+"error:"+error);
}
});
@ -248,249 +102,276 @@
// 기반 / 기소 공통
function fn_statusChg(){
var data = new FormData(document.getElementById("statusChgForm"));
var url = "${pageContext.request.contextPath}/web/ve/aplct/tngrVisitEdu/eduEnd/updateAplctStateCdAjax.do";
$.ajax({
type:"POST",
url: url,
data: data,
dataType:'json',
async: false,
processData: false,
contentType: false,
cache: false,
success:function(returnData){
if(returnData.result == "success"){
alert("설문결과가 등록 되었습니다.");
//alert("변경되었습니다.");
// 새로고침
window.location.reload();
}
},
error:function(request , status, error){
alert("code:"+request.status+"\n"+"message:"+request.responseText+"\n"+"error:"+error);
}
});
//event.stopImmediatePropagation();
var url = "${pageContext.request.contextPath}/web/ve/aplct/tngrVisitEdu/eduEnd/updateAplctStateCdAjax.do";
$.ajax({
type:"POST",
url: url,
data: data,
dataType:'json',
async: false,
processData: false,
contentType: false,
cache: false,
success:function(returnData){
if(returnData.result == "success"){
alert("설문결과가 등록 되었습니다.");
window.location.reload();
}
},
error:function(request , status, error){
alert("code:"+request.status+"\n"+"message:"+request.responseText+"\n"+"error:"+error);
}
});
}
$(document).ready(function(){
/*
boardCaptionDetailToggle4();
// 레이어팝업 포커싱 이동 수정
$(".tooltip-close").click(function(){
var activeTarget = $('[data-tooltip-con="sub36_pop02"]');
activeTarget.hide();
$('[data-tooltip="sub01_pop02"]').focus();
});
//레이어팝업 초정 이동 시 필요한 data 값 추가
var btnLast = $('.popup_cont').find('.page').find('button:last-child');
btnLast.attr('data-focus-next','sub36_pop02');
btnLast.attr('data-focus','sub36_pop02_close');
*/
// 레이어팝업 포커싱 이동 수정
$(".tooltip-close").click(function(){
var activeTarget = $('[data-tooltip-con="sub36_pop02"]');
activeTarget.hide();
$('[data-info="${vEEduChasiVO.eduAplctOrd}"]').focus();
});
})
$(document).ready(function(){
// 레이어팝업 포커싱 이동 수정
$(".tooltip-close").click(function(){
var activeTarget = $('[data-tooltip-con="sub36_pop02"]');
activeTarget.hide();
$('[data-info="${vEEduChasiVO.eduAplctOrd}"]').focus();
});
})
function f_print(){
document.getElementById('est_btn_wrap').style.display = 'none';
//var initBody = document.body.innerHTML;
var initBody = document.getElementById('divBody').innerHTML;
window.onbeforeprint = function(){
// print_area는 인쇄하고자 하는 영역의 ID를 말합니다.( 필수 )
// document.body.innerHTML = document.getElementById("print_area").innerHTML;
}
window.onafterprint = function(){
document.body.innerHTML = initBody;
}
window.print();
document.getElementById('est_btn_wrap').style.display = '';
}
function f_print(){
document.getElementById('est_btn_wrap').style.display = 'none';
var initBody = document.getElementById('divBody').innerHTML;
window.onbeforeprint = function(){ }
window.onafterprint = function(){ document.body.innerHTML = initBody; }
window.print();
document.getElementById('est_btn_wrap').style.display = '';
}
function downloadPDF() {
const element = document.getElementById('divBody'); // PDF로 변환하고자 하는 HTML 요소를 선택합니다. 예: document.getElementById('your-element-id')
function downloadPDF() {
const element = document.getElementById('divBody');
html2canvas(element).then((canvas) => {
const imgData = canvas.toDataURL('image/png');
const pdf = new jspdf.jsPDF();
const imgProps= pdf.getImageProperties(imgData);
const pdfWidth = pdf.internal.pageSize.getWidth();
const pdfHeight = (imgProps.height * pdfWidth) / imgProps.width;
pdf.addImage(imgData, 'PNG', 0, 0, pdfWidth, pdfHeight);
pdf.save("download.pdf");
});
}
html2canvas(element).then((canvas) => {
const imgData = canvas.toDataURL('image/png');
const pdf = new jspdf.jsPDF();
const imgProps= pdf.getImageProperties(imgData);
const pdfWidth = pdf.internal.pageSize.getWidth();
const pdfHeight = (imgProps.height * pdfWidth) / imgProps.width;
async function savePDF() {
document.getElementById('est_btn_wrap').style.display = 'none';
const { jsPDF } = window.jspdf;
const element = document.getElementById('divBody');
pdf.addImage(imgData, 'PNG', 0, 0, pdfWidth, pdfHeight);
pdf.save("download.pdf");
});
}
const originalScrollY = window.scrollY;
window.scrollTo(0, 0);
async function savePDF() {
document.getElementById('est_btn_wrap').style.display = 'none';
const { jsPDF } = window.jspdf;
const element = document.getElementById('divBody');
const canvas = await html2canvas(element, {
scale: 2,
useCORS: true,
windowWidth: document.documentElement.scrollWidth,
windowHeight: document.documentElement.scrollHeight
});
// 스크롤 영역 전체 캡처를 위해 overflow 제거
const originalScrollY = window.scrollY;
window.scrollTo(0, 0);
window.scrollTo(0, originalScrollY);
const canvas = await html2canvas(element, {
scale: 2, // 해상도 향상
useCORS: true,
windowWidth: document.documentElement.scrollWidth,
windowHeight: document.documentElement.scrollHeight
});
const imgData = canvas.toDataURL('image/png');
const pdf = new jsPDF('p', 'mm', 'a4');
const pdfWidth = pdf.internal.pageSize.getWidth();
const pdfHeight = pdf.internal.pageSize.getHeight();
window.scrollTo(0, originalScrollY);
const imgWidth = pdfWidth;
const imgHeight = canvas.height * pdfWidth / canvas.width;
const imgData = canvas.toDataURL('image/png');
const pdf = new jsPDF('p', 'mm', 'a4');
const pdfWidth = pdf.internal.pageSize.getWidth();
const pdfHeight = pdf.internal.pageSize.getHeight();
// 캔버스의 크기 비율에 따라 페이지 분할
const imgWidth = pdfWidth;
const imgHeight = canvas.height * pdfWidth / canvas.width;
let heightLeft = imgHeight;
let position = 0;
pdf.addImage(imgData, 'PNG', 0, position, imgWidth, imgHeight);
heightLeft -= pdfHeight;
while (heightLeft > 0) {
position = heightLeft - imgHeight;
pdf.addPage();
pdf.addImage(imgData, 'PNG', 0, position, imgWidth, imgHeight);
heightLeft -= pdfHeight;
}
pdf.save('page.pdf');
document.getElementById('est_btn_wrap').style.display = '';
}
async function makePDF() {
const { jsPDF } = window.jspdf;
const element = document.getElementById("divBody");
// 1⃣ body에 임시 클론을 붙여서 화면 밖에서도 렌더링되도록 함
const cloned = element.cloneNode(true);
const container = document.createElement('div');
// pdf style 적용이 안되서 추가
const styleEl = document.createElement('style');
styleEl.innerHTML = `
.estimate{padding:30px 3%;}
.estimate *{font-family: 'HYgsrB', sans-serif !important; color:#222 !important;}
.est_body{position:relative; padding:50px 0; text-align:left;}
.est_body h2{font-size:44px; -webkit-text-stroke-width:0.05px; -webkit-text-stroke-color:#222; text-align:center;}
.est_body .cont1>div p{width:100%;margin:0 0 8px 30px;text-align:left;line-height: 1.5;}
.est_body .cont5 div{display:block;}
.est_body .cont5 div span:first-child{font-size:18px; font-weight:700; line-height: 1.5; color:#222; margin:0 0 10px 30px; display:block;text-align:left;}
.estimate_popup .est_body .cont5.user_info{display:block;margin:50px 0 0 30px;}
.estimate_popup .est_body .cont5.user_info div{width:100%;justify-content:flex-start;font-size:18px;font-weight:700;line-height:1.5;margin:0 0 4px 0;}
.estimate_popup .est_body .cont5.user_info div span:nth-child(1){font-size:18px;font-weight:700;margin:0;}
.est_body .cont5.substance>div{margin:100px 0; text-align:center;}
.est_body .cont5.substance>div p{font-size:20px; font-weight:700; color:#222; margin:0 50px; line-height:1.5; text-align:justify; letter-spacing:1px;}
.est_body .cont5 .date{font-size:18px; font-weight:700; color:#222; display:block; text-align:center; margin-bottom:10px;}
.est_body .cont5 .date+div{text-align:center;margin:0 auto;}
.est_body .cont5 .date+div span{display:inline-block;font-size:32px;text-align:center;}
.est_body .cont5 .big_stamp{font-size:22px;margin:0 0 0 -6px;}`;
cloned.prepend(styleEl);
container.style.position = 'absolute';
container.style.top = '0';
container.style.left = '0';
container.style.width = element.scrollWidth + 'px';
container.style.height = 'auto';
container.style.background = 'white';
container.style.zIndex = '-1';
container.style.overflow = 'visible';
container.style.fontFamily = "'HYgsrB', sans-serif";
container.style.fontWeight = '700';
container.style.opacity = '0';
container.appendChild(cloned);
document.body.appendChild(container);
// 2⃣ 클론 기준으로 html2canvas 렌더링
const canvas = await html2canvas(cloned, {
scale: 2,
useCORS: true,
scrollX: 0,
scrollY: 0,
windowWidth: cloned.scrollWidth,
windowHeight: cloned.scrollHeight,
backgroundColor: "#ffffff",
});
// 3⃣ 임시 클론 제거
document.body.removeChild(container);
// 4⃣ PDF 생성
const imgData = canvas.toDataURL("image/png");
const watermarkImg = await loadImage('/ipedu/visitEdu/usr/publish/images/content/watermark.png'); // 추가
const pdf = new jsPDF("p", "mm", "a4");
const pdfWidth = pdf.internal.pageSize.getWidth();
const pdfHeight = pdf.internal.pageSize.getHeight();
const imgProps = pdf.getImageProperties(imgData);
const imgWidth = pdfWidth;
const imgHeight = (imgProps.height * pdfWidth) / imgProps.width;
//alert(pdfWidth);
//alert(pdfHeight);
//const imgHeight = pdfHeight;
//alert(imgWidth);
//alert(imgHeight);
let heightLeft = imgHeight;
let position = 0;
const yOffset = (pdfHeight - imgHeight) / 2;
/*
pdf.addImage(imgData, "PNG", 0, yOffset, imgWidth, imgHeight);
heightLeft -= pdfHeight;
*/
while (heightLeft > 0) {
position = heightLeft - imgHeight;
pdf.addImage(imgData, "PNG", 0, position, imgWidth, imgHeight);
pdf.addImage(watermarkImg, 'PNG', pdfWidth / 2 - 40, pdfHeight / 2 - 40, 80, 80);
let heightLeft = imgHeight;
let position = 0;
pdf.addImage(imgData, 'PNG', 0, position, imgWidth, imgHeight);
heightLeft -= pdfHeight;
if (heightLeft > 0) pdf.addPage();
}
pdf.save("divBody_전체.pdf");
}
// 워터마크 이미지 로드 함수
function loadImage(src) {
return new Promise((resolve, reject) => {
const img = new Image();
img.crossOrigin = "anonymous";
img.onload = () => resolve(img);
img.onerror = reject;
img.src = src;
});
}
while (heightLeft > 0) {
position = heightLeft - imgHeight;
pdf.addPage();
pdf.addImage(imgData, 'PNG', 0, position, imgWidth, imgHeight);
heightLeft -= pdfHeight;
}
pdf.save('page.pdf');
document.getElementById('est_btn_wrap').style.display = '';
}
/* =========================
A4 꽉 채우기 + 최하단 고정 버전
========================= */
async function makePDF() {
const { jsPDF } = window.jspdf;
const element = document.getElementById("divBody");
// 화면 밖 렌더용 클론
const cloned = element.cloneNode(true);
const container = document.createElement('div');
// PDF 전용 스타일 (오른쪽 넘침 방지: 좌우 여백은 padding으로만)
const styleEl = document.createElement('style');
// makePDF() 내부
styleEl.innerHTML = `
/* 전역 초기화 */
html, body { margin:0; padding:0; background:#fff; }
/* A4 고정 캔버스(바깥 회색 배경과 구분되는 실제 페이지 영역) */
.estimate{
width:794px; /* 210mm @96dpi ≈ 794px */
height:1123px; /* 297mm @96dpi ≈ 1123px */
position:relative;
background:#fff;
overflow:hidden; /* 바깥으로 나가는 것 전부 컷 */
margin:0 auto;
display:flex;
align-items:stretch;
justify-content:stretch;
}
/* 위/아래 여백 동기화용 기준값(원하면 24px↔6mm 정도) */
.est_body{ --edge-gap: 24px; }
/* 실제 내용 박스: 내부로 0.5% 축소 + inset으로 테두리 */
.est_body{
width:100%;
height:100%;
box-sizing:border-box;
border:none !important; /* border 제거(오차 방지) */
box-shadow: inset 0 0 0 1px #000; /* 레이아웃 영향 없는 테두리 */
background:#fff;
display:flex; flex-direction:column;
justify-content:flex-start;
padding: 0 44px; /* 좌우 여백(약 12mm) */
overflow:hidden;
word-break:keep-all; overflow-wrap:break-word;
/* ★ 핵심: 살짝 축소해 A4 밖으로 절대 안 나가게 */
transform: translateZ(0) scale(0.995);
transform-origin: center top; /* 위에서부터 쌓이니 상단 기준 */
}
.est_body *{ font-family:'HYgsrB', sans-serif !important; color:#222 !important; box-sizing:border-box; }
/* 상단 번호 라인: 좌우 margin 제거, 위 여백은 edge-gap */
.cont1.tb_ver2 { margin: var(--edge-gap) 0 0 0 !important; }
.cont1.tb_ver2 > div p{
margin: 0 0 16px 0; /* 좌우 margin 제거 */
line-height:1.5; font-size:16px;
}
/* 제목 */
.est_body h2{
font-size:44px; text-align:center;
-webkit-text-stroke-width:0.05px; -webkit-text-stroke-color:#222;
margin:48px 0 24px; /* 대략 16mm / 6mm */
}
/* 사용자 정보: 좌우 margin 제거 */
.cont5.user_info{ display:block; margin:24px 0 0 0; }
.cont5.user_info div{ font-size:18px; font-weight:700; line-height:1.5; margin:0 0 8px 0; }
/* 본문 문구: 좌우 margin 제거, 정렬은 padding으로 */
.cont5.substance > div{ margin:32px 0; text-align:center; }
.cont5.substance > div p{
font-size:18px; font-weight:700; margin:0;
line-height:1.5; text-align:justify; letter-spacing:0.2px;
}
/* 하단(날짜/원장명/도장): 최하단 고정 + 바닥에서 edge-gap 만큼 띄우기 */
.cont5.footer{
margin-top:auto;
text-align:center;
padding-top:40px; /* ≈10mm */
padding-bottom: var(--edge-gap); /* 위쪽 번호 여백과 동일 간격 */
}
.cont5.footer .date{
font-size:18px; font-weight:700; margin:0 0 24px 0; display:block; text-align:center;
}
.cont5.footer .sign-row{ text-align:center; margin:0 auto; }
.cont5.footer .sign-row span{ display:inline-block; font-size:28px; vertical-align:middle; }
.cont5.footer .big_stamp img{ width:136px; height:auto; margin-left:16px; vertical-align:middle; } /* ≈36mm */
/* 이미지 우측 삐져나옴 방지 */
img{ max-width:100%; height:auto; display:inline-block; }
`;
cloned.prepend(styleEl);
// 렌더 컨테이너 (A4 고정)
container.style.position = 'absolute';
container.style.top = '0';
container.style.left = '0';
container.style.width = '210mm';
container.style.height = '297mm';
container.style.background = '#ffffff';
container.style.zIndex = '-1';
container.style.overflow = 'hidden';
container.style.opacity = '0';
container.appendChild(cloned);
document.body.appendChild(container);
// 캔버스 생성
const canvas = await html2canvas(cloned, {
scale: 2,
useCORS: true,
scrollX: 0,
scrollY: 0,
windowWidth: cloned.scrollWidth,
windowHeight: cloned.scrollHeight,
backgroundColor: "#ffffff",
});
// 임시 클론 제거
document.body.removeChild(container);
// PDF 생성 + 워터마크
const imgData = canvas.toDataURL("image/png");
const pdf = new jsPDF("p", "mm", "a4");
const pdfWidth = pdf.internal.pageSize.getWidth();
const pdfHeight = pdf.internal.pageSize.getHeight();
// 워터마크 로드
/* let watermarkImg = null;
try {
watermarkImg = await loadImage('/ipedu/visitEdu/usr/publish/images/content/watermark.png');
} catch (e) { } */
// 내용 먼저
pdf.addImage(imgData, "PNG", 0, 0, pdfWidth, pdfHeight);
const watermarkImg = await loadImage('/ipedu/visitEdu/usr/publish/images/content/watermark.png'); // 추가
pdf.addImage(watermarkImg, 'PNG', pdfWidth/2 - 40, pdfHeight/2 - 40, 80, 80);
// 워터마크(중앙, 반투명)
/* if (watermarkImg) {
try {
const g = pdf.GState ? new pdf.GState({ opacity: 0.12 }) : null;
if (g && pdf.setGState) pdf.setGState(g);
pdf.addImage(watermarkImg, 'PNG', pdfWidth/2 - 40, pdfHeight/2 - 40, 80, 80);
if (g && pdf.setGState) pdf.setGState(new pdf.GState({ opacity: 1 }));
} catch (e) {
pdf.addImage(watermarkImg, 'PNG', pdfWidth/2 - 40, pdfHeight/2 - 40, 80, 80);
}
} */
pdf.save("교육이수증.pdf");
}
// 워터마크 이미지 로드 함수(옵션)
function loadImage(src) {
return new Promise((resolve, reject) => {
const img = new Image();
img.crossOrigin = "anonymous";
img.onload = () => resolve(img);
img.onerror = reject;
img.src = src;
});
}
</script>
<!-- 일정 상세 -->
<form id="statusChgForm" name="statusChgForm" method="post">
<input type="hidden" name="prcsAplctPrdOrd" id="prcsAplctPrdOrd" value="<c:out value='${chasiSrvyList[0].prcsAplctPrdOrd}' />"/>
@ -507,7 +388,6 @@ function loadImage(src) {
<input type="hidden" name="qestnrId" id="qestnrId" value="${chasiSrvyList[0].qestnrId}">
<input type="hidden" name="qestmInfoSize" id="qestmInfoSize" value="${fn:length(chasiSrvyList)}">
<div class="popup_wrap popType01 estimate_popup" data-info="${vEEduChasiVO.eduAplctOrd}" data-tooltip-con="sub36_pop02" data-focus="sub36_pop02" data-focus-prev="sub36_pop02_close" id="popup_cont">
<div class="popup_tit">
@ -521,30 +401,26 @@ function loadImage(src) {
<div class="estimate" id="divBody">
<div class="cont2 clearfix">
<!-- <div class="est_head clearfix">
<img src="/publish/images/CI.png" alt="문자온 CI">
<div class="clearfix">
<p>&nbsp;</p>
<p>&nbsp;</p>
</div>
</div> -->
<div class="est_body" style="border:1px solid black">
<div class="cont1 tb_ver2" style="margin-top:10px;">
<div>
<p><기소유예-2025-00083></p>
<!-- <p><기소유예-2025-00083></p> -->
<p>
<<kc:code codeId="VE0011" code="${completeDocDetail.lctrDivCd}"/>-<c:out value="${completeDocDetail.eduCmpltCrtfcNmbr}"/>>
</p>
</div>
</div>
<h2>교 육 이 수 증</h2>
<div class="cont5 user_info">
<div>
<span>수료과목 : 조건부 기소유예 10기</span>
<span>수료과목 : <c:out value="${completeDocDetail.title}"/></span>
</div>
<div>
<span>성 명: 조건부 기소유예 10기</span>
<span>성 명: <c:out value="${completeDocDetail.chrgNm}"/></span>
</div>
<div>
<span>교육일시 : 2025.10.25</span>
<span>교육일시 : <c:out value="${completeDocDetail.eduStrtPnttm}"/></span>
</div>
</div>
@ -552,19 +428,20 @@ function loadImage(src) {
<div>
<p>
위 사람은 한국지식재산보호원 지식재산 보호 교육 시스템에서
진행하는 '조건부 기소유예 10기'를 수료 하였기에 위 교육이수증을 드립니다.
진행하는 '<c:out value="${completeDocDetail.title}"/>'를 수료 하였기에 위 교육이수증을 드립니다.
</p>
</div>
</div>
<div class="cont5">
<p class="date">2025년 10월 7일</p>
<div>
<span>한국지식재산보호원장</span>
<!-- ★★★ 최하단 고정 푸터 영역 ★★★ -->
<div class="cont5 footer">
<p class="date">${todayStr}</p>
<div class="sign-row">
<span>한국지식재산보호원장</span>
<span class="big_stamp">
<img src="/ipedu/visitEdu/usr/publish/images/content/stamp.png">
<img src="/ipedu/visitEdu/usr/publish/images/content/stamp.png" alt="도장">
</span>
</div>
<!-- <div style="height:1500px;background:skyblue;">여러장 test</div> -->
</div>
</div>
</div>

View File

@ -0,0 +1,586 @@
<%--
Class Name : qustnrFndtnPopList.jsp
Description : 설문팝업
Modification Information
1.강의 종류(청소년, 성인 ... VE0011) 및 설문 종류 (10-기본, 20-신청자, 30-강사) 및 상태(등록, 완료) 에 맞는 설문 레이어 팝업을 만든다.
수정일 수정자 수정내용
------- -------- ---------------------------
2021.12.02 조용준 내용
author : 조용준
since : 2021.12.02
--%>
<%@ page contentType="text/html; charset=utf-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="ui" uri="http://egovframework.gov/ctl/ui"%>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions"%>
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>
<%@ taglib prefix="kc" uri="/WEB-INF/tlds/kcc_tld.tld"%>
<script type="text/javascript" src="${pageContext.request.contextPath}/kccadrPb/usr/script/popup.js"></script>
<link rel="stylesheet" href="${pageContext.request.contextPath}/publish/css/estimate.css">
<link rel="stylesheet" href="${pageContext.request.contextPath}/publish/css/font.css">
<link rel="stylesheet" href="${pageContext.request.contextPath}/publish/css/button.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/1.4.1/html2canvas.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.5.1/jspdf.umd.min.js"></script>
<script type="text/javaScript" language="javascript">
/*
function fncGoScholList(){
linkPage(1);
}
function linkPage(pageNo){
var data = {
pageIndex : pageNo,
searchKeyword : $("#searchKeyword").val(),
searchCondition : $("#searchCondition").val(),
pageUnit : 5,
formId : $("#formId").val(),
}
fncScholList(data);
}
function fncScholList(paramObj) {
if(paramObj == undefined || paramObj == ''){
paramObj = {
pageIndex : 1,
searchKeyword : "",
searchCondition : "",
pageUnit : 5,
formId : $("#formId").val(),
};
}
// 학교 리스트 팝업 호출
commonPopLayeropen(
"${pageContext.request.contextPath}/web/ve/aplct/cpyrgExprnClsrm/scholInfo/popup/scholPopList.do"
, 500
, 600
, paramObj
, "N"
, "scholPop"
);
}
*/
function fncScholDataSlct_back(p_code, p_nm){
var fNm = "#"+$("#formId").val();
$(fNm + " #stndrdScholCd").val(p_code);
$(fNm + " #scholInsttNm").val(p_nm);
$(".btn_popup_close").click();
}
function fncScholDataSlct(thisObj){
var inObj = $(thisObj).closest("td").find("input[type=hidden]");
var rsObj = new Object();
$.each(inObj, function(idx, value){
console.log(value.value);
rsObj[value.name] = value.value;
});
callBackSchPop(rsObj);
$(".btn_popup_close").click();
}
function replyCalculation(){
/*
var qestnrParticipant = $("#qestnrParticipant").val(); //참석자 수량
var qestnrRespondent = $("#qestnrRespondent").val(); //응답자 수량
if(qestnrParticipant == "" || qestnrParticipant == null){
alert("참석자 수량을 넣어주세요");
$("#qestnrParticipant").focus();
return
}
if(qestnrRespondent == "" || qestnrRespondent == null){
alert("응답자 수량을 넣어주세요");
$("#qestnrParticipant").focus();
return
}
if(Number(qestnrParticipant) < Number(qestnrRespondent)){
alert("응답자 수량이 참석자 수량보다 많습니다.");
$("#qestnrParticipant").focus();
return
}
var responseRateTxt = (Number(qestnrRespondent) / Number(qestnrParticipant)*Number(100)).toFixed(1);
$("#responseRate").text(responseRateTxt + "%");
$("#noResponse").text(Number(qestnrParticipant) - Number(qestnrRespondent));
*/
}
function popupSrvySendSubmit(){
var v_qestmSize = parseInt('${chasiSrvyListCnt}'); //평가문항 수량
var v_sum = 0;
//var qestmSize = parseInt($("#qestmInfoSize").val()); //평가문항 수량
//var qestnrParticipant = parseInt($("#qestnrParticipant").val()); //참석자 수량
//var qestnrRespondent = parseInt($("#qestnrRespondent").val()); //응답자 수량
/*
if(qestnrParticipant == null || qestnrParticipant == ""){
alert("참석자 수량을 넣어주세요");
$("#qestnrParticipant").focus();
return
}
if(qestnrRespondent == null || qestnrRespondent == ""){
alert("응답자 수량을 넣어주세요");
$("#qestnrRespondent").focus();
return
}
if(qestnrParticipant < qestnrRespondent){
alert("응답자 수량이 참석자 수보다 많습니다 확인해 주세요");
$("#qestnrRespondent").focus();
return
}
*/
for(var i=0; i < v_qestmSize; i++){
//var verySatisfied = $("#verySatisfied_"+i).val();
//var satisfied = $("#satisfied_"+i).val();
//var neither = $("#neither_"+i).val();
//var dissatisfied = $("#dissatisfied_"+i).val();
//var veryDissatisfied = $("#veryDissatisfied_"+i).val();
var radioNumber = $("input:radio[name='resultList["+i+"].responseRadio']:checked").val(); // 체크된 value
//alert(radioNumber);
/*
if(verySatisfied == null || verySatisfied == ""){
alert((i+1)+"번 [매우만족] 만족도를 정확히 넣어주세요");
$("#verySatisfied_"+i).focus();
return
}
if(satisfied == null || satisfied == ""){
alert((i+1)+"번 [만족] 만족도를 정확히 넣어주세요");
$("#satisfied_"+i).focus();
return
}
if(neither == null || neither == ""){
alert((i+1)+"번 [보통] 만족도를 정확히 넣어주세요");
$("#neither_"+i).focus();
return
}
if(dissatisfied == null || dissatisfied == ""){
alert((i+1)+"번 [불만족] 만족도를 정확히 넣어주세요");
$("#dissatisfied_"+i).focus();
return
}
if(veryDissatisfied == null || veryDissatisfied == ""){
alert((i+1)+"번 [매우불만족] 만족도를 정확히 넣어주세요");
$("#veryDissatisfied_"+i).focus();
return
}
*/
//var sum = Number(verySatisfied) + Number(satisfied) + Number(neither) + Number(dissatisfied) + Number(veryDissatisfied);
radioNumber = Number(radioNumber);
if (radioNumber){
v_sum = v_sum + 1;
}
}
//alert(v_sum);
//alert(v_qestmSize);
if(v_qestmSize != v_sum ){
alert("문항의 합계가 응답수량과 맞지 않습니다.");
$("#verySatisfied_"+i).focus();
return
}
if(confirm("설문결과를 등록 하시겠습니까?")){
// var frm = document.newSrvyPopupForm;
var data = new FormData(document.getElementById("newSrvyPopupForm"));
$.ajax({
type:"POST"
//,url:"${pageContext.request.contextPath}/web/ve/aplct/tngrVisitEdu/eduEnd/insertNewSrvyInfoAjax.do"
,url:"${pageContext.request.contextPath}/web/ve/aplct/tngrVisitEdu/eduEnd/insertNewSrvyFndtnInfoEAAjax.do"
,data: data
,dataType:'json'
,async: false
,processData: false
,contentType: false
,cache: false
,success:function(returnData){
if(returnData.result == 'success'){
//alert("설문결과가 등록 되었습니다.");
fn_statusChg();
//window.location.reload();
}else if(returnData.result == 'fail'){
alert(returnData.msg);
location.href="/web/user/login/ssoLogin.do?test=test";
}
}
,error:function(request , status, error){
alert("code:"+request.status+"\n"+"message:"+request.responseText+"\n"+"error:"+error);
}
});
}
}
// 기반 / 기소 공통
function fn_statusChg(){
var data = new FormData(document.getElementById("statusChgForm"));
var url = "${pageContext.request.contextPath}/web/ve/aplct/tngrVisitEdu/eduEnd/updateAplctStateCdAjax.do";
$.ajax({
type:"POST",
url: url,
data: data,
dataType:'json',
async: false,
processData: false,
contentType: false,
cache: false,
success:function(returnData){
if(returnData.result == "success"){
alert("설문결과가 등록 되었습니다.");
//alert("변경되었습니다.");
// 새로고침
window.location.reload();
}
},
error:function(request , status, error){
alert("code:"+request.status+"\n"+"message:"+request.responseText+"\n"+"error:"+error);
}
});
//event.stopImmediatePropagation();
}
$(document).ready(function(){
/*
boardCaptionDetailToggle4();
// 레이어팝업 포커싱 이동 수정
$(".tooltip-close").click(function(){
var activeTarget = $('[data-tooltip-con="sub36_pop02"]');
activeTarget.hide();
$('[data-tooltip="sub01_pop02"]').focus();
});
//레이어팝업 초정 이동 시 필요한 data 값 추가
var btnLast = $('.popup_cont').find('.page').find('button:last-child');
btnLast.attr('data-focus-next','sub36_pop02');
btnLast.attr('data-focus','sub36_pop02_close');
*/
// 레이어팝업 포커싱 이동 수정
$(".tooltip-close").click(function(){
var activeTarget = $('[data-tooltip-con="sub36_pop02"]');
activeTarget.hide();
$('[data-info="${vEEduChasiVO.eduAplctOrd}"]').focus();
});
})
function f_print(){
document.getElementById('est_btn_wrap').style.display = 'none';
//var initBody = document.body.innerHTML;
var initBody = document.getElementById('divBody').innerHTML;
window.onbeforeprint = function(){
// print_area는 인쇄하고자 하는 영역의 ID를 말합니다.( 필수 )
// document.body.innerHTML = document.getElementById("print_area").innerHTML;
}
window.onafterprint = function(){
document.body.innerHTML = initBody;
}
window.print();
document.getElementById('est_btn_wrap').style.display = '';
}
function downloadPDF() {
const element = document.getElementById('divBody'); // PDF로 변환하고자 하는 HTML 요소를 선택합니다. 예: document.getElementById('your-element-id')
html2canvas(element).then((canvas) => {
const imgData = canvas.toDataURL('image/png');
const pdf = new jspdf.jsPDF();
const imgProps= pdf.getImageProperties(imgData);
const pdfWidth = pdf.internal.pageSize.getWidth();
const pdfHeight = (imgProps.height * pdfWidth) / imgProps.width;
pdf.addImage(imgData, 'PNG', 0, 0, pdfWidth, pdfHeight);
pdf.save("download.pdf");
});
}
async function savePDF() {
document.getElementById('est_btn_wrap').style.display = 'none';
const { jsPDF } = window.jspdf;
const element = document.getElementById('divBody');
// 스크롤 영역 전체 캡처를 위해 overflow 제거
const originalScrollY = window.scrollY;
window.scrollTo(0, 0);
const canvas = await html2canvas(element, {
scale: 2, // 해상도 향상
useCORS: true,
windowWidth: document.documentElement.scrollWidth,
windowHeight: document.documentElement.scrollHeight
});
window.scrollTo(0, originalScrollY);
const imgData = canvas.toDataURL('image/png');
const pdf = new jsPDF('p', 'mm', 'a4');
const pdfWidth = pdf.internal.pageSize.getWidth();
const pdfHeight = pdf.internal.pageSize.getHeight();
// 캔버스의 크기 비율에 따라 페이지 분할
const imgWidth = pdfWidth;
const imgHeight = canvas.height * pdfWidth / canvas.width;
let heightLeft = imgHeight;
let position = 0;
pdf.addImage(imgData, 'PNG', 0, position, imgWidth, imgHeight);
heightLeft -= pdfHeight;
while (heightLeft > 0) {
position = heightLeft - imgHeight;
pdf.addPage();
pdf.addImage(imgData, 'PNG', 0, position, imgWidth, imgHeight);
heightLeft -= pdfHeight;
}
pdf.save('page.pdf');
document.getElementById('est_btn_wrap').style.display = '';
}
async function makePDF() {
const { jsPDF } = window.jspdf;
const element = document.getElementById("divBody");
// 1 body에 임시 클론을 붙여서 화면 밖에서도 렌더링되도록 함
const cloned = element.cloneNode(true);
const container = document.createElement('div');
// pdf style 적용이 안되서 추가
const styleEl = document.createElement('style');
styleEl.innerHTML = `
.estimate{padding:30px 3%;}
.estimate *{font-family: 'HYgsrB', sans-serif !important; color:#222 !important;}
.est_body{position:relative; padding:50px 0; text-align:left;}
.est_body h2{font-size:44px; -webkit-text-stroke-width:0.05px; -webkit-text-stroke-color:#222; text-align:center;}
.est_body .cont1>div p{width:100%;margin:0 0 8px 30px;text-align:left;line-height: 1.5;}
.est_body .cont5 div{display:block;}
.est_body .cont5 div span:first-child{font-size:18px; font-weight:700; line-height: 1.5; color:#222; margin:0 0 10px 30px; display:block;text-align:left;}
.estimate_popup .est_body .cont5.user_info{display:block;margin:50px 0 0 30px;}
.estimate_popup .est_body .cont5.user_info div{width:100%;justify-content:flex-start;font-size:18px;font-weight:700;line-height:1.5;margin:0 0 4px 0;}
.estimate_popup .est_body .cont5.user_info div span:nth-child(1){font-size:18px;font-weight:700;margin:0;}
.est_body .cont5.substance>div{margin:100px 0; text-align:center;}
.est_body .cont5.substance>div p{font-size:20px; font-weight:700; color:#222; margin:0 50px; line-height:1.5; text-align:justify; letter-spacing:1px;}
.est_body .cont5 .date{font-size:18px; font-weight:700; color:#222; display:block; text-align:center; margin-bottom:10px;}
.est_body .cont5 .date+div{text-align:center;margin:0 auto;}
.est_body .cont5 .date+div span{display:inline-block;font-size:32px;text-align:center;}
.est_body .cont5 .big_stamp{font-size:22px;margin:0 0 0 -6px;}`;
cloned.prepend(styleEl);
container.style.position = 'absolute';
container.style.top = '0';
container.style.left = '0';
container.style.width = element.scrollWidth + 'px';
container.style.height = 'auto';
container.style.background = 'white';
container.style.zIndex = '-1';
container.style.overflow = 'visible';
container.style.fontFamily = "'HYgsrB', sans-serif";
container.style.fontWeight = '700';
container.style.opacity = '0';
container.appendChild(cloned);
document.body.appendChild(container);
// 클론 기준으로 html2canvas 렌더링
const canvas = await html2canvas(cloned, {
scale: 2,
useCORS: true,
scrollX: 0,
scrollY: 0,
windowWidth: cloned.scrollWidth,
windowHeight: cloned.scrollHeight,
backgroundColor: "#ffffff",
});
//임시 클론 제거
document.body.removeChild(container);
//PDF 생성
const imgData = canvas.toDataURL("image/png");
const watermarkImg = await loadImage('/ipedu/visitEdu/usr/publish/images/content/watermark.png'); // 추가
const pdf = new jsPDF("p", "mm", "a4");
const pdfWidth = pdf.internal.pageSize.getWidth();
const pdfHeight = pdf.internal.pageSize.getHeight();
const imgProps = pdf.getImageProperties(imgData);
const imgWidth = pdfWidth;
const imgHeight = (imgProps.height * pdfWidth) / imgProps.width;
//alert(pdfWidth);
//alert(pdfHeight);
//const imgHeight = pdfHeight;
//alert(imgWidth);
//alert(imgHeight);
let heightLeft = imgHeight;
let position = 0;
const yOffset = (pdfHeight - imgHeight) / 2;
/*
pdf.addImage(imgData, "PNG", 0, yOffset, imgWidth, imgHeight);
heightLeft -= pdfHeight;
*/
while (heightLeft > 0) {
position = heightLeft - imgHeight;
pdf.addImage(imgData, "PNG", 0, position, imgWidth, imgHeight);
pdf.addImage(watermarkImg, 'PNG', pdfWidth / 2 - 40, pdfHeight / 2 - 40, 80, 80);
heightLeft -= pdfHeight;
if (heightLeft > 0) pdf.addPage();
}
pdf.save("divBody_전체.pdf");
}
// 워터마크 이미지 로드 함수
function loadImage(src) {
return new Promise((resolve, reject) => {
const img = new Image();
img.crossOrigin = "anonymous";
img.onload = () => resolve(img);
img.onerror = reject;
img.src = src;
});
}
</script>
<!-- 일정 상세 -->
<form id="statusChgForm" name="statusChgForm" method="post">
<input type="hidden" name="prcsAplctPrdOrd" id="prcsAplctPrdOrd" value="<c:out value='${chasiSrvyList[0].prcsAplctPrdOrd}' />"/>
<input type="hidden" name="aplctStateCd" id="aplctStateCd" value="20"/>
<input type="hidden" name="eduAplctOrd" id="eduAplctOrd" value="${vEEduChasiVO.eduAplctOrd}">
<input type="hidden" name="lctrDivCd" value="50"/>
</form>
<form id="newSrvyPopupForm" name="newSrvyPopupForm" method="post" >
<input type="hidden" name="siteId" id="siteId" value="${vEEduChasiVO.siteId}">
<input type="hidden" name="eduAplctOrd" id="eduAplctOrd" value="${vEEduChasiVO.eduAplctOrd}">
<input type="hidden" name="eduChasiOrd" id="eduChasiOrd" value="${vEEduChasiVO.eduChasiOrd}">
<input type="hidden" name="qustnrTmplatId" id="qustnrTmplatId" value="${chasiSrvyList[0].qustnrTmplatId}">
<input type="hidden" name="qestnrId" id="qestnrId" value="${chasiSrvyList[0].qestnrId}">
<input type="hidden" name="qestmInfoSize" id="qestmInfoSize" value="${fn:length(chasiSrvyList)}">
<div class="popup_wrap popType01 estimate_popup" data-info="${vEEduChasiVO.eduAplctOrd}" data-tooltip-con="sub36_pop02" data-focus="sub36_pop02" data-focus-prev="sub36_pop02_close" id="popup_cont">
<div class="popup_tit">
<p>이수증 출력</p>
<button class="btn_popup_close tooltip-close" data-focus="sub36_pop02_close" title="팝업 닫기" onclick="window.close();"><i></i></button>
</div>
<div class="popup_cont" style="max-height:85vh;">
<div class="cont_body">
<div class="pop_tb_type02">
<div class="estimate" id="divBody">
<div class="cont2 clearfix">
<!-- <div class="est_head clearfix">
<img src="/publish/images/CI.png" alt="문자온 CI">
<div class="clearfix">
<p>&nbsp;</p>
<p>&nbsp;</p>
</div>
</div> -->
<div class="est_body" style="border:1px solid black">
<div class="cont1 tb_ver2" style="margin-top:10px;">
<div>
<p><기소유예-2025-00083></p>
</div>
</div>
<h2>교 육 이 수 증</h2>
<div class="cont5 user_info">
<div>
<span>수료과목 : 조건부 기소유예 10기</span>
</div>
<div>
<span>성 명: 조건부 기소유예 10기</span>
</div>
<div>
<span>교육일시 : 2025.10.25</span>
</div>
</div>
<div class="cont5 substance">
<div>
<p>
위 사람은 한국지식재산보호원 지식재산 보호 교육 시스템에서
진행하는 '조건부 기소유예 10기'를 수료 하였기에 위 교육이수증을 드립니다.
</p>
</div>
</div>
<div class="cont5">
<p class="date">2025년 10월 7일</p>
<div>
<span>한국지식재산보호원장</span>
<span class="big_stamp">
<img src="/ipedu/visitEdu/usr/publish/images/content/stamp.png">
</span>
</div>
<!-- <div style="height:1500px;background:skyblue;">여러장 test</div> -->
</div>
</div>
</div>
</div>
<div class="pop_btn_wrap btn_layout01" id="est_btn_wrap">
<div class="btn_left"></div>
<div class="btn_center">
<button type="button" class="btnType btnType5" onclick="javascript:makePDF(); return false;">인쇄하기</button>
<button class="btn_popup_close btnType4 tooltip-close" data-focus="sub36_pop02_close" onclick="window.close();" title="팝업 닫기">닫기</button>
</div>
<div class="btn_right"></div>
</div>
</div>
</div>
</div>
</div>
</form>