diff --git a/src/main/java/cokr/xit/fims/framework/support/tag/privacy/input.java b/src/main/java/cokr/xit/fims/framework/support/tag/privacy/input.java index c5030962..8ea49b0d 100644 --- a/src/main/java/cokr/xit/fims/framework/support/tag/privacy/input.java +++ b/src/main/java/cokr/xit/fims/framework/support/tag/privacy/input.java @@ -38,7 +38,7 @@ public class input extends TagSupport { } sb.append(" />"); - sb.append(", (default: true) + * footers: true, // (Boolean), display table footers (th or td elements) in the , (default: false) + * formats: ["xls", "csv", "txt"], // (String[]), filetype(s) for the export, (default: ['xls', 'csv', 'txt']) + * filename: "id", // (id, String), filename for the downloaded file, (default: 'id') + * bootstrap: false, // (Boolean), style buttons using bootstrap, (default: true) + * exportButtons: true, // (Boolean), automatically generate the built-in export buttons for each of the specified formats (default: true) + * position: "bottom", // (top, bottom), position of the caption element relative to table, (default: 'bottom') + * ignoreRows: null, // (Number, Number[]), row indices to exclude from the exported file(s) (default: null) + * ignoreCols: null, // (Number, Number[]), column indices to exclude from the exported file(s) (default: null) + * trimWhitespace: true // (Boolean), remove all leading/trailing newlines, spaces, and tabs from cell text in the exported file(s) (default: false) + * }); + ===================================*/ + excelExport : function(fileName){ + //selector 설정 + var _sltHead = '#div_thead'; + var _sltBody = '#div_tbody'; + var _sltFoot = '#div_tfoot'; + var _htmlColgroup = $('#div_thead > table > colgroup').html();; + var _htmlHead = $(_sltHead+' > table > thead').html(); + var _htmlBody = $(_sltBody+' > table > tbody').html(); + + + //필수조건 확인 + if($(_sltHead).length==0){ + alert('헤더 데이터는 필수조건 입니다.'); + return false; + } + if($(_sltBody).length==0){ + alert('바디 데이터는 필수조건 입니다.'); + return false; + } + + + //소유자번호 유무 확인 + var arrCellsOfOwnerNo = new Array(); + $(_sltHead+' table tr:last-child th').each(function(){ + if(this.innerHTML.indexOf('주민번호')>-1 + ||this.innerHTML.indexOf('주민등록번호')>-1 + ||this.innerHTML.indexOf('소유자번호')>-1 + ||this.innerHTML.indexOf('소유자주민번호')>-1 + ||this.innerHTML.indexOf('주민/법인번호')>-1 + ) + arrCellsOfOwnerNo.push(this.cellIndex); + }); + //소유자번호 마스킹 처리 + if(arrCellsOfOwnerNo.length>0){ + var isMask = confirm('개인정보를 마스킹처리 하시겠습니까?'); + var _maskBody = ''; + $(_htmlBody).each(function(){ + var row = this; + arrCellsOfOwnerNo.forEach(function(cellIdx){ + var cell = $(row).find('td:eq('+cellIdx+')').text(); + $(row).find('td:eq('+cellIdx+')').text(nvl(cell).fmtJuminNo(isMask)); + }); + _maskBody += ''+$(row).html()+''; + }); + _htmlBody = _maskBody; + } + + + //파일명 설정 + if(fileName==undefined || fileName==null || fileName=='') + fileName = $('#docTitleNm').text(); + + //테이블 설정 + var colgroup = ''+ _htmlColgroup +''; + var thead = ''+ _htmlHead +''; + var tbody = ''+ _htmlBody +''; + if($(_sltBody+' > table > tfoot').length>0) + tbody += ''+$(_sltBody+' > table > tfoot').html()+''; + var tfoot = $(_sltFoot).length==0?'':''+$(_sltFoot+' > table > tfoot').html()+''; + var table = ''+colgroup+thead+tbody+tfoot+'
'; + + ExcelUtil.download(table, fileName); + + }, + + pdfExport : function(fileName, selector){ + //pdf_wrap을 canvas객체로 변환 + html2canvas($(selector)[0]).then(function(canvas) { + var doc = new jsPDF('p', 'mm', 'a4'); //jspdf객체 생성 + var imgData = canvas.toDataURL('image/png'); //캔버스를 이미지로 변환 + doc.addImage(imgData, 'PNG', 0, 0, doc.internal.pageSize.getWidth(), doc.internal.pageSize.getHeight()); //이미지를 기반으로 pdf생성 + doc.addPage(); + doc.save(fileName+'.pdf'); //pdf저장 + }); + + + }, + + wordExport : function(fileName){ + + }, + + pptExport : function(fileName){ + + } +} + + + +/** + *
+ * ajax 실행
+ * ex)
+ * cmmAjax({
+ *    url: ""
+ *    ,data: {
+ *        DLR_ID : $("#dealerSelect_dlrId").val()
+ *        ,DLR_NM : $("#dealerSelect_dlrNm").val()
+ *    }
+ *    ,success: (response)=>{   //선택
+ *         //callback function
+ *    }
+ *    ,exception: (response)=>{ //선택
+ *         // callback function
+ *    }
+ * });
+ * @param {object} param
+ * 
+ */ +const cmmAjax = (param) => { + $.ajax({ + url: param.url + ,type: nvl(param.type, "post") + ,data: param.data + ,async: nvl(param.async, true) + ,dataType: nvl(param.dataType, "json") + ,processData: nvl(param.processData, true) + ,contentType: nvl(param.contentType, 'application/x-www-form-urlencoded;charset=UTF-8') + ,cache : false + ,beforeSend: (jqXhr, settings) => { + jqXhr.setRequestHeader('AJAX',true); + } + ,success: function (res) { + if (param.showSuccessMsg === undefined || param.showSuccessMsg === true) { + if(res.message) alert(res.message); + } + if ($.type(param.success) === 'function') { + param.success(res) + } + } + ,error: function(jqXHR, error, errThrown ){ + console.error('=============================================================='); + console.error('>>>>>>>>>ajax call error<<<<<<<<<<<'); + //console.error('::ajaxError >>>>> ', event, status, error) + console.error(`status=${jqXHR.status}, responseText=${jqXHR.responseText}, errorThrow=${errThrown}`); + console.error('=============================================================='); + + const resText = jqXHR.responseText; + if(typeof resText === 'string'){ + alert(JSON.parse(resText).message); + return false; + } + + if(typeof resText === 'object'){ + alert(resText.message); + return false; + } + + return document.write(jqXHR.responseText); + + + } + }); +}; + +/** + *
+ * 팝업호출시(isPopup)
+ * 1) alert confirm 후 업무처리
+ * 2) 부모(opener) 의 callBackSerch 실행
+ * 3) window close
+ * 일반호출시
+ * 1) alert confirm 후 업무처리
+ * 2) fnBiz.search() 호출
+ *
+ * @param {string} workType add | modify | remove
+ * @param {object} param parameter data
+ * 
+ */ +const cmmBizAjax = (workType, param, isPopup = true) => { + let confirmMsg = '하시겠습니까?'; + if(workType === 'add') confirmMsg = `등록 ${confirmMsg}`; + else if(workType === 'modify') confirmMsg = `변경 ${confirmMsg}`; + else if(workType === 'remove') confirmMsg = `삭제 ${confirmMsg}`; + else confirmMsg = `${workType} ${confirmMsg}`; + // else{ + // alert('workType이 부정확 합니다.'); + // return false; + // } + + param = $.extend(param, { + success: ()=>{ + //if(callback === 'function') window.opener.callback(); + //else window.opener.callbackSearch(); + if(isPopup) { + if(workType === 'add' || workType === 'remove'){ + window.opener.callbackSearch(); + window.close(); + } else { + window.location.reload(); + } + }else{ + fnBiz.search(); + } + } + }); + + dialog.alert({ + content: confirmMsg, + onOK:() => { + cmmAjax(param); + } + }); + +}; + +const cmmApiCall = (param) => { + $.ajax({ + url: param.url + ,type: nvl(param.type, "post") + ,data: param.data + ,async: nvl(param.async, true) + ,dataType: nvl(param.dataType, "json") + ,processData: nvl(param.processData, true) + ,contentType: nvl(param.contentType, 'application/json;charset=UTF-8') + ,cache : false + ,beforeSend: (jqXhr, settings) => { + jqXhr.setRequestHeader('AJAX',true); + } + ,success: function (res) { + if (param.showSuccessMsg === undefined || param.showSuccessMsg === true) { + if(res.message) alert(res.message); + } + if ($.type(param.success) === 'function') { + param.success(res.data) + } + } + ,error: function(jqXHR, error, errThrown ){ + console.error('=============================================================='); + console.error('>>>>>>>>>ajax call error<<<<<<<<<<<'); + //console.error('::ajaxError >>>>> ', event, status, error) + console.error(`status=${jqXHR.status}, responseText=${jqXHR.responseText}, errorThrow=${errThrown}`); + console.error('=============================================================='); + + const resText = jqXHR.responseText; + if(typeof resText === 'string'){ + alert(JSON.parse(resText).message); + return false; + } + + if(typeof resText === 'object'){ + alert(resText.message); + return false; + } + + return document.write(jqXHR.responseText); + } + }); +}; + + + +const cmmDownloadAjax = (param) => { + $.ajax({ + url: param.url + ,type: nvl(param.type, "post") + ,data: param.data + ,async: nvl(param.async, true) + ,dataType: nvl(param.dataType, "json") + //,contentType: nvl(param.contentType, 'application/x-www-form-urlencoded;charset=UTF-8') + //,contentType: 'blob' + /* + ,xhr: function () { + let xhr = new XMLHttpRequest(); + xhr.onreadystatechange = function () { + //response 데이터를 바이너리로 처리한다. 세팅하지 않으면 default가 text + xhr.responseType = "blob"; + }; + return xhr; + } + */ + ,success: function (res, msg, xhr) { + if (xhr.readyState == 4 && xhr.status == 200) { + // 성공했을때만 파일 다운로드 처리하고 + let disposition = xhr.getResponseHeader('Content-Disposition'); + let filename; + if (disposition && disposition.indexOf('attachment') !== -1) { + let filenameRegex = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/; + let matches = filenameRegex.exec(disposition); + if (matches != null && matches[1]) filename = matches[1].replace(/['"]/g, ''); + } + let blob = new Blob([res]); + let link = document.createElement('a'); + link.href = window.URL.createObjectURL(blob); + link.download = filename; + link.click(); + }else{ + //실패했을때는 alert 메시지 출력 + alertPopup("다운로드에 실패하였습니다."); + } + + + if (param.showSuccessMsg === undefined || param.showSuccessMsg === true) { + if(res.message) alert(res.message); + } + if ($.type(param.success) === 'function') { + param.success(res) + } + } + ,exception: function (res) { + alert(res.message); + if ($.type(param.exception) === 'function') { + param.exception(res); + } + } + }); +}; + +function dataURLtoBlob(dataurl) { + var arr = dataurl.split(','), + mime = arr[0].match(/:(.*?);/)[1], + bstr = atob(arr[1]), + n = bstr.length, + u8arr = new Uint8Array(n); + while (n--) { + u8arr[n] = bstr.charCodeAt(n); + } + return new Blob([u8arr], { + type: mime + }); +} + +function downloadImg(imgSrc) { + var image = new Image(); + image.crossOrigin = "anonymous"; + image.src = imgSrc; + var fileName = image.src.split("/").pop(); + image.onload = function() { + var canvas = document.createElement('canvas'); + canvas.width = this.width; + canvas.height = this.height; + canvas.getContext('2d').drawImage(this, 0, 0); + if (typeof window.navigator.msSaveBlob !== 'undefined') { + window.navigator.msSaveBlob(dataURLtoBlob(canvas.toDataURL()), fileName); + } else { + var link = document.createElement('a'); + link.href = canvas.toDataURL(); + link.download = fileName; + link.click(); + } + }; +} +/** + *
+ * val 값이 null이면 ifNulVal(미지정시 '')
+ * null이 아니면 ifNotNullVal(미지정시 val)
+ * @param {string} val
+ * @param {string} ifNullVal
+ * @param {string} ifNotNullVal
+ * @returns {string|*}
+ * 
+ */ +window.nvl = (val, ifNullVal, ifNotNullVal) => { + return val==null + ?( ifNullVal==null?"":ifNullVal) + :(ifNotNullVal==null?val:ifNotNullVal); +}; diff --git a/src/main/webapp/resources/js/fims/common/XitExportUtil.js b/src/main/webapp/resources/js/fims/common/XitExportUtil.js new file mode 100644 index 00000000..b1703fd5 --- /dev/null +++ b/src/main/webapp/resources/js/fims/common/XitExportUtil.js @@ -0,0 +1,472 @@ +/*===================================================================== + * + * File Export 도구 Script + * -XitFileExportUtil.exportExcel() 기능을 사용하기 위해선 "xlsx.full.min.js"와 "Filesaver.min.js" 라이브러리가 반드시 필요 하다. + * @date 2020.02.27 + * @author 박민규 + * + =====================================================================*/ +/** + * Xit 파일 Export 도구 + * @author 박민규 + * @date 2020.05.29. + */ +var XitFileExportUtil = function(fileName, dataType, dataSet, ext){ + this._fileName = fileName; //파일명 + this._dataType = dataType; //Data 타입(table, json, array) + this._dataSet = dataSet; //DataSet( Object 또는 Array ) +} +XitFileExportUtil.prototype.setFileName = function(fileName){ this._fileName = fileName; } +XitFileExportUtil.prototype.setDataType = function(dataType){ this._dataType = dataType; } +XitFileExportUtil.prototype.setDataSet = function(arrDataSet){ this._dataSet = dataSet; } +XitFileExportUtil.prototype.exportExcel = function(){ + // 변수 declare + var _fileName = fnIsEmpty(this._fileName)?'noname':this._fileName; + var _dataType = this._dataType; + var _dataSet = this._dataSet; + var _isMultiSheet = this._dataSet instanceof Array; + var _sheetName = 'Sheet'; + + + + // step 1. workbook 생성 + var wb = XLSX.utils.book_new(); + if(_isMultiSheet){ + _dataSet.forEach(function(data, idx){ + // step 2. 시트 만들기 + var worksheet = createWorkSheet(data); + // step 3. workbook에 새로만든 워크시트에 이름을 주고 붙인다. + XLSX.utils.book_append_sheet(wb, worksheet, _sheetName+(idx+1)); + }); + }else{ + // step 2. 시트 만들기 + var worksheet = createWorkSheet(_dataSet); + // step 3. workbook에 새로만든 워크시트에 이름을 주고 붙인다. + XLSX.utils.book_append_sheet(wb, worksheet, _sheetName+'1'); + } + // step 4. 엑셀 파일 만들기 + var wbout = XLSX.write(wb, {bookType:'xlsx', type: 'binary'}); + // step 5. 엑셀 파일 내보내기 + saveAs(new Blob([s2ab(wbout)],{type:"application/octet-stream"}), _fileName+'.xlsx'); + + + + + // function Declare + function fnIsEmpty(val){ + if(val==undefined||val==null||val==''||val=={}||val==[]) + return true; + return false; + } + function createWorkSheet(data){ + var result; + + switch (_dataType) { + case 'table': + result = XLSX.utils.table_to_sheet(data);//table타입 data( ex: ...
) + break; + case 'json': + result = XLSX.utils.json_to_sheet(data);//json타입 data( ex: [{'이름':'홍길동', '나이':'18세', '출생연도':'1443'}, ... ] ) + break; + case 'array': + result = XLSX.utils.aoa_to_sheet(data);//배열타입 data( ex: [['이름', '나이', '출생연도'],['홍길동', '18세', '1443'], ... ] ) + break; + default: + result = ''; + break; + } + + return result; + } + function s2ab(s) { + var buf = new ArrayBuffer(s.length); //convert s to arrayBuffer + var view = new Uint8Array(buf); //create uint8array as viewer + for (var i=0; ithead draw + var thead = document.createElement('thead'); + for(var i=0; i'+arrHead[i]+''); + } + table.appendChild(thead); + //table>tbody draw + var tbody = document.createElement('tbody'); + for(var i=0; i'+arrBody[i]+''); + } + table.appendChild(tbody); + //table>tfoot draw + var tfoot = document.createElement('tfoot'); + for(var i=0; i'+arrFoot[i]+''); + } + table.appendChild(tfoot); + //전체 테이블영역에 append + var div = document.createElement('div'); + div.appendChild(table); + + + /*=================== + * After 처리 + ===================*/ + div = this.afterProc(div); + + + return div; + }, + + + /* + * case2. 전체 테이블 영역 내 테이블이 n개 인 경우 + * @date 2020.02.27 + * @author 박민규 + */ + case2 : function(includeEntireTableId){ + /*=================== + * DATA 생성 + ===================*/ + var arrTable = new Array(); + $('#'+includeEntireTableId+' table').each(function(tableidx, table){ + //head 데이터 설정 + var arrHead = new Array(); + $(table).find('thead > tr').each(function(rowidx, row){ + /* 주석처리사유: tr 영역 내 input[type="hidden"] 과 같은 엘리먼트가 포함되어 있을 경우 레이아웃이 틀어 짐*/ +// if(arrHead[rowidx]==undefined) arrHead[rowidx] = row.innerHTML; +// else arrHead[rowidx] += row.innerHTML; + $(row).find('th, td').each(function(cellidx, cell){ + if(arrHead[rowidx]==undefined) arrHead[rowidx] = cell.outerHTML; + else arrHead[rowidx] += cell.outerHTML; + }); + }); +// console.log(arrHead); + //body 데이터 설정 + var arrBody = new Array(); + $(table).find('tbody > tr').each(function(rowidx, row){ + /* 주석처리사유: tr 영역 내 input[type="hidden"] 과 같은 엘리먼트가 포함되어 있을 경우 레이아웃이 틀어 짐*/ +// if(arrBody[rowidx]==undefined) arrBody[rowidx] = row.innerHTML; +// else arrBody[rowidx] += row.innerHTML; + $(row).find('th, td').each(function(cellidx, cell){ + if(arrBody[rowidx]==undefined) arrBody[rowidx] = cell.outerHTML; + else arrBody[rowidx] += cell.outerHTML; + }); + }); +// console.log(arrBody); + //body 데이터 설정 + var arrFoot = new Array(); + $(table).find('tfoot > tr').each(function(rowidx, row){ + /* 주석처리사유: tr 영역 내 input[type="hidden"] 과 같은 엘리먼트가 포함되어 있을 경우 레이아웃이 틀어 짐*/ +// if(arrFoot[rowidx]==undefined) arrFoot[rowidx] = row.innerHTML; +// else arrFoot[rowidx] += row.innerHTML; + $(row).find('th, td').each(function(cellidx, cell){ + if(arrFoot[rowidx]==undefined) arrFoot[rowidx] = cell.outerHTML; + else arrFoot[rowidx] += cell.outerHTML; + }); + }); +// console.log(arrBody); + //table 데이터 설정 + var tableData = new Object(); + tableData['thead'] = arrHead; + tableData['tbody'] = arrBody; + tableData['tfoot'] = arrFoot; + arrTable[tableidx] = tableData; + }); +// console.log(arrTable); + + + /*=================== + * TABLE 그리기 + ===================*/ + //div draw + var div = document.createElement('div'); + arrTable.forEach(function(table, tableidx){ + var arrHead = arrTable[tableidx].thead; + var arrBody = arrTable[tableidx].tbody; + var arrFoot = arrTable[tableidx].tfoot; + + //table draw + var table = document.createElement('table'); + //table>thead draw + var thead = document.createElement('thead'); + for(var i=0; i'+arrHead[i]+''); + } + table.appendChild(thead); + //table>tbody draw + var tbody = document.createElement('tbody'); + for(var i=0; i'+arrBody[i]+''); + } + table.appendChild(tbody); + //table>tfoot draw + var tfoot = document.createElement('tfoot'); + for(var i=0; i'+arrFoot[i]+''); + } + table.appendChild(tfoot); + //전체 테이블영역에 append + div.appendChild(table); + }); + + + /*=================== + * After 처리 + ===================*/ + div = this.afterProc(div); + + + return div; + }, + + + + + /* + * 완료된 Table Data에 대한 후처리 + * @date 2020.02.27 + * @author 박민규 + */ + afterProc : function(div){ + //checkbox 처리 + $(div).find('table tr > td > input[type="checkbox"]').each(function(cellidx, cell){ + if($(cell).is(':checked')) + $(cell).parent().html('?'); + else + $(cell).parent().html('?'); + }); + //selectbox 처리 + $(div).find('table tr > td > select').each(function(cellidx, cell){ + $(cell).parent().html(cell.options[cell.selectedIndex].text); + }); + //특정 단어가 포함된 열(col) index 설정 + var arrCellsOfOwnerNo = new Array(); + var arrCellOfAdres = new Array(); + $(div).find('table thead tr th').each(function(){ + if(this.innerHTML.indexOf('주민번호')>-1 + ||this.innerHTML.indexOf('주민등록번호')>-1 + ||this.innerHTML.indexOf('소유자번호')>-1 + ||this.innerHTML.indexOf('소유자주민번호')>-1 + ||this.innerHTML.indexOf('주민/법인번호')>-1 + ) + arrCellsOfOwnerNo.push(this.cellIndex); + + if(this.innerHTML.indexOf('주소')>-1||this.innerHTML.indexOf('번호')>-1) + arrCellOfAdres.push(this.cellIndex); + }); + //소유자번호 마스킹 처리 + if(arrCellsOfOwnerNo.length>0){ + var isMask = confirm('개인정보를 마스킹처리 하시겠습니까?\n -[확인] 선택 시 마스킹 처리\n -[취소] 선택 시 전체 노출'); + + arrCellsOfOwnerNo.forEach(function(value){ + $(div).find('table tbody tr td:nth-child('+(Number(value)+1)+')').each(function(cellidx, cell){ + cell.innerHTML = fmtOwnerNo(cell.innerHTML, isMask); + }); + }); + } + //일부 주소데이터의 날짜 타입변환 방지 처리(case는 아래주석 참조) + //case1. 서울 종로구 홍지문길 84-5 -> (as-is)1984-05-01 -> (to-be)서울 종로구 홍지문길 84 - 5 + //case2. 서울 종로구 창신길 33-4 -> (as-is)2033-04-01 -> (to-be)서울 종로구 창신길 33 - 4 + if(arrCellOfAdres.length>0){ + arrCellOfAdres.forEach(function(value){ + $(div).find('table tbody tr td:nth-child('+(Number(value)+1)+')').each(function(cellidx, cell){ + cell.innerHTML = cell.innerHTML.replace(/[-]/gi, ' - '); + }); + }); + } + +// console.log(div); + return div; + } + + +}; + + + + + +/** + * 테이블 유형별 json타입 엑셀데이터 생성 + */ +var excelJsonDataCreateByCase; + + + +/** + * 테이블 유형별 배열(array)타입 엑셀데이터 생성 + */ +var excelArrayDataCreateByCase; + + + + + + +/** + * 소유자번호 포맷설정 및 마스킹 처리 + * @param ownerNo 소유자번호 + * @param isMask 마스킹처리여부 + * @returns + * @date 2020.02.27. + * @author 박민규 + */ +function fmtOwnerNo(ownerNo, isMask){ + if(ownerNo==null||ownerNo==undefined||ownerNo=='') + return ownerNo; + if(isMask==null||isMask==undefined||isMask=='') + isMask=false; + + + var value = ownerNo.replace(/[-]/gi,''); + if(value.length == 13) //주민번호 + if(isMask) + value = value.substring(0, 6) + '-' +'*******'; + else + value = value.substring(0, 6) + '-' +value.substring(6, 13); + else if(value.length == 10) //사업자번호 + value = value.substring(0, 3) + '-' +value.substring(3, 5) + '-' + value.substring(5, 10); + + + return value; +} \ No newline at end of file diff --git a/src/main/webapp/resources/js/fims/common/cmmBottomSheet.js b/src/main/webapp/resources/js/fims/common/cmmBottomSheet.js new file mode 100644 index 00000000..55c00671 --- /dev/null +++ b/src/main/webapp/resources/js/fims/common/cmmBottomSheet.js @@ -0,0 +1,22 @@ + +const cmmBS = { + contextMenu: ({ rowKey, columnName }) => ( + [ + [ + { + name: 'bsAdd', + label: '바텀시트에 추가', + action: function() { + $('#bs').show(500); + var props = {}; + props['rowKey'] = rowKey; + props['grid'] = columnName; + fnBiz.bsAdd(props); + }, + classNames: [''] + }, + ], + ] + ), + +} \ No newline at end of file diff --git a/src/main/webapp/resources/js/fims/common/cmmDownloadImg.js b/src/main/webapp/resources/js/fims/common/cmmDownloadImg.js new file mode 100644 index 00000000..6ddee957 --- /dev/null +++ b/src/main/webapp/resources/js/fims/common/cmmDownloadImg.js @@ -0,0 +1,224 @@ +/* Download an img */ + +/** + *
+ * 첨부파일 정보 목록으로 부터 이미지 download
+ * 이미지 url 사용
+ * @param {string} divImgListElementId
+ * @param {object} cmmFileDtls json
+ * @param {function} fnBizPagePopup 이벤트 발생시 호출할 함수
+ * @param {boolean} isEditor 이미지 클릭시 이미지 에디터로 open
+ * @param {string} thumbnailSize 썸네일 이미지 크기 - default 100px
+ * 
+ */ +function cmmImgDownload(divImgListElementId, cmmFileDtls, fnBizPagePopup = fnBiz.pagePopup, isEditor, thumbnailSize = '100px', callback) { + const downloadUrl = '/framework/biz/cmm/file/download.do'; + + $(divImgListElementId).children().remove(); + if(cmmFileDtls != null){ + cmmFileDtls.forEach((dtl, idx) => { + let imgDiv = document.getElementById(dtl.infKey); + if(!imgDiv?.hasChildNodes()){ + imgDiv = document.createElement("div"); + imgDiv.setAttribute("id", dtl.infKey); + imgDiv.setAttribute("value", dtl.fileMastrId); + imgDiv.setAttribute("class", "dragDiv") + } + + //const params = `?filename=${dtl.orginlFileNm}&` + $.param(dtl); + const params = `?fileId=${dtl.fileId}&filePath=${dtl.filePath}&orginlFileNm=${dtl.orginlFileNm}`; + const title = dtl.orginlFileNm; + + const x = document.createElement("img"); + //x.setAttribute("class", "draggable") + x.setAttribute("src", downloadUrl+params); + x.setAttribute("id", dtl.fileId); + x.setAttribute("class", "draggable") + x.style = 'width:'+ thumbnailSize; + x.style = 'height:'+ thumbnailSize; + //x.style = 'object-fit: "contain";'; + //x.style = 'object-fit: scale-down;'; + x.setAttribute("title", title); + x.setAttribute("alt", dtl.orginlFileNm); + x.setAttribute("name", dtl.orginlFileNm); + x.setAttribute("data-file-mastr-id", dtl.fileMastrId); + x.setAttribute("data-file-id", dtl.fileId); + x.setAttribute("data-file-path", dtl.filePath); + x.setAttribute("data-file-size", dtl.fileSize); + + x.addEventListener('dblclick', (e)=>{ + if(isEditor) { + fnBizPagePopup('imageEditor', {imageTagId: dtl.fileId}); + }else{ + dtl.downloadUrl = downloadUrl+params; + //dtl.editor = true; + fnBizPagePopup('imageView', dtl); + } + }) + imgDiv.appendChild(x); + document.querySelector(divImgListElementId).appendChild(imgDiv); + }); + } + + dragable(); + if(callback) callback(); +} + +/** + * file download 실행 + * @param blob + * @param fileName + */ +function downloadFile(blob, fileName, callback){ + const url = URL.createObjectURL(blob); + + const anchorElement = document.createElement('a'); + document.body.appendChild(anchorElement); + anchorElement.download = fileName; // a tag에 download 속성을 줘서 클릭할 때 다운로드가 일어날 수 있도록 하기 + anchorElement.href = url; // href에 url 달아주기 + + anchorElement.click(); // 코드 상으로 클릭을 해줘서 다운로드를 트리거 + + // cleanup - 쓰임을 다한 url 객체 삭제 + anchorElement.onload = () => { + URL.revokeObjectUrl(url); + } + //URL.revokeObjectUrl(url); + document.body.removeChild(anchorElement); // cleanup - 쓰임을 다한 a 태그 삭제 + + if($.type(callback) === 'function') callback(); +} + +function download(img) { + var link = document.createElement("a"); + link.href = img.src; + link.download = true; + link.style.display = "none"; + var evt = new MouseEvent("click", { + "view": window, + "bubbles": true, + "cancelable": true + }); + + document.body.appendChild(link); + link.dispatchEvent(evt); + document.body.removeChild(link); + console.log("Downloading..."); +} + +/* Download all images in 'imgs'. + * Optionaly filter them by extension (e.g. "jpg") and/or + * download the 'limit' first only */ +function downloadAll(imgs, ext, limit) { + /* If specified, filter images by extension */ + if (ext) { + ext = "." + ext; + imgs = [].slice.call(imgs).filter(function (img) { + var src = img.src; + return (src && (src.indexOf(ext, src.length - ext.length) !== -1)); + }); + } + + /* Determine the number of images to download */ + limit = (limit && (0 <= limit) && (limit <= imgs.length)) + ? limit : imgs.length; + + /* (Try to) download the images */ + for (var i = 0; i < limit; i++) { + var img = imgs[i]; + console.log("IMG: " + img.src + " (", img, ")"); + download(img); + } +} + + + +/*이미지 드레그앤 드롭 start*/ +function dragable() { + const draggables = document.querySelectorAll(".draggable"); + const containers = document.querySelectorAll(".dragDiv"); + + + + draggables.forEach(draggable => { + draggable.addEventListener("dragstart", () => { + console.log('drag start => ', draggable.getAttribute('id')); + draggable.classList.add("dragging"); + }); + + draggable.addEventListener("dragend", () => { + console.log('drag end => ', draggable.getAttribute('data-file-mastr-id')); + draggable.classList.remove("dragging"); + }); + }); + + containers.forEach(container => { + container.addEventListener("dragover", e => { + e.preventDefault(); + const afterElement = getDragAfterElement(container, e.clientX); + const draggable = document.querySelector(".dragging"); + if (afterElement === undefined) { + container.appendChild(draggable); + } else { + container.insertBefore(draggable, afterElement); + } + }); + }); +} +function getDragAfterElement(container, x) { + const draggableElements = [ + ...container.querySelectorAll(".draggable:not(.dragging)"), + ]; + + return draggableElements.reduce( + (closest, child) => { + const box = child.getBoundingClientRect(); + const offset = x - box.left - box.width / 2; + // console.log(offset); + if (offset < 0 && offset > closest.offset) { + return { offset: offset, element: child }; + } else { + return closest; + } + }, + { offset: Number.NEGATIVE_INFINITY }, + ).element; +} +/*이미지 드레그앤 드롭 end*/ + + +/*이미지 드레그앤 드롭 저장 start*/ +function dragableSave() { + let imgData = {}; + let imgNode = document.querySelector("#imgList").childNodes; + console.log(imgNode); + + for(let i=0; i { + alert('저장되었습니다.') + } + }) +} diff --git a/src/main/webapp/resources/js/fims/common/cmmPopup.js b/src/main/webapp/resources/js/fims/common/cmmPopup.js new file mode 100644 index 00000000..3895a77a --- /dev/null +++ b/src/main/webapp/resources/js/fims/common/cmmPopup.js @@ -0,0 +1,466 @@ +const CmmPopup = { + defaultOpenOptions: { + /** + *
+         * 창의 높이.
+         * 
+ * + * @attribute {Number} (open) height + */ + height: 200 + + /** + *
+         * 창의 넓이.
+         * 
+ * + * @attribute {Number} (open) width + */ + , width: 400 + + /** + *
+         * 창 위치(y좌표).
+         * 
+ * + * @attribute {Number} (open) top + */ + , top: 0 + + /** + *
+         * 창 위치(x좌표).
+         * 
+ * + * @attribute {Number} (open) left + */ + , left: 0 + + /** + *
+         * 메뉴바 사용 여부. 파일, 편집, 보기 등의 버튼이 있는 줄. yes or no (안 됨)
+         * 
+ * + * @attribute {Object} (open) menubar + */ + , menubar: "no" + + /** + *
+         * 툴바 사용 여부. 뒤로, 앞으로, 검색, 즐겨찾기 등의 버튼이 나오는 줄. yes or no
+         * 
+ * + * @attribute {Object} (open) toolbar + */ + , toolbar: "no" + + /** + *
+         * 주소창 변경 여부. URL입력하는 곳. yes or no
+         * 
+ * + * @attribute {Object} (open) location + */ + , location: "no" + + /** + *
+         * 리사이징 가능 여부. 새창이 떴을 시에 최소화, 최대화 등을 비롯해 마우스로 창의 크기를 조절 가능 여부. yes or no
+         * 
+ * + * @attribute {Object} (open) resizable + */ + , resizable: "no" + + /** + *
+         * 창 아래 링크 사용 여부. 인터넷 창 아래부분 보면 회색깔의 링크 주소 나오는 부분. yes or no
+         * 
+ * + * @attribute {Object} (open) status + */ + , status: "no" + + /** + *
+         * 스크롤바 사용여부. 우측부분과 하단 부분에 생기는 스크롤바를 지칭. yes or no
+         * 
+ * + * @attribute {Object} (open) scrollbars + */ + , scrollbars: "yes" + + /** + *
+         * 창 최대화로 띄움. yes or no
+         * 
+ * + * @attribute {Object} (open) fullscreen + */ + , fullscreen: "no" + + /** + *
+         * 가운데 정렬 여부. true 일 경우 top과 left를 자동 계산한다.
+         * 
+ * + * @attribute {Object} (open) useCenterLocation + */ + , useCenterLocation: true + + /** + *
+         * method type. post일 경우 form을 생성하고 data attribute의 값을 넣어 전송.
+         * 
+ * + * @attribute {Object} (open) method + */ + , method: "get" + + /** + *
+         * parameter data
+         * 
+ * + * @attribute {Object} (open) data + */ + , data: null + } + + , defaultModalDaialogOptions: { + /** + *
+         * 창의 높이.
+         * 
+ * + * @attribute {Number} (modal) dialogHeight + */ + dialogHeight: 200 + + /** + *
+         * 창의 넓이.
+         * 
+ * + * @attribute {Number} (modal) dialogWidth + */ + , dialogWidth: 400 + + /** + *
+         * 창 위치(y좌표).
+         * 
+ * + * @attribute {Number} (modal) dialogTop + */ + , dialogTop: 0 + + /** + *
+         * 창 위치(x좌표).
+         * 
+ * + * @attribute {Number} (modal) dialogLeft + */ + , dialogLeft: 0 + + /** + *
+         * 가운데 정렬 여부. yes/no, 1/0, on/off (정확하지 않음. useCenterLocation 이용 권장.)
+         * 
+ * + * @attribute {String} (modal) center + */ + , center: "no" + + /** + *
+         * 도움말 사용 여부. yes/no, 1/0, on/off
+         * 
+ * + * @attribute {String} (modal) help + */ + , help: "no" + + /** + *
+         * 리사이징 가능 여부. 새창이 떴을 시에 최소화, 최대화 등을 비롯해 마우스로 창의 크기를 조절 가능 여부. yes/no, 1/0, on/off
+         * 
+ * + * @attribute {String} (modal) resizable + */ + , resizable: "no" + + /** + *
+         * 스크롤바 사용여부. 우측부분과 하단 부분에 생기는 스크롤바를 지칭. yes or no
+         * 
+ * + * @attribute {String} (modal) scroll + */ + , scroll: "yes" + + /** + *
+         * 메뉴바 사용 여부. 파일, 편집, 보기 등의 버튼이 있는 줄. yes or no (안 됨)
+         * 
+ * + * @attribute {String} (modal) menubar + */ + , menubar: "no" + + /** + *
+         * 툴바 사용 여부. 뒤로, 앞으로, 검색, 즐겨찾기 등의 버튼이 나오는 줄. yes or no
+         * 
+ * + * @attribute {String} (modal) toolbar + */ + , toolbar: "no" + + /** + *
+         * 주소창 변경 여부. URL입력하는 곳. yes or no
+         * 
+ * + * @attribute {String} (modal) location + */ + , locationbars: "no" + + /** + *
+         * 상태바 사용여부. yes/no, 1/0, on/off
+         * 
+ * + * @attribute {String} (modal) status + */ + , status: "no" + + /** + *
+         * 가운데 정렬 여부. true 일 경우 top과 left를 자동 계산한다.
+         * 
+ * + * @attribute {Boolean} (modal) useCenterLocation + */ + , useCenterLocation: true + } + + /** + *
+     * modaless CmmPopup.open(). options에 추가적으로 사용할 option 값을 json 객체의 필드 형태로 넘기면 된다.
+     * @method open
+     * @param {String} url 문서의 주소
+     * @param {Object} options 추가적으로 사용할 option 값을 담은 json 객체
+     * @param {Object} params parameter json object
+     * @param {String} target default 'nonamePopup'
+     * @param {String} method default 'get'
+     * @returns {object} 새로 열린 팝업창의 윈도우 객체.
+     * 
+ */ + ,open: function (url, params, options, target = 'nonamePopup', method = 'post') { + var extendOptions = $.extend({}, this.defaultOpenOptions, options); + + // 가운데 정렬 계산. + if (extendOptions.useCenterLocation) { + const centerPosition = this.getCenterPosition(extendOptions.width, extendOptions.height); + extendOptions.left = centerPosition.left; + extendOptions.top = centerPosition.top; + } + + // status 문자열 생성. + var optionsString = ""; + for (var i in extendOptions) { + optionsString += i + "=" + extendOptions[i] + ", "; + } + method = method.toLowerCase(); + var popup; + + switch (method) { + case "post": + popup = window.open("", target, optionsString); + const form = this._getForm(url, target, method, params ? params : {}); + form.submit(); + break; + case "get": + default: + url += params ? "?" + $.param(params) : ""; + popup = window.open(url, target, optionsString); + break; + } + if (popup) popup.focus(); + return popup; + } + + , openModal: function (url, params, options, title = 'nonamePopup', method = 'post') { + if($("#popupShowBtn").length < 1){ + var modalTemplate = ` + + `; + + $("body").append(modalTemplate); + } + + $("#modalDialog").attr("class","modal-dialog"); + + if(options.width) { + $("#modalDialog").addClass("w-dialog-px-"+options.width); + } + + if($("#modalIframe").length > 0){ + $("#modalIframe").remove(); + } + + var dynamicPopup = document.createElement("pop"); + dynamicPopup.setAttribute("id","pop"+1); + + // .setAttribute("src" , "") + // .setAttribute("width" , "100%") + // .setAttribute("frameborder" , "0") + // .setAttribute("scrolling" , "no") + // .css("border" , "0") + // .css("overflow" , "auto") + // .css("overflow-x" , "no") + ; + $("#modalBody").append(dynamicPopup); + + popup = CmmPopup.open(url, params, options, "modalIframe", method); + + $(popup.frameElement).on("load", function(){ + var popupHeight = $(popup.frameElement.contentDocument.getElementById("wrap")).height(); + $(popup.frameElement).attr("height", popupHeight); + }); + + $("#popupShowBtn").trigger("click"); + + return popup; + } + /** + *
+     * 주소 검색 팝업 호출
+     * 결과 return callback 함수로 fnCallbackZipSearch 사용
+     * fnCallbackZipSearch 함수는 var 로 선언
+     *
+     * ex)
+     *    var fnCallbackZipSearch = (obj) => fnSetZipSearch(obj, document.userInfoVO);
+     * 
+ */ + ,zipPopup: function(){ + let popUrl = '/_anonymous_/api/AdresSearch.do'; + const params = {callback: 'fnCallbackZipSearch'}; + const popTitle = "주소 찾기"; + const popOption = {width: 570, height:420}; + + this.open(popUrl, params ,popOption, '주소 검색'); + } + + /** + *
+     * 주소 검색 Popup 결과를 set하는 콜백 함수
+     * @param {Object} zipObj - 주소 검색 결과
+     * @param {Object} tgtObj - 주소 검색 결과값을 Set할 객체(addr, zip, zip_view, daddr)
+     *
+     * ex)
+     *    var fnCallbackZipSearch = (obj) => CmmPopup.fnSetZipSearch(obj, document.userInfoVO);
+     * 
+ */ + ,setZipSearch: function(zipObj, tgtObj){ + //화면에 출력 + tgtObj.addr.value = zipObj.roadAddrPart1; + tgtObj.zip.value = zipObj.zipNo; + tgtObj.zip_view.value = zipObj.zipNo; + tgtObj.daddr.value = zipObj.roadAddrPart2 + ' ' + zipObj.addrDetail; + + } + + /** + * modal CmmPopup.showModalDialog(). options에 추가적으로 사용할 option 값을 json 객체의 필드 형태로 넘기면 된다. + * @method showModalDialog + * @param {String} url 문서의 주소 + * @param {Object} argument 팝업창으로 넘길 데이터. + * @param {Object} options 추가적으로 사용할 option 값을 담은 json 객체 + * @returns {object} 자식창에서 리턴하는 값. + */ + ,showModalDialog: function (url, argument, options) { + let extendOptions = $.extend({}, this.defaultModalDaialogOptions, options); + + // 가운데 정렬 계산. + if (extendOptions.useCenterLocation) { + let centerPosition = this.getCenterPosition(extendOptions.dialogWidth, extendOptions.dialogHeight); + extendOptions.dialogLeft = centerPosition.left + "px"; + extendOptions.dialogTop = centerPosition.top + "px"; + } + extendOptions.dialogWidth += "px"; + extendOptions.dialogHeight += "px"; + + // status 문자열 생성. + let optionsString = ""; + for (let i in extendOptions) { + optionsString += i + "=" + extendOptions[i] + "; "; + } + + return window.showModalDialog(url, argument, optionsString); + } + + /** + * 현재 브라우저에서 주어진 높이와 넓이를 가지는 창이 가운데에 위치되는 좌표 값을 구한다. + * @method getCenterPosition + * @param {Integer} width 넓이 + * @param {Integer} height 높이. + * @returns {object} 해당 창이 가운데에 위치되는 좌표 값. + */ + ,getCenterPosition : function(width, height) { + const offsetX = typeof window.screenX != 'undefined' ? window.screenX : window.screenLeft; + const offsetY = typeof window.screenY != 'undefined' ? window.screenY : window.screenTop; + const browserWidth = typeof window.outerWidth!='undefined' ? window.outerWidth : document.documentElement.clientWidth; + const browserHeight = typeof window.outerHeight != 'undefined' ? window.outerHeight: (document.documentElement.clientHeight - 22); + const shownBrowserWidth = (offsetX < 0) ? window.screen.width + offsetX : offsetX; + const left = parseInt(shownBrowserWidth + ((browserWidth - width) / 2), 10); + const top = parseInt(offsetY + ((browserHeight - height) / 2), 10); + return {left:left, top:top}; + } + + /** + * 폼생성 + * @method getProperty + * @param {String} url 문서의 주소 + * @param {String} target 목표창 이름 + * @param {String} method form method type(get, post, etc) + * @param {Object} data 서버로 전송할 parameter data + * @returns {object} 새로 열린 팝업창의 윈도우 객체. + */ + ,_getForm: function(url, target, method, data) { + if($("#PopupForm").length) { + $("#PopupForm").remove(); + } + const form = $("
").attr("method", method) + .attr("target", target) + .attr("action", url); + for(const i in data) { + const input = $("").attr("type", "hidden") + .attr("name", i) + .attr("value", data[i]); + form.append(input); + } + $("body").append(form); + + return form; + } +} diff --git a/src/main/webapp/resources/js/fims/common/cmmUtil.js b/src/main/webapp/resources/js/fims/common/cmmUtil.js new file mode 100644 index 00000000..928cfcb4 --- /dev/null +++ b/src/main/webapp/resources/js/fims/common/cmmUtil.js @@ -0,0 +1,599 @@ +function deepCopy(obj) { + if(typeof obj !== 'object' || obj === null) { + return obj; + } + + if(obj instanceof Date) { + return new Date(obj.getTime()); + } + + if(obj instanceof Array) { + return obj.reduce((arr, item, i) => { + arr[i] = deepCopy(item); + return arr; + }, []); + } + + if(obj instanceof Object) { + return Object.keys(obj).reduce((newObj, key) => { + newObj[key] = deepCopy(obj[key]); + return newObj; + }, {}) + } +} + + +$(document).keydown(function(event){ + let code; + if (event.keyCode) code = event.keyCode; + else if (event.which) code = event.which; + if(code==8){ + const targetNode = event.target.nodeName; + const readonly = event.target.readOnly; + const disabled = event.target.disabled; + const type = event.target.type; + //type이 password나 text인 input와 textarea를 제외한 모든 엘리먼트에서 백스페이스기능을 제한함 + if( !( ((targetNode=="INPUT"&&(type=="text"||type=="password"))||targetNode=="TEXTAREA")&&(!readonly&&!disabled))) { + if(event.preventDefault){ + event.preventDefault(); + }else{ + event.returnValue = false; + } + } + } +}); + +/** + * cmmClearForm(tagElementId) + * tagElement의 하위 input tag 클리어 시 사용. + * resetForm()은 input tag의 action 이전 값을 기억. + * clearForm()은 input tag의 모든값을 nullString 로 세팅. + * @param targetId : 초기화 하고자하는 상위 targetId + * @param notClearNameArr : 폼안에 검색조건이 있는 경우 clear하지 않을 이름. + */ +window.cmmClearForm = function (targetId, notClearNameArr) { + $("#"+targetId+" :input").each(function() { + if ( $.inArray(this.name, notClearNameArr) > -1 ) { + return true; //=>continue + } + switch(this.type) { + case 'password': + case 'select-multiple': + case 'text': + case 'textarea': + $(this).val(''); + break; + case 'select-one': + $(this).val($(this).find("option:first").val()); + break; + case 'checkbox': + case 'radio': + this.checked = false; + } + }); +}; + +/** + * hidden 을 포함한 form 의 모든 항목 초기화 + * @param targetId : 초기화 하고자하는 상위 targetId + * @param notClearNameArr : 폼안에 검색조건이 있는 경우 clear하지 않을 이름. + */ +window.cmmClearFormAll = function (targetId, notClearNameArr) { + $("#"+targetId+" :input").each(function() { + if ( $.inArray(this.name, notClearNameArr) > -1 ) { + return true; //=>continue + } + switch(this.type) { + case 'password': + case 'select-multiple': + case 'text': + case 'hidden': + case 'textarea': + $(this).val(''); + break; + case 'select-one': + $(this).val($(this).find("option:first").val()); + break; + case 'checkbox': + case 'radio': + this.checked = false; + } + }); +}; + +/** + * setTimeCombo(objectId, timeDiv) + * objectI에 시간 또는 분 combobox 생성 + * timeDiv가 'H'이면 시간, 'M'이면 분 + * @param id : 콤보박스를 생성할 element ID + * @param timeDiv : 'H'-시간, 'M'-분 + */ +window.setTimeCombo = function(id, timeDiv){ + var hh; + + if(timeDiv == 'H'){ + for (var i=0; i<24; i++){ + + if(i < 10) hh = '0'+i; + else hh = i+''; + + var option = document.createElement('option'); + var txt = document.createTextNode(hh); + option.setAttribute("value", hh); + option.appendChild(txt); + $("#"+id).append(option); + } + + }else{ + for (var i=0; i<60; i++){ + + if(i < 10) hh = '0'+i; + else hh = i+''; + + var option = document.createElement('option'); + var txt = document.createTextNode(hh); + option.setAttribute("value", hh); + option.appendChild(txt); + $("#"+id).append(option); + } + } +}; + +/** + * 문자열에서 exceptChar를 제거한다. + * @param exceptChar - 제거할 문자 + * @return exceptChar가 제거된 문자 + */ +String.prototype.remove = function(exceptChar) { + if ( this == null ) return ""; + if ( exceptChar == null ) return this; + var str = this; + for ( var i=0, len=exceptChar.length ; i < len ;i++ ) { + str = str.replace(new RegExp("[\\"+exceptChar.charAt(i)+"]", "g"), ""); + } + return str; +} + +/** + * 문자열이 숫자형인지의 여부를 반환한다. + * @param exceptChar - 추가 허용할 문자 + * @return 숫자형여부 + */ +String.prototype.isNum = function(exceptChar) { + return (/^-?(?:\d+|\d{1,3}(?:,\d{3})+)?(?:\.\d+)?$/).test(this.remove(exceptChar)) ? true : false; +}; + +/** + * 문자열을 숫자형으로 캐스팅한다. + * @return 캐스팅된 숫자 + */ +String.prototype.toNum = function() { + + if(this.isNum()) { + return Number(this.remove(DELIMITER_AMT)); + } else { + return null; + } +}; + +/** + * 문자열의 UTF8 byte 길이를 반환한다. + * @return 문자열의 UTF8 byte 길이 + */ +window.cmmGetUTF8ByteSize = function(str) { + if ( str == null || str.length == 0 ) { + return 0; + } + var size = 0; + for ( var i=0, len=str.length ; i < len ;i++ ) { + var charCode = str.charCodeAt(i), + charSize = 0; + //http://ko.wikipedia.org/wiki/UTF-8 + if ( charCode <= 0x00007F ) { //127 + charSize = 1; + } else if ( charCode <= 0x0007FF) { //2047 + charSize = 2; + } else if ( charCode <= 0x00FFFF) { //65535 + charSize = 3; + } else { + charSize = 4; + } + size += charSize; + } + return size; + +}; + +/** + * 문자열의 byte 길이를 반환한다. + * @return 문자열의 byte 길이 + */ +String.prototype.getByte = function() { + return cmmGetUTF8ByteSize(this); +// var cnt = 0; +// +// for (var i = 0; i < this.length; i++) { +// if (this.charCodeAt(i) > 127) { +// cnt += 2; +// } else { +// cnt++; +// } +// } +// +// return cnt; +}; + +/** + * 문자열이 지정한 최소길이 이상인지의 여부를 반환한다. + * @param minLen - 최소길이 + * @return 최소길이 이상인지의 여부 + */ +String.prototype.isMin = function(minLen) { + + return this.length >= minLen; +}; + +/** + * 문자열이 지정한 최대길이 이하인지의 여부를 반환한다. + * @param maxLen - 최대길이 + * @return 최대길이 이하인지의 여부 + */ +String.prototype.isMax = function(maxLen) { + + return this.length <= maxLen; +}; + +/** + * 문자열이 지정한 최소바이트수 이상인지의 여부를 반환한다. + * @param minByte - 최소바이트수 + * @return 최소바이트수 이상인지의 여부 + */ +String.prototype.isMinByte = function(minByte) { + + return this.getByte() >= minByte; +}; + +/** + * 문자열이 지정한 최대바이트수 이하인지의 여부를 반환한다. + * @param maxByte - 최대바이트수 + * @return 최대바이트수 이하인지의 여부 + */ +String.prototype.isMaxByte = function(maxByte) { + + return this.getByte() <= maxByte; +}; + +/** + * 문자열 좌우 공백을 제거한다. + * @return 좌우 공백 제거된 문자열 + */ +$(function() { + if ( !String.prototype.trim ) { // Use native String.trim function wherever possible + String.prototype.trim = function() { + return this.replace(/^\s+/g, '').replace(/\s+$/g, ''); + }; + } +}); +/** + * 문자열 좌 공백을 제거한다. + * @return 좌 공백 제거된 문자열 + */ +String.prototype.ltrim = function() { + return this.replace(/(^\s*)/, ""); +}; + +/** + * 문자열 우 공백을 제거한다. + * @return 우 공백 제거된 문자열 + */ +String.prototype.rtrim = function() { + return this.replace(/(\s*$)/, ""); +}; + +/** + * 문자열에서 모든 교체할 문자열을 대체 문자열로 치환한다. + * @param pattnStr - 찾을 문자열 + * @param chngStr - 대체 문자열 + * @return 치환된 문자열 + */ +String.prototype.replaceAll = function(pattnStr, chngStr) { + + var retsult = ""; + var trimStr = this;//.replace(/(^\s*)|(\s*$)/g, ""); + + if(trimStr && pattnStr != chngStr) { + + retsult = trimStr; + + while(retsult.indexOf(pattnStr) > -1) { + retsult = retsult.replace(pattnStr, chngStr); + } + } + + return retsult; +}; + +/** + * 문자열을 거꾸로 치환한다. + * @return 거꾸로 치환된 문자열 + */ +String.prototype.reverse = function() { + + var result = ''; + + for(var i=this.length-1; i>-1; i--) { + result += this.substring(i, i+1); + } + + return result; +}; + +/** + * 지정한 길이만큼 원본 문자열 왼쪽에 패딩문자열을 채운다. + * @param len - 채울 길이 + * @param padStr - 채울 문자열 + * @return 채워진 문자열 + */ +String.prototype.lpad = function(len, padStr) { + + var result = ''; + var loop = Number(len) - this.length; + + for(var i=0; i + * [downloadImage] + * @param {[string]} img [base64encoded image data] + * @param {[string]} fileName [new file name] + * @return [image file] + * + */ +function downloadImage(img, fileName) { + var imgData = atob(img.split(',')[1]), + len = imgData.length, + buf = new ArrayBuffer(len), + view = new Uint8Array(buf), + blob, + i; + + for (i = 0; i < len; i++) { + view[i] = imgData.charCodeAt(i) & 0xff; // masking + } + + blob = new Blob([view], { + type: 'application/octet-stream', + }); + + if (window.navigator.msSaveOrOpenBlob) { + window.navigator.msSaveOrOpenBlob(blob, fileName); + } else { + //var url = URL.createObjectURL(blob); + var a = document.createElement('a'); + a.style = 'display: none'; + a.href = URL.createObjectURL(blob);; + //a.href = img.src; + a.download = fileName; + document.body.appendChild(a); + a.click(); + + setTimeout(function () { + document.body.removeChild(a); + //URL.revokeObjectURL(url); + }, 100); + } +} + +var readBlob = async () => { + const data = await fetch('https://play-lh.googleusercontent.com/hYdIazwJBlPhmN74Yz3m_jU9nA6t02U7ZARfKunt6dauUAB6O3nLHp0v5ypisNt9OJk'); + const blob = await data.blob(); + const reader = new FileReader(); + reader.onload = () => { + const base64data = reader.result; + console.log(base64data) + } + reader.readAsDataURL(blob); + + fetch('https://www.business2community.com/wp-content/uploads/2014/04/Free.jpg') + .then((response) => response.blob()) + .then((blob) => { + const url = URL.createObjectURL(blob); + document.querySelector('img').src = url; + document.querySelector('a').href = url; + }); +} + +/** + * + * @param b64Data + * @param contentType + * @param sliceSize + * @returns {Blob} + */ +// bas64를 blob으로 변환해주는 함수 +function b64toBlob(b64Data, contentType = '', sliceSize = 512) { + const image_data = atob(b64Data.split(',')[1]); // data:image/gif;base64 필요없으니 떼주고, base64 인코딩을 풀어준다 + + const arraybuffer = new ArrayBuffer(image_data.length); + const view = new Uint8Array(arraybuffer); + + for (let i = 0; i < image_data.length; i++) { + view[i] = image_data.charCodeAt(i) & 0xff; + // charCodeAt() 메서드는 주어진 인덱스에 대한 UTF-16 코드를 나타내는 0부터 65535 사이의 정수를 반환 + // 비트연산자 & 와 0xff(255) 값은 숫자를 양수로 표현하기 위한 설정 + } + + return new Blob([arraybuffer], { type: contentType }); + +/* + const contentType = 'image/png'; + const b64Data = + 'data:image/gif;base64,R0lGODlhAAEAAcQAALe9v9ve3/b393mDiJScoO3u74KMkMnNz4uUmKatsOTm552kqK+1uNLW18DFx3B7gP///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH/C1hNUCBEYXRhWE1QPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS4wLWMwNjAgNjEuMTM0Nzc3LCAyMDEwLzAyLzEyLTE3OjMyOjAwICAgICAgICAiPiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPiA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyIgeG1wTU06T3JpZ2luYWxEb2N1bWVudElEPSJ4bXAuZGlkOjAxODAxMTc0MDcyMDY4MTE5QjEwQjYyNTc4MkUxRURBIiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOjEzN0VEMDZBQjMyNzExRTE4REMzRUZGMkFCOTM1NkZBIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjEzN0VEMDY5QjMyNzExRTE4REMzRUZGMkFCOTM1NkZBIiB4bXA6Q3JlYXRvclRvb2w9IkFkb2JlIFBob3Rvc2hvcCBDUzUgTWFjaW50b3NoIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6MDI4MDExNzQwNzIwNjgxMTlCMTBCNjI1NzgyRTFFREEiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6MDE4MDExNzQwNzIwNjgxMTlCMTBCNjI1Nzgy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'; + + const blob = b64toBlob(b64Data, contentType); // base64 -> blob + const blobUrl = URL.createObjectURL(blob); // object url 생성 + + const img = document.createElement('img'); + img.src = blobUrl; + document.body.appendChild(img); +*/ +} + +/** + * 전달받은 이미지를 base64로 인코딩한다 + * @param file - 이미지 파일 또는 이미지 URL + * @param maxWidth - 인코딩 시의 이미지 max width 사이즈 + * @returns {Promise} + */ +var readImage = () => { + let image = this.$refs.image.src + this.toBlob(image) + .then(res => { + console.log(res) + this.image = { + filename: res.name, + size: res.size, + type: res.type, + lastModified: res.lastModified + } + }) +}; + +/** + * 이미지 url을 blob 파일로 변환하여 전달한다 + * @param url + * @returns {Promise} + */ +var toBlob = (url) => { + return new Promise((resolve, reject) => { + this.base64Encode(url) + .then(res => { + let byteString = atob(res.dataUrl) + let ab = new ArrayBuffer(byteString.length) + let ia = new Uint8Array(ab) + + for (let i = 0; i < byteString.length; i++) { + ia[i] = byteString.charCodeAt(i) + } + + // write the array buffer to blob + let blob = new Blob([ab], {type: 'image/' + res.type}) + + let formData = new FormData() + formData.append('file', blob, res.name) + resolve(formData.get('file')) + }) + }) +}; + +/** + * 전달받은 이미지를 base64로 인코딩한다 + */ +var base64Encode = (url) => { + const re = new RegExp('.(gif|jpg|jpeg|tiff|png|ico)$', 'i') + let name = (/[^(/|\\)]*$/).exec(url)[0] + let type = re.test(name) ? re.exec(name)[0].replace('.', '') : 'jpg' + + return new Promise((resolve, reject) => { + let image = new Image() + + image.onload = function (event) { + let canvas = document.createElement('canvas') + // draw canvas + canvas.width = image.naturalWidth + canvas.height = image.naturalHeight + canvas.getContext('2d').drawImage(image, 0, 0) + + let dataUrl = canvas.toDataURL('image/' + type) + resolve({ + name: name, + type: type, + dataUrl: dataUrl.split(',')[1] + }) + } + image.onerror = function () { + let msg = `"${file}"을 로딩하는 데 오류가 발생하였습니다. 이미지 파일을 확인해주세요.` + alert(msg) + console.error(msg) + } + image.crossOrigin = 'anonymous'; + image.src = url + }) +} diff --git a/src/main/webapp/resources/js/fims/common/defaultUI.js b/src/main/webapp/resources/js/fims/common/defaultUI.js new file mode 100644 index 00000000..10bec417 --- /dev/null +++ b/src/main/webapp/resources/js/fims/common/defaultUI.js @@ -0,0 +1,98 @@ + +/* + * 단축키 Event + */ +document.onkeydown=function(e) { + if (e.key == "F1" && e.ctrlKey == true) { + if ( self !== top ) { + $(top.document.getElementById("favorites")).trigger("click"); + } else { + $("#favorites").trigger("click"); + } + } +}; + + +/* + * 보안모드 + */ +function fn_securityModeToggle(flag, elementId){ + + var executionArea; + if(elementId){ + executionArea = $("#"+elementId); + } else { + executionArea = $(document); + } + + var targets = executionArea.find("input.privacy"); + for(let i=0; i< targets.length; i++){ + let originId = targets[i].id; + let originValue= targets[i].value; + let maskingValue = originValue.replace(/[0-9a-zA-Z]/g, "*"); + document.getElementById("mask-"+originId).value = maskingValue; + } + + if(flag){ //개인정보 숨김 + + //입력상자 + $("input.privacy").attr("hidden","hidden"); + $("input.privacy-mask").removeAttr("hidden"); + + //그리드 + $("th.privacy").attr("hidden","hidden"); + $("td.privacy").attr("hidden","hidden"); + $("th.privacy-mask").removeAttr("hidden"); + $("td.privacy-mask").removeAttr("hidden"); + + } else { //개인정보 표시 + + //입력상자 + $("input.privacy").removeAttr("hidden"); + $("input.privacy-mask").attr("hidden","hidden"); + + $("th.privacy").removeAttr("hidden"); + $("td.privacy").removeAttr("hidden"); + $("th.privacy-mask").attr("hidden","hidden"); + $("td.privacy-mask").attr("hidden","hidden"); + + } + +} + +$(document).ready(function(){ + + + /*--------------------- 검색영역 상세검색 제어 ---------------------*/ + $( "body" ).on( "click", ".btn-open-detail", function() { + $(this).find('i').toggleClass('bx-chevron-down'); + $(this).find('i').toggleClass('bx-chevron-up'); + }); + + /*--------------------- 달력 제어 ---------------------*/ + $(".form-date").datepicker({ + changeMonth: true, + changeYear: true, + showButtonPanel: true + }); + $( "body .form-date" ).next("button.bx-calendar").on("click", function() { + $(this).prev().focus(); + }); + + + /*------- 팝업 제어 ---------*/ + /*------- 팝업 열림 -------*/ + $( "body" ).on( "click", "button[data-show-popup]", function(e) { + var popId = $(e.currentTarget).data("show-popup"); + $(".modal-wrap").css("display",'table'); + $(".modal-wrap .cont-box#"+popId).show(); + + + }); + /*------- 팝업 닫힘 -------*/ + $( "body" ).on( "click", ".modal-wrap button[data-modal-close]", function() { + $(".modal-wrap, .modal-wrap .cont-box").hide(); + + + }); +}); \ No newline at end of file diff --git a/src/main/webapp/resources/js/fims/common/popupPageNavigation.js b/src/main/webapp/resources/js/fims/common/popupPageNavigation.js new file mode 100644 index 00000000..de9eac82 --- /dev/null +++ b/src/main/webapp/resources/js/fims/common/popupPageNavigation.js @@ -0,0 +1,135 @@ +// 이전/다음 페이지 navigation data + +class PageNavigation { + grid = null; + pageNav = null; + + // 현재 gridData 목록 + gridInfo = { + gridDatas: null + // 현재 rowData + ,curRowData: null + // 현재 데이타 위치 + ,curRowPos: null + // 현재 데이타 위치 + ,gridDataPos: null + // 현재 page + ,pageNum: null + // 페이지당 갯수 + ,fetchSize: null + // 전체 데이타 count + ,totalSize: null + // 페이지 이동 구분 + ,pageMove: null + }; + + /** + * 페이지 이동 or 팝업 호출시 생성 + * @param {object} GRID + * @param {array} gridDatas 그리드 데이타 key 필드 배열 + * @param {number} gridDataPos 현재 그리드 페이지의 데이타 row + */ + constructor(GRID, gridDatas, gridDataPos) { + let pageInfo = { + pageNum: 1, + fetchSize: null, + totalSize: null + }; + + if(GRID.paginationInfoRef.paging === true){ + const {pageNum, fetchSize, totalSize} = GRID.paginationInfoRef; + pageInfo.pageNum = pageNum; + pageInfo.fetchSize = fetchSize; + pageInfo.totalSize = totalSize; + }else{ + pageInfo.fetchSize = GRID.paginationInfoRef.totalSize; + pageInfo.totalSize = GRID.paginationInfoRef.totalSize; + } + + this.gridInfo = { + + gridDatas + ,gridDataPos + ,curRowData: gridDatas[gridDataPos] + ,curRowPos: (pageInfo.pageNum - 1) * pageInfo.fetchSize + gridDataPos + 1 + ,pageNum: pageInfo.pageNum + ,fetchSize: pageInfo.fetchSize + ,totalSize: pageInfo.totalSize + ,pageMove: null + ,next: null + } + this.pageNav = this; + this.grid = GRID; + }; + + /** + * 팝업 페이지 에서 강제 페이징 처리시 호출 + * @param {json} res 그리드 목록 조회 결과 + * @param {array} gridDatas 그리드 데이타 key 필드 배열 + * @param {function} callback 호출할 function - 생성한 PageNavigation을 함께 전달 + */ + resetGrid(res, gridDatas, callback) { + this.grid.resetData(res.data?.contents); + if (this.gridInfo.next) this.pageNav = new PageNavigation(this.grid, gridDatas, 0); + else this.pageNav = new PageNavigation(this.grid, gridDatas, this.gridInfo.fetchSize - 1); + + callback(this.pageNav) + } + /** + * 팝업창의 prev, next 버튼 클릭후 정보 갱신을 위해 호출 + * @param {object} prevObj prev button object + * @param {object} nextObj next button object + * @param {object} totObj total tag object + */ + reloadNav(prevObj, nextObj, totObj){ + + if(this.gridInfo.curRowPos === 1){ + prevObj.attr('disabled', true); + }else{ + prevObj.attr('disabled', false); + } + if(this.gridInfo.curRowPos === this.gridInfo.totalSize){ + nextObj.attr('disabled', true); + }else{ + nextObj.attr('disabled', false); + } + totObj.text(this.gridInfo.curRowPos + " / " + this.gridInfo.totalSize); + } + + /** + * 팝업창 prev, next 버튼 클릭시 호출 + * @param {string} evDiv 'prev|next' + * @param {function} callback 페이지 이동시 호출할 callback + */ + onClickNavBtn(evDiv, callback) { + const isTypeScroll = this.grid.paginationInfoRef?.pagingType === 'scroll'; + + if (evDiv === 'next') { + if(this.gridInfo.gridDataPos + 1 === this.gridInfo.fetchSize){ + this.gridInfo.pageMove = true; + this.gridInfo.next = true; + this.gridInfo.pageNum++; + + }else{ + this.gridInfo.curRowPos++; + this.gridInfo.gridDataPos++; + this.gridInfo.curRowData = this.gridInfo.gridDatas[this.gridInfo.gridDataPos]; + callback(this.gridInfo); + } + + } else { + if(this.gridInfo.gridDataPos === 0){ + this.gridInfo.pageMove = true; + this.gridInfo.next = false; + this.gridInfo.pageNum--; + + }else { + this.gridInfo.curRowPos--; + this.gridInfo.gridDataPos--; + this.gridInfo.curRowData = this.gridInfo.gridDatas[this.gridInfo.gridDataPos]; + callback(this.gridInfo) + } + } + } +} + diff --git a/src/main/webapp/resources/js/fims/framework/egov/EgovCmmUtl.js b/src/main/webapp/resources/js/fims/egov/EgovCmmUtl.js similarity index 100% rename from src/main/webapp/resources/js/fims/framework/egov/EgovCmmUtl.js rename to src/main/webapp/resources/js/fims/egov/EgovCmmUtl.js diff --git a/src/main/webapp/resources/js/fims/framework/egov/showModalDialog.js b/src/main/webapp/resources/js/fims/egov/showModalDialog.js similarity index 100% rename from src/main/webapp/resources/js/fims/framework/egov/showModalDialog.js rename to src/main/webapp/resources/js/fims/egov/showModalDialog.js diff --git a/src/main/webapp/resources/js/fims/framework/egov/showModalDialogCallee.js b/src/main/webapp/resources/js/fims/egov/showModalDialogCallee.js similarity index 100% rename from src/main/webapp/resources/js/fims/framework/egov/showModalDialogCallee.js rename to src/main/webapp/resources/js/fims/egov/showModalDialogCallee.js diff --git a/src/main/webapp/resources/js/fims/framework/cmm/frwkApiURL.js b/src/main/webapp/resources/js/fims/framework/cmm/frwkApiURL.js deleted file mode 100644 index 9db32399..00000000 --- a/src/main/webapp/resources/js/fims/framework/cmm/frwkApiURL.js +++ /dev/null @@ -1,31 +0,0 @@ -const frwkApiUrl = { - /** - * framework 공통 API URL - */ - //paintweb image editor popup - POPUP_PAINTWEB_IMG_EDITOR: '/framework/biz/cmm/file/cmmPaintwebImageEditorPopup.do' - //image view - ,POPUP_IMG_VIEW: '/framework/biz/cmm/file/cmmImageViewPopup.do' - - //파일 download - file full path - ,DOWNLOAD_BY_FILE_PATH: '/framework/biz/cmm/file/downloadFromFileFullPath.do' - ,DOWNLOAD: '/framework/biz/cmm/file/download.do' - ,REMOVE_FILE: '/framework/biz/cmm/file/removeFile.do' - - //공통 답변 템플릿 - ,FIND_ANS_TMPLS: '/framework/biz/cmm/answer/findCmmAnsTmpls.do' - ,POPUP_ANS_TMPLS: '/framework/biz/cmm/answer/cmmAnsTmplPopup.do' - ,SAVE_ANS_TMPLS: '/framework/biz/cmm/answer/addCmmAnsTmpls.do' - ,MODIFY_ANS_TMPLS: '/framework/biz/cmm/answer/modifyCmmAnsTmpls.do' - - - /** - * framework 업무 API URL - */ - //게시판 - 기본 화면 관리(게시판 기본 양식) - ,FIND_BOARD_BASICS: '/framework/biz/mng/bbs/findBoardBasics.do' - ,FIND_BOARD_BASIC_ATTCH_FILES: '/framework/biz/mng/bbs/findCmmBoardAttchFiles.do' - ,POPUP_BOARD_BASIC: '/framework/biz/mng/bbs/mngBoardBasicMgtPopup.do' - ,SAVE_BOARD_BASIC: '/framework/biz/mng/bbs/addBoardBasic.do' - ,MODIFY_BOARD_BASIC: '/framework/biz/mng/bbs/modifyBoardBasic.do' -} diff --git a/src/main/webapp/resources/js/fims/biz/layout/myView.js b/src/main/webapp/resources/js/fims/myView.js similarity index 100% rename from src/main/webapp/resources/js/fims/biz/layout/myView.js rename to src/main/webapp/resources/js/fims/myView.js