This commit is contained in:
Rinjae
2025-09-05 17:16:26 +09:00
commit c54ef1903f
4947 changed files with 817291 additions and 0 deletions
@@ -0,0 +1,177 @@
<%@ page language="java" contentType="text/html; charset=utf-8"%>
<%@ page import="java.io.*"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ include file="/jsp/common/include/localemessage.jsp" %>
<%
response.setHeader("Pragma", "No-cache");
response.setHeader("Cache-Control", "no-cache");
response.setHeader("Expires", "0");
%>
<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=euc-kr">
<jsp:include page="/jsp/common/include/css.jsp"/>
<jsp:include page="/jsp/common/include/script.jsp"/>
<link href="<c:url value="/addon/bootstrap-5.3.2/css/bootstrap.min.css"/>" rel="stylesheet"/>
<script src="<c:url value="/addon/bootstrap-5.3.2/js/bootstrap.bundle.min.js"/>"></script>
<script language="javascript" >
var url = '<c:url value="/onl/apim/apigroup/apiGroupMan.json"/>';
var url_view = '<c:url value="/onl/apim/apigroup/apiGroupMan.view"/>';
function useFormatter(cellvalue,options,rowObject){
if(cellvalue == null || cellvalue == '')
return ''
return cellvalue === '0'?'미공개':'공개';
}
function detail(){
var postData = getSearchForJqgrid("cmd","LIST"); //jqgrid에서는 object 로
$("#grid").setGridParam({ url:url,postData: postData }).trigger("reloadGrid");
}
function search(){
var postData = getSearchForJqgrid("cmd","LIST"); //jqgrid에서는 object 로
$("#grid").setGridParam({ url:url,postData: postData ,page:1 }).trigger("reloadGrid");
}
function list(){
detail()
var gridPostData = getSearchForJqgrid("cmd","LIST"); //jqgrid에서는 object 로
$('#grid').jqGrid({
datatype : "json",
mtype : 'POST',
url : url,
postData : gridPostData,
colNames : [ 'API 그룹 명',
/*'설명',*/
'표시순서',
'공개여부',
'생성자',
'생성일시',
'변경자',
'변경일시',
'id',
],
colModel : [ { name : 'groupName' , align : 'center' , width:'80', sortable:false},
/*{ name : 'groupDesc' , align : 'left' },*/
{ name : 'displayOrder' , align : 'center', width:'20'},
{ name : 'displayYn' , align : 'center', width:'20', formatter:useFormatter},
{ name : 'createdBy' , align : 'center' , width:'40' },
{ name : 'createdDate' , align : 'center' , width:'60'},
{ name : 'lastModifiedBy' , align : 'center' , width:'40' },
{ name : 'lastModifiedDate' , align : 'center' , width:'60' },
{ name : 'id' , align : 'center' , width:'40', hidden: true },
],
jsonReader : {
repeatitems : false
},
pager : $('#pager'),
page : '${param.page}',
rowNum : '${rmsDefaultRowNum}',
autoheight : true,
height : $("#container").height(),
autowidth : true,
viewrecords : true,
rowList : eval('[${rmsDefaultRowList}]'),
loadComplete:function (d){
var colModel = $(this).getGridParam("colModel");
for(var i = 0 ; i< colModel.length; i++){
$(this).setColProp(colModel[i].name, {sortable : false});
}
},
ondblClickRow : function(rowId) {
var rowData = $(this).getRowData(rowId);
let key = rowData['id'];
var url2 = url_view;
url2 += '?cmd=DETAIL';
url2 += '&page=' + $(this).getGridParam("page");
url2 += '&returnUrl=' + getReturnUrl();
url2 += '&menuId=' + '${param.menuId}';
//검색값
url2 += '&' + getSearchUrl();
//key값
url2 += '&apiGroupId=' + key;
goNav(url2);
}
});
}
$(document).ready(function() {
list();
resizeJqGridWidth('grid','content_middle','1000');
$("#btn_search").click(function(){
search();
});
$("#btn_new").click(function(){
var url2 = url_view;
url2 += '?cmd=DETAIL';
url2 += '&page='+$("#grid").getGridParam("page");
url2 += '&returnUrl='+getReturnUrl();
url2 += '&menuId='+'${param.menuId}';
//검색값
url2 += '&'+getSearchUrl();
//key값
url2 += '&eaiSvcName=';
goNav(url2);
});
$("input[name^=search]").keydown(function(key){
if (key.keyCode == 13){
$("#btn_search").click();
}
});
buttonControl();
});
</script>
</head>
<body>
<div class="right_box">
<div class="content_top">
<ul class="path">
<li><a href="#">${rmsMenuPath}</a></li>
</ul>
</div><!-- end content_top -->
<div class="content_middle" id="content_middle">
<div class="search_wrap">
<button type="button" class="cssbtn" id="btn_new" level="W" ><i class="material-icons">add</i> <%= localeMessage.getString("button.new") %></button>
<button type="button" class="cssbtn" id="btn_search" level="R" ><i class="material-icons">search</i> <%= localeMessage.getString("button.search") %></button>
</div>
<div class="title" id="title" >${rmsMenuName}</div>
<table class="search_condition" cellspacing=0;>
<tbody>
<tr>
<th style="width:180px;">API 그룹 명</th>
<td>
<input type="text" name="searchGroupName" value="${param.searchGroupName}">
</td>
<th style="width:180px;">공개여부</th>
<td>
<div class="select-style">
<select name="searchDisplayYn">
<option value="">전체</option>
<option value="1">공개</option>
<option value="0">미공개</option>
</select>
</div>
</td>
</tr>
</tbody>
</table>
<table id="grid" ></table>
<div id="pager"></div>
</div><!-- end content_middle -->
</div><!-- end right_box -->
</body>
</html>
@@ -0,0 +1,493 @@
<%@ page language="java" contentType="text/html; charset=utf-8"%>
<%@ page import="java.io.*"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ include file="/jsp/common/include/localemessage.jsp" %>
<%
response.setHeader("Pragma", "No-cache");
response.setHeader("Cache-Control", "no-cache");
response.setHeader("Expires", "0");
%>
<%!
public String getRequiredLabel(String label) {
return label + " <span class=\"required-mark\">*</span>";
}
%>
<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<jsp:include page="/jsp/common/include/css.jsp"/>
<jsp:include page="/jsp/common/include/script.jsp"/>
<jsp:include page="/jsp/common/include/portal.jsp"/>
<script language="javascript" >
var url = '<c:url value="/onl/apim/apigroup/apiGroupMan.json"/>';
var url_view = '<c:url value="/onl/apim/apigroup/apiGroupMan.view"/>';
var url_popup_view = '<c:url value="/onl/transaction/apim/apiSpecManPopup.view"/>';
var isDetail = false;
let dialog;
let selectedOrgs = {};
function componentRenderingInit() {
$('#apiGrid').jqGrid({
datatype: "json",
colNames: ['업무구분',
'API ID',
'API 설명',
'표시순서'
],
colModel: [ { name : 'bizCode', align : 'center', width:'40', sortable:false},
{ name : 'apiId', align : 'left', width:'100'},
{ name : 'apiDesc', align : 'left' },
{ name : 'displayOrder', align : 'center', width: '60', editable: true,
edittype: 'text', editrules: { number: true, required: true }, formatter: 'integer' }
],
sortable: true,
rowNum: 10000,
autoheight: true,
height: "510",
autowidth: true,
multiselect: true,
viewrecords: true,
sortname: 'displayOrder',
sortorder: 'asc',
gridComplete: function() {
if (!this.sortableInitialized) {
$("#apiGrid tbody").sortable({
items: 'tr.jqgrow',
cursor: 'move',
axis: 'y',
helper: function (e, ui) {
ui.children().each(function () {
$(this).width($(this).width());
});
return ui;
},
update: function (event, ui) {
// 드래그 앤 드롭 완료 후 displayOrder 재계산
const rows = $("#apiGrid").jqGrid('getRowData');
rows.forEach((row, index) => {
const rowId = $("#apiGrid").getDataIDs()[index];
$("#apiGrid").jqGrid('setCell', rowId, 'displayOrder', index + 1);
});
}
}).disableSelection();
this.sortableInitialized = true;
}
}
});
/*$('#contentDetail').summernote({
height: 300,
toolbar: [
['style', ['style']],
['font', ['bold', 'underline', 'clear']],
['color', ['color']],
['para', ['ul', 'ol', 'paragraph']],
['table', ['table']],
['insert', ['link', 'picture', 'video']],
['view', ['codeview', 'help']]
],
callbacks: {
onInit: function() {
$('.note-editable').on('keydown', function(e) {
if (e.keyCode === 8) {
e.stopPropagation();
}
});
}
}
});*/
}
function selectOrg(selectedOrgs) {
// 기관 ID와 이름을 각각의 필드에 설정
const orgIds = selectedOrgs.map(org => org.id).join(',');
$('#displayOrg').val(orgIds);
const orgNames = selectedOrgs.map(org => org.orgName).join(', ');
$('#displayOrgName').val(orgNames);
}
function detail(key){
if (!isDetail)return;
$.ajax({
type : "POST",
url:url,
dataType:"json",
data:{cmd: 'DETAIL', apiGroupId : key},
success:function(json){
json.apiGroupApiList.sort((a, b) => {
return (a.displayOrder || 0) - (b.displayOrder || 0);
});
$("#apiGrid")[0].addJSONData(json.apiGroupApiList);
var data = json;
$('input[name=groupName]');
$("#ajaxForm input[type!=checkbox]:not([type=file]),#ajaxForm select,#ajaxForm textarea").each(function(){
var name = $(this).attr("name");
var tag = $(this).prop("tagName");
$(tag+"[name="+name+"]").val(data[name]);
});
// $('#contentDetail').summernote('code', data.contentDetail);
const files = $("input[type='file']");
for (let i = 0; i < files.length; i++) {
const fileInput = files[i];
if (data[fileInput.name]) {
const previewSelector = "#"+fileInput.name+"Preview";
$(previewSelector).attr('src', data[fileInput.name]).show();
$(previewSelector).attr('tooltip', 'true'); // 툴팁 설정
}
}
if(json.displayYn === "1") {
$("input[name=displayYn]").prop('checked', true);
} else {
$("input[name=displayYn]").prop('checked', false);
}
if(json.displayRoleCode) {
const roles = json.displayRoleCode.split(',');
roles.forEach(role => {
$('input[name="roleCode"][value="' + role + '"]').prop('checked', true);
});
}
if(json.displayOrg) {
$("#displayOrg").val(json.displayOrg); // ID 값
$("#displayOrgName").val(json.displayOrgName);
}
},
error:function(e){
alert(e.responseText);
}
});
}
function init(key){
componentRenderingInit();
detail(key);
}
function toBase64(file) {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = () => resolve(reader.result);
reader.onerror = error => reject(error);
});
}
function readURL(input, previewSelector) {
if (input.files && input.files[0]) {
var reader = new FileReader();
reader.onload = function (e) {
$(previewSelector).attr('src', e.target.result);
$(previewSelector).show();
$(previewSelector).attr('tooltip', 'true'); // 툴팁 설정
}
reader.readAsDataURL(input.files[0]);
} else {
$(previewSelector).hide();
}
}
$(document).ready(function() {
var returnUrl = getReturnUrlForReturn();
var key ="${param.apiGroupId}";
if (key != "" && key !="null"){
isDetail = true;
}
init(key);
$(document).tooltip({
items: "img[tooltip]",
content: function () {
var element = $(this);
var imgSrc = element.attr("src");
return "<img src='" + imgSrc + "' style='max-width:300px; max-height:300px;'/>";
},
track: true
});
$("#btn_select_org").click(function(){
var popupUrl = url_popup_view + "?cmd=POPUP_LIST";
var selectedOrgIds = $('#displayOrg').val() || '';
if (selectedOrgIds) {
popupUrl += "&selectedOrgIds=" + encodeURIComponent(selectedOrgIds);
}
var args = { title:'공개 법인 리스트', selectedOrgIds: selectedOrgIds };
showModal(popupUrl, args, 450, 550);
});
$("#btn_modify").click(async function(){
if (!checkRequired("ajaxForm")) return;
const roleValues = $('input[name="roleCode"]:checked')
.map(function() { return $(this).val(); })
.get()
.join(',');
$('#displayRoleCode').val(roleValues);
let postData = $('#ajaxForm').serializeArray();
if(!postData.some(item => item.name === 'displayYn')) {
postData.push({ name: "displayYn", value: "0" });
}
if (isDetail){
postData.push({ name: "cmd" , value:"UPDATE"});
}else{
postData.push({ name: "cmd" , value:"INSERT"});
}
postData = postData.filter(item => !(item.name === "id" && item.value === ''));
const files = $("input[type='file']");
for (let i = 0; i < files.length; i++) {
const fileInput = files[i];
if (fileInput.files.length > 0) {
const file = fileInput.files[0];
const base64 = await toBase64(file);
postData.push({ name: fileInput.name , value: base64});
}
}
const data = $("#apiGrid").getRowData();
const apiGroupApiList = new Array();
const apiGroupId = $("input[name=id]").val();
for ( let i = 0; i < data.length; i++) {
const apiGroupApi = {
apiId: data[i]["apiId"],
displayOrder: data[i]["displayOrder"],
}
if(apiGroupId != ''){
apiGroupApi.apiGroupId = apiGroupId;
}
apiGroupApiList.push(apiGroupApi);
}
postData.push({
name : "apiGroupApiList",
value : JSON.stringify(apiGroupApiList)
});
$.ajax({
type : "POST",
url:url,
data:postData,
success:function(args){
alert("저장 되었습니다.");
goNav(returnUrl);//LIST로 이동
},
error:function(e){
alert(e.responseText);
}
});
});
$("#btn_delete").click(function(){
if(confirm("삭제하시겠습니까?")){
var postData = $('#ajaxForm').serializeArray();
postData.push({ name: "cmd" , value:"DELETE"});
$.ajax({
type : "POST",
url:url,
data:postData,
success:function(args){
if(args.status=="error"){
alert("동기화중 오류입니다.\n확인하여 주십시요.\n" + args.message);
}else{
alert("삭제 되었습니다.");
goNav(returnUrl);//LIST로 이동
}
},
error:function(e){
alert(e.responseText);
}
});
}
});
$("#btn_previous").click(function(){
goNav(returnUrl);//LIST로 이동
});
$("#btn_popup_api").click(function(){
const args = { title: 'API 선택' };
let url2 = url_view + "?cmd=POPUP";
const currentApis = $("#apiGrid").getRowData().map(row => row.apiId);
if(currentApis.length > 0) {
url2 += "&selectedApiIds=" + encodeURIComponent(currentApis.join(','));
}
showModal(url2,args,1280,860,function (){
const popupFrame = args.self.frames[0];
const returnValue = popupFrame.returnValue;
if (!returnValue) {
return;
}
// 단일 객체인 경우도 배열로 처리하기 위해 배열로 변환
const itemsToAdd = Array.isArray(returnValue) ? returnValue : [returnValue];
itemsToAdd.forEach(item => {
// 중복 체크를 위해 현재 그리드의 데이터를 다시 가져옴
const currentGridData = $("#apiGrid").getRowData();
const isDuplicate = currentGridData.some(row => row.apiId === item.apiId);
// 중복되지 않은 경우에만 추가
if (!isDuplicate) {
const newRowId = $("#apiGrid").getGridParam("reccount") + 1;
const currentRowCount = $("#apiGrid").jqGrid('getRowData').length;
$("#apiGrid").jqGrid('addRowData', newRowId, {
bizCode: item.bizCode,
apiId: item.apiId,
apiDesc: item.apiDesc,
displayOrder: currentRowCount + 1
});
}
});
});
});
$("#btn_delete_api").click(function(){
var grid = $("#apiGrid");
var selectedRowIds = grid.jqGrid('getGridParam', 'selarrrow'); // 선택된 행의 ID 배열을 가져옴
if (selectedRowIds.length > 0) {
// 선택된 행의 ID를 복사한 배열을 사용
var idsToDelete = selectedRowIds.slice();
for (var i = 0; i < idsToDelete.length; i++) {
grid.jqGrid('delRowData', idsToDelete[i]); // 선택된 각 행을 삭제
}
} else {
alert("Please select at least one row to delete.");
}
});
$("input[type='file'][name='mainIcon']").change(function() {
readURL(this, "#mainIconPreview");
});
// $("input[type='file'][name='contentIcon']").change(function() {
// readURL(this, "#contentIconPreview");
// });
$('input[name="displayOrder"]').on('input', function() {
this.value = this.value.replace(/[^0-9]/g, '');
});
buttonControl(isDetail);
titleControl(isDetail);
});
</script>
</head>
<body>
<div class="right_box">
<div class="content_top">
<ul class="path">
<li><a href="#">${rmsMenuPath}</a></li>
</ul>
</div><!-- end content_top -->
<div class="content_middle">
<div class="search_wrap">
<button type="button" class="cssbtn" id="btn_delete" level="W" status="DETAIL"><i class="material-icons">delete</i> <%= localeMessage.getString("button.delete") %></button>
<button type="button" class="cssbtn" id="btn_modify" level="W" status="DETAIL,NEW"><i class="material-icons">save</i> <%= localeMessage.getString("button.modify") %></button>
<button type="button" class="cssbtn" id="btn_previous" level="R" status="DETAIL,NEW"><i class="material-icons">arrow_back</i> <%= localeMessage.getString("button.previous") %></button>
</div>
<div class="title">API 그룹 상세</div>
<form id="ajaxForm">
<input type="hidden" name="id">
<div id="titleRow" class="table_row_title">API 그룹</div>
<table class="table_row" cellspacing="0">
<tr>
<th style="width:150px;"><%= getRequiredLabel("API 그룹 명") %></th>
<td colspan="7">
<input type="text" name="groupName" data-required data-warning="API 그룹 명을 입력하여 주십시오.">
</td>
</tr>
<tr>
<th style="width:150px;">공개 여부</th>
<td style="width:100px;">
<label class="checkbox-inline">
<input type="checkbox" name="displayYn" value="1" onclick="this.value = this.checked ? '1' : '0'"> 공개
</label>
</td>
<th style="width:150px;"><%= getRequiredLabel("표시 순서") %></th>
<td style="width:100px;">
<input type="number" name="displayOrder" min="1" step="1" data-required data-warning="표시 순서를 입력하여 주십시오.">
</td>
<th style="width:150px;">공개 권한</th>
<td colspan="3">
<div class="checkbox-group">
<label class="checkbox-inline">
<input type="checkbox" name="roleCode" value="ROLE_USER"> 개인사용자
</label>
<label class="checkbox-inline">
<input type="checkbox" name="roleCode" value="ROLE_CORP_USER" style="margin-left: 5px;"> 법인사용자
</label>
<label class="checkbox-inline">
<input type="checkbox" name="roleCode" value="ROLE_CORP_MANAGER" style="margin-left: 5px;"> 법인관리자
</label>
<input type="hidden" name="displayRoleCode" id="displayRoleCode">
</div>
</td>
</tr>
<tr>
<th style="width:150px;">공개 법인</th>
<td colspan="7" >
<div style="display: flex;">
<input type="text" id="displayOrgName" readonly>
<input type="hidden" name="displayOrg" id="displayOrg">
<button type="button" class="cssbtn smallBtn" id="btn_select_org" style="margin-left: 10px; vertical-align: middle;" >
<i class="material-icons">search</i> 법인 선택
</button>
</div>
</td>
</tr>
<tr>
<th style="width:150px;">메인 아이콘</th>
<td colspan="7">
<input type="file" name="mainIcon" accept="image/*" />
<img id="mainIconPreview" src="#" alt="Main Icon Preview" style="display:none;height:20px">
</td>
</tr>
<%--<tr>
<th>컨텐츠 내용</th>
<td colspan="5">
<textarea name="contentDetail" id="contentDetail" rows="10" cols="50"></textarea>
</td>
</tr>--%>
</table>
<div style="margin-top:15px;">
<div style="display: flex; align-items: center; justify-content: space-between; margin-bottom: 5px ">
<div class="table_row_title" style="margin-bottom: 0px">그룹 대상 API</div>
<div style="text-align: end;">
<button type="button" class="cssbtn" id="btn_delete_api" level="W" status="DETAIL,NEW">
<i class="material-icons">delete</i> <%= localeMessage.getString("button.delete") %>
</button>
<button type="button" class="cssbtn" id="btn_popup_api" level="W" status="DETAIL,NEW">
<i class="material-icons">add</i> <%= localeMessage.getString("button.add") %>
</button>
</div>
</div>
<div id = "gridDiv">
<table id="apiGrid"></table>
</div>
</div>
</form>
</div><!-- end content_middle -->
</div><!-- end right_box -->
</body>
</html>
@@ -0,0 +1,242 @@
<%@ page language="java" contentType="text/html; charset=utf-8"%>
<%@ page import="java.io.*"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ include file="/jsp/common/include/localemessage.jsp" %>
<%
response.setHeader("Pragma", "No-cache");
response.setHeader("Cache-Control", "no-cache");
response.setHeader("Expires", "0");
%>
<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=euc-kr">
<jsp:include page="/jsp/common/include/css.jsp"/>
<jsp:include page="/jsp/common/include/script.jsp"/>
<script language="javascript" >
var url = '<c:url value="/onl/transaction/apim/apiInterfaceMan.json"/>';
var url_view = '<c:url value="/onl/transaction/apim/apiInterfaceMan.view"/>';
var selectName = "searchEaiBzwkDstcd"; // selectBox Name
function processSelectedData() {
var grid = $("#grid");
var selectedRowIds = grid.jqGrid('getGridParam', 'selarrrow');
var selectedData = [];
for(var i = 0; i < selectedRowIds.length; i++) {
var rowData = grid.jqGrid('getRowData', selectedRowIds[i]);
selectedData.push({
bizCode: rowData.eaiBzwkDstcd,
apiId: rowData.eaiSvcName,
apiDesc: rowData.eaiSvcDesc
});
}
if(selectedData.length === 0) {
alert("선택된 항목이 없습니다.");
return;
}
alert("선택한 " + selectedData.length + "건의 API를 추가합니다.");
window.returnValue = selectedData.length === 1 ? selectedData[0] : selectedData;
window.close();
}
function updateSelectionInfo(gridId) {
var grid = $(gridId || "#grid");
var selectedRows = grid.jqGrid('getGridParam', 'selarrrow');
$("#selected-count").text("총: " + selectedRows.length + " 건");
}
function init( callback) {
$.ajax({
type : "POST",
url:url,
dataType:"json",
data:{cmd: 'LIST_COMBO'},
success:function(json){
new makeOptions("BIZCODE","BIZNAME").setObj($("select[name=searchEaiBzwkDstcd]")).setNoValueInclude(true).setNoValue("","전체").setData(json.bizList).setFormat(codeName3OptionFormat).rendering();
setSearchable(selectName); // 콤보에 searchable 설정
if (typeof callback === 'function') {
callback();
}
},
error:function(e){
alert(e.responseText);
}
});
}
function detail(){
var postData = getSearchForJqgrid("cmd","LIST"); //jqgrid에서는 object 로
$("#grid").setGridParam({ url:url,postData: postData }).trigger("reloadGrid");
}
function search(){
var postData = getSearchForJqgrid("cmd","LIST"); //jqgrid에서는 object 로
$("#grid").setGridParam({ url:url,postData: postData ,page:1 }).trigger("reloadGrid");
}
function ioFormatter(cellvalue,options,rowObject){
var serviceType = sessionStorage["serviceType"];
if(cellvalue == "I"){
return "타발";
}else if(cellvalue =="O"){
return "당발";
}
}
function adapterNameShortFormatter(cellvalue,options,rowObject){
if(cellvalue == null || cellvalue == '')
return ''
return cellvalue.substring(1, 4);
}
function list(){
detail()
var gridPostData = getSearchForJqgrid("cmd","LIST"); //jqgrid에서는 object 로
// gridPostData.searchApiEnableYn = 'Y';
var urlParams = new URLSearchParams(window.location.search);
var selectedApiIds = urlParams.get("selectedApiIds");
$('#grid').jqGrid({
datatype : "json",
mtype : 'POST',
url : url,
postData : gridPostData,
colNames : [ '업무구분',
'API 명',
'API 설명',
'요청',
'응답',
'작성자',
'가상응답여부',
'SyncAsyncType',
],
colModel : [ { name : 'eaiBzwkDstcd' , align : 'center' , width:'40', sortable:false},
{ name : 'eaiSvcName' , align : 'left' , width:'100'},
{ name : 'eaiSvcDesc' , align : 'left' },
{ name : 'fromAdapter' , align : 'center' , width:'40', formatter:adapterNameShortFormatter },
{ name : 'toAdapter' , align : 'center' , width:'40', formatter:adapterNameShortFormatter },
{ name : 'author' , align : 'center' , width:'60' },
{ name : 'simYn' , align : 'center' , width:'40' },
{ name : 'syncAsyncType' , align : 'center' , width:'40', hidden: true },
],
jsonReader : {
repeatitems : false
},
pager : $('#pager'),
page : '${param.page}',
rowNum : '${rmsDefaultRowNum}',
autoheight : true,
height : $("#container").height(),
autowidth : true,
viewrecords : true,
multiselect: true,
multiboxonly: false,
rowList : eval('[${rmsDefaultRowList}]'),
loadComplete:function (d){
var $grid = $(this);
if(selectedApiIds) {
const selectedIds = selectedApiIds.split(',');
$.each($grid.getDataIDs(), function(_, id) {
var rowData = $grid.getRowData(id);
if(selectedIds.includes(rowData.eaiSvcName)) {
$grid.jqGrid('setSelection', id, true);
}
});
}
var colModel = $(this).getGridParam("colModel");
for(var i = 0 ; i< colModel.length; i++){
$(this).setColProp(colModel[i].name, {sortable : false});
}
updateSelectionInfo("#grid");
},
onSelectRow: function(rowid, status, e) {
updateSelectionInfo("#grid");
},
onSelectAll: function(rowids, status) {
updateSelectionInfo("#grid");
},
ondblClickRow : function(rowId) {
const rowData = $(this).getRowData(rowId);
const returnValue = {
bizCode: rowData.eaiBzwkDstcd,
apiId: rowData.eaiSvcName,
apiDesc: rowData.eaiSvcDesc
};
alert("선택한 API를 추가합니다.\nAPI ID: " + rowData.eaiSvcName);
window.returnValue = returnValue;
window.close();
}
});
}
$(document).ready(function() {
init(list);
resizeJqGridWidth('grid','content_middle','1000');
// 업무구분명 선택 시 자동 검색
$("select[name=searchEaiBzwkDstcd]").change(function() {
search();
});
$("#btn_search").click(function(){
search();
});
$("input[name^=search]").keydown(function(key){
if (key.keyCode == 13){
$("#btn_search").click();
}
});
buttonControl();
$("#btn_select").click(function(){
processSelectedData();
});
$("#btn_close").click(function () {
window.close();
});
});
</script>
</head>
<body>
<div>
<div class="content_middle" id="content_middle" style="margin-top: 0px">
<div class="search_wrap">
<button type="button" class="cssbtn" id="btn_search" level="R" ><i class="material-icons">search</i> <%= localeMessage.getString("button.search") %></button>
<button type="button" class="cssbtn" id="btn_select" level="R" ><i class="material-icons">check</i> <%= localeMessage.getString("button.check") %></button>
<button type="button" class="cssbtn" id="btn_close" level="R" status="DETAIL"><i class="material-icons">close</i> <%= localeMessage.getString("button.close") %></button>
</div>
<div class="title" id="title" >${rmsMenuName}</div>
<!-- 선택 정보 표시 영역 추가 -->
<div style="margin-bottom: 5px;">
<span id="selected-count" style="color: #666; font-size: 12px;"></span>
</div>
<table class="search_condition" cellspacing=0;>
<tbody>
<tr>
<th style="width:180px;">업무구분명</th>
<td>
<select name="searchEaiBzwkDstcd" value="${param.searchEaiBzwkDstcd}">
</select>
</td>
<th style="width:180px;">API ID</th>
<td>
<input type="text" name="searchEaiSvcName" value="${param.searchEaiSvcName}">
</td>
</tr>
</tbody>
</table>
<table id="grid" ></table>
<div id="pager"></div>
</div><!-- end content_middle -->
</div><!-- end right_box -->
</body>
</html>
@@ -0,0 +1,138 @@
<%@ page language="java" contentType="text/html; charset=utf-8" %>
<%@ page import="java.io.*" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib uri="http://www.springframework.org/tags" prefix="spring" %>
<%@ include file="/jsp/common/include/localemessage.jsp" %>
<%
response.setHeader("Pragma", "No-cache");
response.setHeader("Cache-Control", "no-cache");
response.setHeader("Expires", "0");
%>
<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<jsp:include page="/jsp/common/include/css.jsp"/>
<jsp:include page="/jsp/common/include/script.jsp"/>
<script language="javascript">
var url = '<c:url value="/onl/apim/approval/apprequest/prodAppRequestMan.json" />';
var url_view = '<c:url value="/onl/apim/approval/apprequest/prodAppRequestMan.view" />';
$(document).ready(function() {
$('#grid').jqGrid({
datatype: "json",
mtype: 'POST',
url: url,
postData: {
cmd: 'LIST',
},
colNames: ['id', '기관명 ', '상태', '생성일'],
colModel: [
{name: 'id', align: 'center', key: true, hidden: true},
{
name: 'org.orgName',
align: 'center',
width: 150,
label: '기업명'
},
{
name: 'status',
align: 'center',
width: 80,
formatter: function(cellvalue) {
const statusMap = {
'PENDING': '대기중',
'APPROVED': '승인',
'REJECTED': '반려',
'CANCELED': '취소'
};
return statusMap[cellvalue] || cellvalue;
}
},
{name: 'createdDate', align: 'center', width: 120}
],
jsonReader: {
repeatitems: false
},
pager: $('#pager'),
rowNum: '${rmsDefaultRowNum}',
rowList: eval('[${rmsDefaultRowList}]'),
viewrecords: true,
autowidth: true,
height: 'auto',
ondblClickRow: function(rowId) {
var rowData = $(this).getRowData(rowId);
var id = rowData['id'];
var approvalType = rowData['approvalType'];
var args = {};
var url2 = url_view;
url2 += '?cmd=DETAIL';
url2 += '&menuId=' + '${param.menuId}';
url2 += '&type=' + approvalType;
url2 += '&id=' + id;
showModal(url2, args, 800, 650, function() {
$("#grid").trigger("reloadGrid");
});
},
loadError: function(jqXHR, textStatus, errorThrown) {
var location = '<%=request.getContextPath()%>/';
comloadError(jqXHR, textStatus, errorThrown, location);
}
});
resizeJqGridWidth('grid', 'content_middle', '1000');
$("#btn_search").click(function() {
var postData = getSearchForJqgrid("cmd", "LIST");
$("#grid").setGridParam({url: url, postData: postData, page: 1}).trigger("reloadGrid");
});
$("select[name^=search], input[name^=search]").keydown(function(key) {
if (key.keyCode == 13) {
$("#btn_search").click();
}
});
buttonControl();
});
</script>
</head>
<body>
<div class="right_box">
<div class="content_top">
<ul class="path">
<li><a href="#">${rmsMenuPath}</a></li>
</ul>
</div><!-- end content_top -->
<div class="content_middle" id="content_middle">
<div class="search_wrap">
<button type="button" class="cssbtn" id="btn_search" level="R"><i class="material-icons">search</i> <%= localeMessage.getString("button.search") %>
</button>
</div>
<div class="title">운영 인증키 요청 목록<span class="tooltip">운영 인증키 요청을 관리합니다.</span></div>
<form id="ajaxForm" onsubmit="return false;">
<table class="search_condition" cellspacing="0">
<tbody>
<tr>
<th style="width:10%;">승인 상태</th>
<td style="width:15%;">
<div class="select-style">
<select name="searchStatus">
<option value="">전체</option>
<option value="PENDING">대기중</option>
<option value="CANCELED">취소됨</option>
<option value="DENIED">반려됨</option>
<option value="APPROVED">승인됨</option>
</select>
</div>
</td>
</tr>
</tbody>
</table>
</form>
<table id="grid"></table>
<div id="pager"></div>
</div><!-- end content_middle -->
</div><!-- end right_box -->
</body>
</html>
@@ -0,0 +1,129 @@
<%@ page contentType="text/html; charset=utf-8" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib uri="http://www.springframework.org/tags" prefix="spring" %>
<%@ include file="/jsp/common/include/localemessage.jsp" %>
<%
response.setHeader("Pragma", "No-cache");
response.setHeader("Cache-Control", "no-cache");
response.setHeader("Expires", "0");
%>
<html>
<head>
<title>운영 인증키 요청 상세</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<jsp:include page="/jsp/common/include/css.jsp"/>
<jsp:include page="/jsp/common/include/script.jsp"/>
<script language="javascript">
var url = '<c:url value="/onl/apim/approval/apprequest/prodAppRequestMan.json" />';
var url_view = '<c:url value="/onl/apim/approval/apprequest/prodAppRequestMan.view" />';
let appRequest = null;
$(document).ready(function() {
var key = "${param.id}";
if (key) {
detail(key);
}
$("#btn_close").click(function() {
window.close();
});
$("#btn_save").click(function() {
console.log(appRequest);
if (confirm("변경하시겠습니까?")) {
$.ajax({
type: "POST",
url: url,
data: {cmd: "UPDATE", id: key, apiList: JSON.stringify(appRequest.apiList), status :$("#approvalStatus").val()},
success: function(args) {
alert("변경되었습니다.");
window.opener.location.reload();
window.close();
},
error: function(e) {
alert(e.responseText);
}
});
}
});
});
function detail(key) {
$.ajax({
type: "POST",
url: url,
dataType: "json",
data: {cmd: 'DETAIL', id: key},
success: function(json) {
var data = json;
appRequest = json;
$("#approvalStatus").val(data.status);
$("#requesterOrg").text(data.org.orgName);
$("#reason").text(data.reason);
$("#createdDate").text(data.createdDate).inputmask("9999-99-99 99:99:99", {'autoUnmask': true});
var apisHtml = "";
for (var i = 0; i < data.apiList.length; i++) {
var api = data.apiList[i];
apisHtml += "<tr>";
apisHtml += "<td>" + api.apiName + "</td>";
apisHtml += "</tr>";
}
$("#apisTable tbody").html(apisHtml);
},
error: function(e) {
alert(e.responseText);
}
});
}
</script>
</head>
<body>
<div class="popup_box">
<div class="title" id="approvalSubject" style="margin-top: 15px;"></div>
<%--제목--%>
<div class="popup_content">
<table class="table_row" cellspacing="0">
<tr>
<th>요청 기관</th>
<td><span id="requesterOrg"></span></td>
<th style="width:20%;">처리 상태</th>
<td style="width:30%;">
<select id="approvalStatus" style="width:100%" >
<option value="PENDING">대기중</option>
<option value="APPROVED">승인</option>
<option value="DENIED">반려</option>
</select>
</td>
</tr>
<tr>
<th>요청일자</th>
<td><span id="createdDate"></span></td>
<th></th>
<td></td>
</tr>
<tr>
<th>요청 사유</th>
<td colspan="3"><span id="reason"></span></td>
</tr>
</table>
<div class="title">API 목록</div>
<table id="apisTable" class="table_row" cellspacing="0">
<thead>
<tr>
<th>API 이름</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
<div class="popup_button">
<button type="button" class="cssbtn" id="btn_save" level="W"><i class="material-icons">check</i>저장</button>
<button type="button" class="cssbtn" id="btn_close" level="R"><i class="material-icons">cancel</i> <%= localeMessage.getString("button.close") %>
</button>
</div>
</div>
</body>
</html>
@@ -0,0 +1,138 @@
<%@ page language="java" contentType="text/html; charset=utf-8" %>
<%@ page import="java.io.*" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ include file="/jsp/common/include/localemessage.jsp" %>
<%
response.setHeader("Pragma", "No-cache");
response.setHeader("Cache-Control", "no-cache");
response.setHeader("Expires", "0");
%>
<html>s
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<jsp:include page="/jsp/common/include/css.jsp"/>
<jsp:include page="/jsp/common/include/script.jsp"/>
<script language="javascript">
var url = '<c:url value="/onl/apim/approval/credential/credentialMan.json" />';
var url_view = '<c:url value="/onl/apim/approval/credential/credentialMan.view" />';
$(document).ready(function () {
var gridPostData = getSearchForJqgrid("cmd", "LIST");
$('#grid').jqGrid({
datatype: "json",
mtype: 'POST',
url: url,
postData: gridPostData,
colNames: [
'clientid',
'법인 명',
'서버',
'<%= localeMessage.getString("clntMan.clntNm") %>',
'APP 상태'
],
colModel: [
{name: 'clientid', key: true, hidden: true },
{name: 'orgname', align: 'left', sortable: false},
{name: 'server', align: 'center', sortable: false},
{name: 'clientname', align: 'left', sortable: false},
{
name: 'appstatus',
align: 'center',
sortable: false,
formatter: function (cellvalue, options, rowObject) {
return cellvalue === '0' ? '차단' : '정상';
}
}
],
jsonReader: {
repeatitems: false
},
pager: $('#pager'),
page: '${param.page}',
rowNum: '${rmsDefaultRowNum}',
autoheight: true,
height: $("#container").height(),
autowidth: true,
viewrecords: true,
rowList: eval('[${rmsDefaultRowList}]'),
ondblClickRow: function (rowId) {
var rowData = $(this).getRowData(rowId);
var url2 = url_view;
url2 += '?cmd=DETAIL';
url2 += '&page=' + $(this).getGridParam("page");
url2 += '&returnUrl=' + getReturnUrl();
url2 += '&menuId=' + '${param.menuId}';
url2 += '&' + getSearchUrl();
url2 += '&clientId=' + rowData['clientid'];
goNav(url2);
}
});
resizeJqGridWidth('grid', 'content_middle', '1000');
$("#btn_search").click(function () {
var postData = getSearchForJqgrid("cmd", "LIST"); //jqgrid에서는 object 로
$("#grid").setGridParam({postData: postData, page: "1"}).trigger("reloadGrid");
});
<%--$("#btn_new").click(function () {--%>
<%-- var url2 = url_view;--%>
<%-- url2 += '?cmd=DETAIL';--%>
<%-- url2 += '&page=' + $("#grid").getGridParam("page");--%>
<%-- url2 += '&returnUrl=' + getReturnUrl();--%>
<%-- url2 += '&menuId=' + '${param.menuId}';--%>
<%-- //검색값--%>
<%-- url2 += '&' + getSearchUrl();--%>
<%-- goNav(url2);--%>
<%--});--%>
$("input[name^=search]").keydown(function (key) {
if (key.keyCode == 13) {
$("#btn_search").click();
}
});
buttonControl();
});
</script>
</head>
<body>
<div class="right_box">
<div class="content_top">
<ul class="path">
<li><a href="#">${rmsMenuPath}</a></li>
</ul>
</div><!-- end content_top -->
<div class="content_middle" id="content_middle">
<div class="search_wrap">
<%-- <button type="button" class="cssbtn" id="btn_new" level="W"><i--%>
<%-- class="material-icons">add</i> <%= localeMessage.getString("button.new") %>--%>
<%-- </button>--%>
<button type="button" class="cssbtn" id="btn_search" level="R"><i
class="material-icons">search</i> <%= localeMessage.getString("button.search") %>
</button>
</div>
<div class="title" id="title">${rmsMenuName}</div>
<table class="search_condition" cellspacing=0;>
<tbody>
<tr>
<th style="width:180px;"><%= localeMessage.getString("clntMan.clntNm") %>
</th>
<td><input type="text" name="searchClientName" value="${param.searchClientName}"></td>
<th style="width:180px;"><%= localeMessage.getString("clntMan.clntId") %>
</th>
<td><input type="text" name="searchClientId" value="${param.searchClientId}"></td>
</tr>
</tbody>
</table>
<table id="grid"></table>
<div id="pager"></div>
</div><!-- end content_middle -->
</div><!-- end right_box -->
</body>
</html>
@@ -0,0 +1,403 @@
<%@ page language="java" contentType="text/html; charset=utf-8" %>
<%@ page import="java.io.*" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ include file="/jsp/common/include/localemessage.jsp" %>
<%
response.setHeader("Pragma", "No-cache");
response.setHeader("Cache-Control", "no-cache");
response.setHeader("Expires", "0");
%>
<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<jsp:include page="/jsp/common/include/css.jsp"/>
<jsp:include page="/jsp/common/include/script.jsp"/>
<script language="javascript">
var url = '<c:url value="/onl/apim/approval/credential/credentialMan.json" />';
var api_url_view = '<c:url value="/onl/apim/apigroup/apiGroupMan.view" />';
var group_url_view = '<c:url value="/onl/admin/authserver/clientMan.view" />';
var isDetail = false;
function isValid() {
if ($('input[name=clientname]').val() == "") {
alert("CLIENT명을 입력하여 주십시요.");
$('input[name=clientname]').focus();
return false;
}
if ($('input[name=clientId]').val() == "") {
alert("CLIENT 아이디를 입력하여 주십시요.");
$('input[name=clientId]').focus();
return false;
}
return true;
}
function detail(key) {
if (!isDetail) return;
$.ajax({
type: "POST",
url: url,
dataType: "json",
data: {cmd: 'DETAIL', clientId: key},
success: function (json) {
var apiList = json["apiList"];
$("#selectedApiGrid").jqGrid("clearGridData");
$("#selectedApiGrid")[0].addJSONData(apiList);
var data = json;
$("#btn_gen_id").hide();
$('input[name=clientId]').css('width', '100%');
$('input[name=clientid]').attr('readonly', true);
$('input[name=clientname]').attr('readonly', true);
$("#btn_clientId_byte").hide();
$("#btn_gen_secret").hide();
$('input[name=clientSecret]').css('width', '100%');
$('input[name=clientSecret]').attr('readonly', true);
$("#btn_clientSecret_byte").hide();
$('select[name=orgid]').prop('disabled', true);
$("#ajaxForm input[type!=checkbox],#ajaxForm select,#ajaxForm textarea").each(function () {
var name = $(this).attr("name");
var tag = $(this).prop("tagName").toLowerCase();
$(tag + "[name=" + name + "]").val(data[name]);
});
// Set the appStatus dropdown value
if (json.appstatus !== undefined && json.appstatus !== null) {
$('select[name=appStatus]').val(json.appstatus);
} else {
$('select[name=appStatus]').val('1'); // Set to normal if no value
}
},
error: function (e) {
alert(e.responseText);
}
});
}
function init(key, callback) {
var selectedApiGrid = $("#selectedApiGrid");
selectedApiGrid.jqGrid({
datatype: "local",
colNames: ['API ID', 'API 이름'],
colModel: [
{name: 'apiId', index: 'apiId', width: 100, align: 'center'},
{name: 'apiName', index: 'apiName', width: 100, align: 'center'}
],
rowNum: 10,
rowList: [10, 20, 30],
pager: '#selectedApiGridPager',
sortname: 'apiId',
viewrecords: true,
sortorder: "asc",
caption: "선택된 API",
height: 200,
autowidth: true,
// multiselect: true,
ondblClickRow: function (rowid, status, e) {
// selectedApiGrid.jqGrid('delRowData', rowid);
}
});
$.ajax({
type: "POST",
url: url,
dataType: "json",
data: {cmd: 'LIST_DETAIL_COMBO'},
success: function (json) {
json.portalOrgList.unshift({
id: "", // 실제 저장될 값은 빈 문자열
orgName: "미분류" // 화면에 표시될 텍스트
});
new makeOptions("id", "orgName")
.setObj($("select[name=orgid]"))
.setFormat(nameOptionFormat)
.setData(json.portalOrgList).rendering();
},
error: function (e) {
alert(e.responseText);
}
});
callback(key);
}
$(document).ready(function () {
var returnUrl = getReturnUrlForReturn();
var key = "${param.clientId}";
if (key != "" && key != "null") {
isDetail = true;
}
init(key, detail);
$("#btn_modify").click(function () {
if (!isValid()) {
return;
}
var postData = $('#ajaxForm').serializeArray();
if (isDetail) {
postData.push({name: "cmd", value: "UPDATE"});
} else {
postData.push({name: "cmd", value: "INSERT"});
}
var data = $("#selectedApiGrid").getRowData();
var gridData = [];
for (var i = 0; i < data.length; i++) {
gridData.push({apiId: data[i]['apiId']});
}
const orgName = $("select[name=orgid] option:selected").text();
postData.push({
name: "orgname",
value: orgName
});
postData.push({
name: "apiList",
value: JSON.stringify(gridData)
});
$.ajax({
type: "POST",
url: url,
data: postData,
success: function (args) {
alert("저장 되었습니다.");
goNav(returnUrl);//LIST로 이동
},
error: function (e) {
alert(e.responseText);
}
});
});
$("#btn_delete").click(function () {
if (confirm("삭제하시겠습니까?")) {
var postData = $('#ajaxForm').serializeArray();
postData.push({name: "cmd", value: "DELETE"});
$.ajax({
type: "POST",
url: url,
data: postData,
success: function (args) {
if (args.status == "error") {
alert("동기화중 오류입니다.\n확인하여 주십시요.\n" + args.message);
} else {
alert("삭제 되었습니다.");
goNav(returnUrl);//LIST로 이동
}
},
error: function (e) {
alert(e.responseText);
}
});
}
});
$("#btn_popup_api").click(function () {
const args = {};
const url2 = api_url_view += "?cmd=POPUP";
showModal(url2, args, 1280, 860, function () {
const popupFrame = args.self.frames[0];
const returnValue = popupFrame.returnValue;
const frameElement = popupFrame.frameElement
const parentElement = frameElement.parentNode; // 부모 노드를 가져옴
if (parentElement) { // 부모 노드가 존재하는지 확인
parentElement.removeChild(frameElement);
}
var rows = $("#selectedApiGrid").jqGrid('getRowData');
console.log(returnValue);
const apiId = returnValue.apiId;
var apiIdExists = rows.some(function (row) {
return row.apiId === apiId;
});
if (apiIdExists) {
return;
}
returnValue.apiName = returnValue.apiDesc;
var ids = $("#selectedApiGrid").jqGrid('getDataIDs');
var lastId = ids.length > 0 ? Math.max.apply(Math, ids) : 0;
var newId = lastId + 1;
$("#selectedApiGrid").jqGrid('addRowData', newId, returnValue, "last");
});
});
$("#btn_popup_api_group").click(function () {
const args = {};
const url2 = group_url_view += "?cmd=GROUP_POPUP";
showModal(url2, args, 1280, 860, function () {
const popupFrame = args.self.frames[0];
const returnValue = popupFrame.returnValue;
const frameElement = popupFrame.frameElement
const parentElement = frameElement.parentNode; // 부모 노드를 가져옴
if (parentElement) { // 부모 노드가 존재하는지 확인
parentElement.removeChild(frameElement);
}
var rows = $("#selectedApiGrid").jqGrid('getRowData');
console.log(returnValue);
if (!returnValue.apiGroupApiList || returnValue.apiGroupApiList.length === 0) {
return; // If apiGroupApiList is empty, do nothing
}
returnValue.apiGroupApiList.forEach(function (apiGroupApi) {
const apiId = apiGroupApi.apiId;
var apiIdExists = rows.some(function (row) {
return row.apiId === apiId;
});
if (apiIdExists) {
return;
}
apiGroupApi.apiName = apiGroupApi.apiDesc;
var ids = $("#selectedApiGrid").jqGrid('getDataIDs');
var lastId = ids.length > 0 ? Math.max.apply(Math, ids) : 0;
var newId = lastId + 1;
$("#selectedApiGrid").jqGrid('addRowData', newId, apiGroupApi, "last");
});
});
});
$("#btn_delete_api").click(function () {
var grid = $("#selectedApiGrid");
var selectedRowIds = grid.jqGrid('getGridParam', 'selarrrow'); // 선택된 행의 ID 배열을 가져옴
if (selectedRowIds.length > 0) {
// 선택된 행의 ID를 복사한 배열을 사용
var idsToDelete = selectedRowIds.slice();
for (var i = 0; i < idsToDelete.length; i++) {
grid.jqGrid('delRowData', idsToDelete[i]); // 선택된 각 행을 삭제
}
} else {
alert("Please select at least one row to delete.");
}
});
$("#btn_previous").click(function () {
goNav(returnUrl);//LIST로 이동
});
$("#btn_gen_id").click(function () {
//$('input[name=clientId]').val(generateString(32));
$('input[name=clientId]').val(generateString($("#btn_clientId_byte").val()));
});
$("#btn_gen_secret").click(function () {
//$('input[name=clientSecret]').val(generateString(128));
$('input[name=clientSecret]').val(generateString($("#btn_clientSecret_byte").val()));
});
buttonControl(isDetail);
titleControl(isDetail);
});
const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
function generateString(length) {
let result = '';
const charactersLength = characters.length;
for (let i = 0; i < length; i++) {
result += characters.charAt(Math.floor(Math.random() * charactersLength));
}
return result;
}
</script>
</head>
<body>
<div class="right_box">
<div class="content_top">
<ul class="path">
<li><a href="#">${rmsMenuPath}</a></li>
</ul>
</div><!-- end content_top -->
<div class="content_middle">
<div class="search_wrap">
<button type="button" class="cssbtn" id="btn_delete" level="W" status="DETAIL"><i class="material-icons">delete</i> <%= localeMessage.getString("button.delete") %>
</button>
<%-- <button type="button" class="cssbtn" id="btn_modify" level="W" status="DETAIL,NEW"><i--%>
<%-- class="material-icons">save</i> <%= localeMessage.getString("button.modify") %>--%>
<%-- </button>--%>
<button type="button" class="cssbtn" id="btn_previous" level="R" status="DETAIL,NEW"><i
class="material-icons">arrow_back</i> <%= localeMessage.getString("button.previous") %>
</button>
</div>
<div class="title" id="title">${rmsMenuName}</div>
<form id="ajaxForm">
<table class="table_row" cellspacing="0">
<tr>
<th style="width:180px;"><%= localeMessage.getString("clntManDtl.clntNm") %> <small>(*)</small></th>
<td><input type="text" name="clientname"/></td>
</tr>
<tr>
<th><%= localeMessage.getString("clntManDtl.clntId") %> <small>(*)</small></th>
<td>
<input type="text" name="clientid" />
<%-- <select name="clientId_byte" id="btn_clientId_byte" style="width: 76px;">--%>
<%-- <option value="32" selected="selected">32 byte</option>--%>
<%-- <option value="64">64 byte</option>--%>
<%-- <option value="128">128 byte</option>--%>
<%-- <option value="256">256 byte</option>--%>
<%-- </select>--%>
<%-- <img src="<c:url value="/img/btn_pop_input.png"/>" id="btn_gen_id"/>--%>
</td>
</tr>
<tr>
<th>APP 상태</th>
<td>
<div class="select-style">
<select name="appstatus" >
<option value="1" selected>정상</option>
<option value="0">차단</option>
</select>
</div>
</td>
</tr>
<tr>
<th>법인</th>
<td>
<div class="select-style">
<select id="orgId" class="form-control" name="orgid">
</select>
</div>
</td>
</tr>
</table>
</form>
<div style="font-size:0;">
<div style="display: flex; align-items: center; justify-content: space-between; margin-bottom: 5px ">
<div class="table_row_title" style="margin-bottom: 0px">API</div>
<%-- <div style="text-align: end;">--%>
<%-- <button type="button" class="cssbtn" id="btn_delete_api" level="W" status="DETAIL,NEW">--%>
<%-- <i class="material-icons">delete</i> <%= localeMessage.getString("button.delete") %>--%>
<%-- </button>--%>
<%-- <button type="button" class="cssbtn" id="btn_popup_api" level="W" status="DETAIL,NEW">--%>
<%-- <i class="material-icons">add</i> API <%= localeMessage.getString("button.add") %>--%>
<%-- </button>--%>
<%-- <button type="button" class="cssbtn" id="btn_popup_api_group" level="W" status="DETAIL,NEW">--%>
<%-- <i class="material-icons">add</i> API 그룹<%= localeMessage.getString("button.add") %>--%>
<%-- </button>--%>
<%-- </div>--%>
</div>
<div style="display:inline-block; width:calc(100%); vertical-align:top;">
<div id="selectedApiList" style="margin-top:10px;">
<table id="selectedApiGrid"></table>
</div>
</div>
</div>
</div><!-- end content_middle -->
</div><!-- end right_box -->
</body>
</html>
@@ -0,0 +1,138 @@
<%@ page language="java" contentType="text/html; charset=utf-8" %>
<%@ page import="java.io.*" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ include file="/jsp/common/include/localemessage.jsp" %>
<%
response.setHeader("Pragma", "No-cache");
response.setHeader("Cache-Control", "no-cache");
response.setHeader("Expires", "0");
%>
<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=euc-kr">
<jsp:include page="/jsp/common/include/css.jsp"/>
<jsp:include page="/jsp/common/include/script.jsp"/>
<link href="<c:url value='/addon/bootstrap-5.3.2/css/bootstrap.min.css'/>" rel="stylesheet"/>
<script src="<c:url value='/addon/bootstrap-5.3.2/js/bootstrap.bundle.min.js'/>"></script>
<script language="javascript">
var url = '<c:url value="/onl/apim/apigroup/apiGroupMan.json"/>';
var url_view = '<c:url value="/onl/apim/apigroup/apiGroupMan.view"/>';
var responseData = {};
function useFormatter(cellvalue, options, rowObject) {
if (cellvalue == null || cellvalue == '')
return '';
return cellvalue === '0' ? '미사용' : '사용';
}
function detail() {
var postData = getSearchForJqgrid("cmd", "LIST"); // jqGrid expects an object
$("#grid").setGridParam({url: url, postData: postData}).trigger("reloadGrid");
}
function search() {
var postData = getSearchForJqgrid("cmd", "LIST"); // jqGrid expects an object
$("#grid").setGridParam({url: url, postData: postData, page: 1}).trigger("reloadGrid");
}
function list() {
detail();
var gridPostData = getSearchForJqgrid("cmd", "LIST"); // jqGrid expects an object
$('#grid').jqGrid({
datatype: "json",
mtype: 'POST',
url: url,
postData: gridPostData,
colNames: ['API 그룹 명', '설명', 'id'],
colModel: [
{name: 'groupName', align: 'center', width: '80', sortable: false},
{name: 'groupDesc', align: 'left'},
{name: 'id', align: 'center', width: '40', hidden: true}
],
jsonReader: {
root: function (obj) {
responseData = obj.rows; // Store the response data
return obj.rows;
},
repeatitems: false
},
pager: $('#pager'),
page: '${param.page}',
rowNum: '${rmsDefaultRowNum}',
autoheight: true,
height: $("#container").height(),
autowidth: true,
viewrecords: true,
rowList: eval('[${rmsDefaultRowList}]'),
loadComplete: function(d) {
var colModel = $(this).getGridParam("colModel");
for (var i = 0; i < colModel.length; i++) {
$(this).setColProp(colModel[i].name, {sortable: false});
}
},
ondblClickRow: function(rowId) {
const rowData = $(this).getRowData(rowId);
$.ajax({
type : "POST",
url:url,
dataType:"json",
data:{cmd: 'DETAIL', apiGroupId : rowData.id},
success:function(json){
window.returnValue = json;
window.close();
},
error:function(e){
alert(e.responseText);
}
});
}
});
}
$(document).ready(function() {
list();
resizeJqGridWidth('grid', 'content_middle', '1000');
$("#btn_search").click(function() {
search();
});
$("input[name^=search]").keydown(function(key) {
if (key.keyCode == 13) {
$("#btn_search").click();
}
});
buttonControl();
});
</script>
</head>
<body>
<div>
<div class="content_middle" id="content_middle" style="margin-top: 0px">
<div class="search_wrap">
<button type="button" class="cssbtn" id="btn_search" level="R"><i class="material-icons">search</i> <%= localeMessage.getString("button.search") %>
</button>
</div>
<div class="title" id="title">${rmsMenuName}</div>
<table class="search_condition" cellspacing="0">
<tbody>
<tr>
<th style="width:180px;">API 그룹 명</th>
<td>
<input type="text" name="searchGroupName" value="${param.searchGroupName}">
</td>
<th style="width:180px;">설명</th>
<td>
<input type="text" name="searchGroupDesc" value="${param.searchGroupDesc}">
</td>
</tr>
</tbody>
</table>
<table id="grid"></table>
<div id="pager"></div>
</div><!-- end content_middle -->
</div><!-- end right_box -->
</body>
</html>
@@ -0,0 +1,103 @@
<%@ page language="java" contentType="text/html; charset=utf-8"%>
<%@ page import="java.io.*"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ include file="/jsp/common/include/localemessage.jsp" %>
<%
response.setHeader("Pragma", "No-cache");
response.setHeader("Cache-Control", "no-cache");
response.setHeader("Expires", "0");
%>
<html>
<head>
<title>Client 선택</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<jsp:include page="/jsp/common/include/css_custom.jsp"/>
<jsp:include page="/jsp/common/include/css.jsp"/>
<jsp:include page="/jsp/common/include/script.jsp"/>
</head>
<script language="javascript">
var url = '<c:url value="/onl/admin/authserver/clientMan.json" />';
$(document).ready(function() {
var gridPostData = getSearchForJqgrid("cmd","POPUP_LIST");
$('#grid').jqGrid({
datatype: "json",
mtype: 'POST',
url: url,
postData: gridPostData,
colNames: ['클라이언트명', '클라이언트ID', '스코프', 'GRANT타입', 'TOKEN유효시간(초)'],
colModel: [
{ name: 'CLIENTNAME', align: 'left', sortable: false },
{ name: 'CLIENTID', align: 'left', sortable: false },
{ name: 'SCOPE', align: 'left', sortable: false },
{ name: 'GRANTTYPES', align: 'left', sortable: false },
{ name: 'ACCESSTOKENVALIDITYSECONDS', align: 'center', sortable: false }
],
jsonReader: {
repeatitems: false
},
pager : $('#pager'),
page : '${param.page}',
rowNum: '${rmsDefaultRowNum}',
autoheight: true,
height: 'auto',
autowidth: true,
viewrecords: true,
shrinkToFit: true,
rowList: eval('[${rmsDefaultRowList}]'),
ondblClickRow: function(rowid) {
var rowData = $(this).getRowData(rowid);
var clientId = rowData['CLIENTID'];
if (window.opener && typeof window.opener.selectClient === "function") {
window.opener.selectClient(clientId);
window.close();
} else if (window.parent && typeof window.parent.selectClient === "function") {
window.parent.selectClient(clientId);
window.parent.closeModal();
}
}
});
resizeJqGridWidth('grid', 'popup_box', '100%');
$("#btn_search").click(function(){
var postData = getSearchForJqgrid("cmd","POPUP_LIST");
$("#grid").setGridParam({ postData: postData, page: 1 }).trigger("reloadGrid");
});
$("#btn_close").click(function(){
if (window.parent && typeof window.parent.closeModal === "function") {
window.parent.closeModal();
} else {
window.close();
}
});
$("input[name^=search]").keydown(function(key){
if (key.keyCode == 13){
$("#btn_search").click();
}
});
});
</script>
<body>
<div class="popup_box" >
<div class="search_wrap">
<button type="button" class="cssbtn" id="btn_search" level="R"><i class="material-icons">search</i> <%= localeMessage.getString("button.search") %></button>
<button type="button" class="cssbtn" id="btn_close" level="R"><i class="material-icons">cancel</i> <%= localeMessage.getString("button.close") %></button>
</div>
<div class="title">Client 선택</div>
<table class="search_condition" cellspacing="0">
<tr>
<th>클라이언트명</th>
<td><input type="text" name="searchClientName" value="${param.searchClientName}"></td>
<th>클라이언트ID</th>
<td><input type="text" name="searchClientId" value="${param.searchClientId}"></td>
</tr>
</table>
<!-- grid -->
<table id="grid"></table>
<div id="pager"></div>
</div><!-- end popup_box -->
</body>
</html>
@@ -0,0 +1,288 @@
<%@ page import="com.eactive.eai.rms.common.util.CommonConstants" %>
<%@ page import="com.eactive.eai.rms.common.login.LoginVo" %>
<%@ page contentType="text/html; charset=utf-8" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib uri="http://www.springframework.org/tags" prefix="spring" %>
<%@ include file="/jsp/common/include/localemessage.jsp" %>
<%
response.setHeader("Pragma", "No-cache");
response.setHeader("Cache-Control", "no-cache");
response.setHeader("Expires", "0");
%>
<html>
<head>
<title>승인 요청 상세</title>
<style>
.table_row tbody tr.highlight_new {
background-color: #e6f3ff !important;
}
.table_row tbody tr.highlight_delete {
background-color: #ffe6e6 !important;
}
.table_row tbody tr.highlight_new td.status {
color: #4a90e2;
font-weight: normal;
}
.table_row tbody tr.highlight_delete td.status {
color: #e74c3c;
font-weight: normal;
}
</style>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<jsp:include page="/jsp/common/include/css.jsp"/>
<jsp:include page="/jsp/common/include/script.jsp"/>
<script language="javascript">
<%
LoginVo loginVo = (LoginVo) session.getAttribute(CommonConstants.LOGIN);
%>
var loginUser = '<%= loginVo.getUserId() %>';
var url = '<c:url value="/onl/apim/approval/portalApprovalMan.json" />';
var url_view = '<c:url value="/onl/apim/approval/portalApprovalMan.view" />';
$(document).ready(function () {
var key = "${param.id}";
if (key) {
detail(key);
}
$("#btn_app_approve").click(function () {
if (confirm("승인하시겠습니까?")) {
$.ajax({
type: "POST",
url: url,
data: {cmd: "APPROVE", id: key},
success: function (args) {
<%--alert("<%= localeMessage.getString("approval.approveSuccess") %>");--%>
alert("승인되었습니다.");
window.opener.location.reload();
window.close();
},
error: function (e) {
alert(e.responseText);
}
});
}
});
$("#btn_app_reject").click(function () {
var rejectReason = prompt("반려 사유를 입력해 주세요");
if (rejectReason != null) {
$.ajax({
type: "POST",
url: url,
data: {cmd: "REJECT", id: key, rejectReason: rejectReason},
success: function (args) {
alert("반려되었습니다.");
window.opener.location.reload();
window.close();
},
error: function (e) {
alert(e.responseText);
}
});
}
});
$('#btn_app_redeploy').click(function () {
if (confirm("재배포 하시겠습니까?")) {
$.ajax({
type: "POST",
url: url,
data: {cmd: "REDEPLOY", id: key},
success: function (args) {
alert("요청되었습니다.");
window.opener.location.reload();
window.close();
},
error: function (e) {
alert(e.responseText);
}
});
}
});
$("#btn_close").click(function () {
window.close();
});
});
function detail(key) {
$.ajax({
type: "POST",
url: url,
dataType: "json",
data: {cmd: 'DETAIL', id: key},
success: function (json) {
var data = json;
$("#approvalType").text(data.approvalType === 'USER' ? "법인사용자" : "API 사용");
$("#approvalStatus").text(data.approvalStatus.description);
$("#requesterName").text(data.requester.userName);
$("#approvalSubject").text(data.approvalSubject);
$("#approvalDetail").html(data.approvalDetail);
$("#createdDate").text(data.createdDate).inputmask("9999-99-99 99:99:99.999", {'autoUnmask': true});
if (data.approvers.some(approver =>
approver.approverStatus === 'CURRENT' &&
approver.user.USERID === loginUser
)) {
document.getElementById("btn_app_approve").style.display = "";
document.getElementById("btn_app_reject").style.display = "";
} else {
document.getElementById("btn_app_approve").style.display = "none";
document.getElementById("btn_app_reject").style.display = "none";
}
if (data.approvalStatus.description === '배포실패') {
document.getElementById("btn_app_redeploy").style.display = "";
}
var approversHtml = "";
data.approvers.sort((a, b) => a.ordinal - b.ordinal);
for (var i = 0; i < data.approvers.length; i++) {
var approver = data.approvers[i];
approversHtml += "<tr>";
approversHtml += "<td>" + approver.user.USERNAME + "</td>";
approversHtml += "<td>" + approver.approverStatusDescription + "</td>";
approversHtml += "<td>" + (approver.approvedDate ? new Date(approver.approvedDate).toLocaleString() : "") + "</td>";
approversHtml += "</tr>";
}
$("#approversTable tbody").html(approversHtml);
$("#clientName").text(data.clientName);
var apiServiceHtml = "";
for (var i = 0; i < data.apiServices.length; i++) {
var apiService = data.apiServices[i];
apiServiceHtml += "<tr>";
apiServiceHtml += "<td>" + apiService.groupName + "</td>";
apiServiceHtml += "</tr>";
}
$("#apiServiceTable tbody").html(apiServiceHtml);
var apisHtml = "";
for (var i = 0; i < data.apis.length; i++) {
var api = data.apis[i];
var apiGroupName = data.apiGroupNameList[i];
var isNew = false;
var isDelete = false;
if ((data.requestType === 'MODIFY' || data.requestType === 'PROD_MODIFY') && data.prevApisList && data.prevApisList.length > 0) {
isNew = !data.prevApisList.some(prevApi => prevApi.apiId === api.apiId);
}
if ((data.requestType === 'DELETE' || data.requestType === 'PROD_DELETE') && data.prevApisList && data.prevApisList.lenght > 0) {
isDelete = true;
isNew = false;
}
var trClass = "";
if (isNew) trClass = "highlight_new";
if (isDelete) trClass = "highlight_delete";
apisHtml += "<tr " + (trClass ? "class='" + trClass + "'" : "") + ">";
apisHtml += "<td>" + apiGroupName + "</td>";
apisHtml += "<td>" + api.apiName + "</td>";
apisHtml += "<td class='status'>" + (isNew ? "추가" : "") + (isDelete ? "삭제" : "") + "</td>";
apisHtml += "</tr>";
}
if ((data.requestType === 'MODIFY' || data.requestType === 'PROD_MODIFY') && data.prevApisList && data.prevApisList.length > 0) {
data.prevApisList.forEach(function(prevApi, index) {
var isDeleted = !data.apis.some(api => api.apiId === prevApi.apiId);
if (isDeleted) {
apisHtml += "<tr class='highlight_delete'>";
apisHtml += "<td>" + data.prevApiGroupNameList[index] + "</td>";
apisHtml += "<td>" + prevApi.apiName + "</td>";
apisHtml += "<td class='status'>삭제</td>";
apisHtml += "</tr>";
}
});
}
$("#apisTable tbody").html(apisHtml);
},
error: function (e) {
alert(e.responseText);
}
});
}
</script>
</head>
<body>
<div class="popup_box">
<div class="title" id="approvalSubject" style="margin-top: 15px;"></div>
<%--제목--%>
<div class="popup_content">
<table class="table_row" cellspacing="0">
<tr>
<th style="width:20%;">승인 유형</th>
<td style="width:30%;"><span id="approvalType"></span></td>
<th style="width:20%;">승인 상태</th>
<td style="width:30%;"><span id="approvalStatus"></span></td>
</tr>
<tr>
<th>요청자</th>
<td><span id="requesterName"></span></td>
<th>생성일</th>
<td><span id="createdDate"></span></td>
</tr>
<tr>
<th>상세 내용</th>
<td colspan="3">
<div id="approvalDetail" style="white-space: pre-wrap;"></div>
</td>
</tr>
</table>
<div class="title">Client 정보</div>
<table id="client" class="table_row" cellspacing="0">
<tr>
<th style="width:20%;">이름</th>
<td><span id="clientName"></span></td>
</tr>
</table>
<div class="title">API 목록</div>
<table id="apisTable" class="table_row" cellspacing="0">
<thead>
<tr>
<th>서비스명</th>
<th>API 이름</th>
<th></th>
</tr>
</thead>
<tbody>
</tbody>
</table>
<div class="title">승인자 목록</div>
<table id="approversTable" class="table_row" cellspacing="0">
<thead>
<tr>
<th>승인자</th>
<th>상태</th>
<th>승인/거절 일시</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
<div class="popup_button">
<button type="button" class="cssbtn" style="display: none;" id="btn_app_approve" level="W"><i
class="material-icons">check</i>승인
</button>
<button type="button" class="cssbtn" style="display: none;" id="btn_app_reject" level="W"><i
class="material-icons">close</i>반려
</button>
<button type="button" class="cssbtn" style="display: none;" id="btn_app_redeploy" level="W"><i
class="material-icons">close</i>재처리
</button>
<button type="button" class="cssbtn" id="btn_close" level="R"><i
class="material-icons">cancel</i> <%= localeMessage.getString("button.close") %>
</button>
</div>
</div>
</body>
</html>
@@ -0,0 +1,155 @@
<%@ page language="java" contentType="text/html; charset=utf-8"%>
<%@ page import="java.io.*"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib uri="http://www.springframework.org/tags" prefix="spring"%>
<%@ include file="/jsp/common/include/localemessage.jsp" %>
<%
response.setHeader("Pragma", "No-cache");
response.setHeader("Cache-Control", "no-cache");
response.setHeader("Expires", "0");
%>
<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<jsp:include page="/jsp/common/include/css.jsp"/>
<jsp:include page="/jsp/common/include/script.jsp"/>
<script language="javascript" >
var url = '<c:url value="/onl/apim/approval/portalApprovalMan.json" />';
var url_view = '<c:url value="/onl/apim/approval/portalApprovalMan.view" />';
const APPROVAL_TYPE_DISPLAY = {
'USER': '법인사용자',
'APP': 'API 사용'
};
$(document).ready(function() {
$('#grid').jqGrid({
datatype: "json",
mtype: 'POST',
url: url,
postData: {
cmd: 'LIST',
searchApprovalType: $('select[name=searchApprovalType]').val(),
searchApprovalStatus: $('select[name=searchApprovalStatus]').val(),
searchApprovalSubject: $('input[name=searchApprovalSubject]').val()
},
colNames: ['No.', 'id', '제목', '승인 유형', '승인 유형', '승인 상태','요청자', '생성일'],
colModel: [
{ name: 'rowNum', align: 'center', width: '30', sortable: false},
{ name: 'id', align: 'center', key: true, hidden: true },
{ name: 'approvalSubject', align: 'center', width: 200 },
{ name: 'approvalType', align: 'center', width: 80, formatter: function(cellvalue) { return APPROVAL_TYPE_DISPLAY[cellvalue] || cellvalue;}},
{ name: 'approvalType', align: 'center', width: 80, hidden: true},
{ name: 'approvalStatus.description', align: 'center', width: 80 },
{ name: 'requester.userName', align: 'center', width: 100 },
{ name: 'createdDate', align: 'center', width: 120, formatter: 'date', formatoptions: { srcformat: 'ISO8601Long', newformat: 'Y-m-d H:i:s' } }
],
jsonReader: {
repeatitems: false
},
pager: $('#pager'),
rowNum: '${rmsDefaultRowNum}',
rowList: eval('[${rmsDefaultRowList}]'),
viewrecords: true,
autowidth: true,
height: 'auto',
ondblClickRow: function(rowId) {
var rowData = $(this).getRowData(rowId);
var id = rowData['id'];
var approvalType = rowData['approvalType'];
var args = {};
var url2 = url_view;
url2 += '?cmd=DETAIL';
url2 += '&menuId=' + '${param.menuId}';
url2 += '&type=' + approvalType;
url2 += '&id=' + id;
showModal(url2, args, 800, 650, function(){
$("#grid").trigger("reloadGrid");
});
},
loadComplete: function(d) {
var records = $(this).getGridParam('records');
var page = $(this).getGridParam('page');
var rowNum = $(this).getGridParam('rowNum');
var rows = $(this).getDataIDs();
for (var i = 0; i < rows.length; i++) {
var number = ((page - 1) * rowNum + i) + 1;
// var reverseNumber = records - ((page - 1) * rowNum + i);
$(this).setCell(rows[i], 'rowNum', number);
}
},
loadError: function(jqXHR, textStatus, errorThrown) {
var location = '<%=request.getContextPath()%>/';
comloadError(jqXHR, textStatus, errorThrown, location);
}
});
resizeJqGridWidth('grid', 'content_middle', '1000');
$("#btn_search").click(function() {
var postData = getSearchForJqgrid("cmd", "LIST");
$("#grid").setGridParam({ url: url, postData: postData, page: 1 }).trigger("reloadGrid");
});
$("select[name^=search], input[name^=search]").keydown(function(key) {
if (key.keyCode == 13) {
$("#btn_search").click();
}
});
buttonControl();
});
</script>
</head>
<body>
<div class="right_box">
<div class="content_top">
<ul class="path">
<li><a href="#">${rmsMenuPath}</a></li>
</ul>
</div><!-- end content_top -->
<div class="content_middle" id="content_middle">
<div class="search_wrap">
<button type="button" class="cssbtn" id="btn_search" level="R"><i class="material-icons">search</i> <%= localeMessage.getString("button.search") %></button>
</div>
<div class="title">승인 요청 목록<span class="tooltip">승인 요청을 관리합니다.</span></div>
<form id="ajaxForm" onsubmit="return false;">
<table class="search_condition" cellspacing="0">
<tbody>
<tr>
<th style="width:10%;">승인 유형</th>
<td style="width:15%;">
<div class="select-style">
<select name="searchApprovalType">
<option value="">전체</option>
<option value="APP">API 사용</option>
<option value="USER">법인사용자</option>
</select>
</div>
</td>
<th style="width:10%;">승인 상태</th>
<td style="width:15%;">
<div class="select-style">
<select name="searchApprovalStatus">
<option value="">전체</option>
<option value="CREATED">생성됨</option>
<option value="REQUESTED">요청됨</option>
<option value="DENIED">반려됨</option>
<option value="END">승인됨</option>
</select>
</div>
</td>
<th style="width:10%;">제목</th>
<td><input type="text" name="searchApprovalSubject" value="${param.searchApprovalSubject}"></td>
</tr>
</tbody>
</table>
</form>
<table id="grid"></table>
<div id="pager"></div>
</div><!-- end content_middle -->
</div><!-- end right_box -->
</body>
</html>
@@ -0,0 +1,477 @@
<%@ page import="com.eactive.eai.rms.common.datasource.DataSourceTypeManager" %>
<%@ page import="com.eactive.eai.rms.common.login.LoginVo" %>
<%@ page import="com.eactive.eai.rms.common.util.CommonConstants" %>
<%@ page contentType="text/html; charset=utf-8" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib uri="http://www.springframework.org/tags" prefix="spring" %>
<%@ include file="/jsp/common/include/localemessage.jsp" %>
<%
response.setHeader("Pragma", "No-cache");
response.setHeader("Cache-Control", "no-cache");
response.setHeader("Expires", "0");
%>
<html>
<head>
<title>사용자 승인 요청 상세</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<jsp:include page="/jsp/common/include/css.jsp"/>
<jsp:include page="/jsp/common/include/script.jsp"/>
<jsp:include page="/jsp/common/include/portal.jsp"/>
<!-- 마스킹 해제 관련 스타일 추가 -->
<style>
.cssbtn.active {
background-color: #f0f0f0;
color: #666;
}
.alert {
padding: 10px 15px;
margin-bottom: 15px;
border: 1px solid transparent;
border-radius: 4px;
display: flex;
align-items: center;
}
.alert-warning {
color: #856404;
background-color: #fff3cd;
border-color: #ffeeba;
}
.alert i {
margin-right: 8px;
}
.unmasked-field {
background-color: #fff3cd;
color: #856404;
padding: 2px 5px;
border-radius: 3px;
}
</style>
<script language="javascript">
<%
LoginVo loginVo = (LoginVo) session.getAttribute(CommonConstants.LOGIN);
%>
var loginUser = '<%= loginVo.getUserId() %>';
var url = '<c:url value="/onl/apim/approval/portalApprovalMan.json" />';
var url_view = '<c:url value="/onl/apim/approval/portalApprovalMan.view" />';
var file_download = '<c:url value="/file/download.do" />';
$(document).ready(function() {
var key = "${param.id}";
if (key) {
detail(key);
}
$("#btn_unmask").click(function() {
var status = $(this).attr("status");
if(status === "DETAIL") {
var reason = prompt("마스킹 해제 사유를 입력해 주세요");
if (reason) {
$.ajax({
type: "POST",
url: url,
data: {
cmd: "UNMASK",
id: key,
reason: reason
},
success: function(data) {
// UI 업데이트
updateDetailView(data);
// 버튼 상태 변경
$("#btn_unmask").hide();
// 마스킹 해제 상태 표시
$(".popup_content").prepend(
'<div class="alert alert-warning" id="unmask-alert">' +
'<i class="material-icons">warning</i> ' +
'현재 마스킹 해제된 상태로 조회중입니다' +
'</div>'
);
},
error: function(e) {
alert(e.responseText);
}
});
}
} else {
// 마스킹 보기로 되돌리기
detail(key);
$(this)
.attr("status", "DETAIL")
.html('<i class="material-icons">lock_open</i> 마스킹해제')
.removeClass('active'); // 활성화 상태 클래스 제거
// 마스킹 해제 상태 알림 제거
$("#unmask-alert").remove();
}
});
$("#btn_user_approve").click(function() {
if (confirm("승인하시겠습니까?")) {
$.ajax({
type: "POST",
url: url,
data: {cmd: "APPROVE", id: key},
success: function(args) {
alert("승인되었습니다.");
window.opener.location.reload();
window.close();
},
error: function(e) {
alert(e.responseText);
}
});
}
});
$("#btn_user_reject").click(function() {
var rejectReason = prompt("반려 사유를 입력해 주세요");
if (rejectReason != null) {
$.ajax({
type: "POST",
url: url,
data: {cmd: "REJECT", id: key, rejectReason: rejectReason},
success: function(args) {
alert("반려되었습니다.");
window.opener.location.reload();
window.close();
},
error: function(e) {
alert(e.responseText);
}
});
}
});
$('#btn_user_redeploy').click(function() {
if (confirm("재배포 하시겠습니까?")) {
$.ajax({
type: "POST",
url: url,
data: {cmd: "REDEPLOY", id: key},
success: function(args) {
alert("요청되었습니다.");
window.opener.location.reload();
window.close();
},
error: function(e) {
alert(e.responseText);
}
});
}
});
$("#btn_close").click(function() {
window.close();
});
});
function downloadFile(fileId, fileSn) {
window.location.href = file_download + '?fileId=' + fileId + '&fileSn=' + fileSn;
}
function detail(key) {
$.ajax({
type: "POST",
url: url,
dataType: "json",
data: {cmd: 'DETAIL', id: key},
success: function(json) {
var data = json;
$("#approvalType").text(data.approvalType === 'USER' ? "법인사용자" : "API 사용");
$("#approvalStatus").text(data.approvalStatus.description);
$("#requesterName").text(data.requester.userName);
$("#approvalSubject").text(data.approvalSubject);
$("#createdDate").text(data.createdDate).inputmask("9999-99-99 99:99:99", {'autoUnmask': true});
// 상세 내용이 있을 때만 tr 표시
if (data.approvalDetail && $.trim(data.approvalDetail)) {
$("#approvalDetail").html(data.approvalDetail);
$("#approvalDetailRow").show();
} else {
$("#approvalDetailRow").hide();
}
data.approvers.sort((a, b) => a.ordinal - b.ordinal);
var approversHtml = "";
for (var i = 0; i < data.approvers.length; i++) {
var approver = data.approvers[i];
approversHtml += "<tr>";
approversHtml += "<td>" + approver.user.USERNAME + "</td>";
approversHtml += "<td>" + approver.approverStatusDescription + "</td>";
approversHtml += "<td>" + (approver.approvedDate ? new Date(approver.approvedDate).toLocaleString() : "") + "</td>";
approversHtml += "</tr>";
}
$("#approversTable tbody").html(approversHtml);
// Display Portal User details
var portalUser = data.portalUser;
$("#loginId").text(portalUser.loginId);
$("#userName").text(portalUser.userName);
$("#mobileNumber").text(portalUser.mobileNumber);
$("#userStatusDescription").text(portalUser.userStatusDescription);
$("#roleCodeDescription").text(portalUser.roleCodeDescription);
if (data.approvers.some(approver =>
approver.approverStatus === 'CURRENT' &&
approver.user.USERID === loginUser
)) {
document.getElementById("btn_user_approve").style.display = "";
document.getElementById("btn_user_reject").style.display = "";
} else {
document.getElementById("btn_user_approve").style.display = "none";
document.getElementById("btn_user_reject").style.display = "none";
}
if (data.approvalStatus.description === '배포실패'){
document.getElementById("btn_user_redeploy").style.display = "";
}
// Display Portal Org details
var portalOrg = portalUser.portalOrgUIs;
$("#orgName").text(portalOrg.orgName);
$("#orgStatusDescription").text(portalOrg.orgStatusDescription);
$("#serviceName").text(portalOrg.serviceName);
$("#corpRegNo").text(formatCorpRegNo(portalOrg.corpRegNo));
$("#compRegNo").text(formatCompanyRegNo(portalOrg.compRegNo));
$("#scPhoneNumber").text(portalOrg.scPhoneNumber); // 고객센터 전화번호
$("#orgPhoneNumber").text(portalOrg.orgPhoneNumber); // 회사 전화번호
$("#ceoName").text(portalOrg.ceoName); // 대표자 성명
$("#orgIndustryType").text(portalOrg.orgIndustryType || ""); // 업종
$("#orgAddr").text(portalOrg.orgAddr); // 소재지
$("#orgSectors").text(portalOrg.orgSectors || ""); // 업태
$("#orgCode").text(portalOrg.orgCode);
$("#ipWhitelist").text(portalOrg.ipWhitelist || "");
if (portalOrg.compRegFile) {
$("#fileName").text(portalOrg.fileName);
if (portalOrg.fileName) {
$("#fileWrapper").show().off('click').on('click', function() {
downloadFile(portalOrg.compRegFile, '1'); // fileSn은 단일 파일이므로 '1'로 고정
});
$("#compRegFile").val(portalOrg.compRegFile);
} else {
$("#fileWrapper").hide();
}
} else {
$("#fileName").text("");
$("#fileWrapper").hide();
}
},
error: function(e) {
alert(e.responseText);
}
});
}
function updateDetailView(data) {
$("#approvalType").text(data.approvalType === 'USER' ? "법인사용자" : "API 사용");
$("#approvalStatus").text(data.approvalStatus.description);
$("#requesterName").text(data.requester.userName);
$("#approvalSubject").text(data.approvalSubject);
$("#createdDate").text(data.createdDate).inputmask("9999-99-99 99:99:99", {'autoUnmask': true});
// 상세 내용이 있을 때만 tr 표시
if (data.approvalDetail && $.trim(data.approvalDetail)) {
$("#approvalDetail").html(data.approvalDetail);
$("#approvalDetailRow").show();
} else {
$("#approvalDetailRow").hide();
}
// 승인자 목록 업데이트
updateApprovers(data.approvers);
// 사용자 정보 업데이트
var portalUser = data.portalUser;
$("#loginId").text(portalUser.loginId);
$("#userName").text(portalUser.userName);
$("#mobileNumber").text(portalUser.mobileNumber);
$("#userStatusDescription").text(portalUser.userStatusDescription);
$("#roleCodeDescription").text(portalUser.roleCodeDescription);
// 법인 정보 업데이트
var portalOrg = portalUser.portalOrgUIs;
updateOrgInfo(portalOrg);
// 마스킹 상태에 따라 데이터를 다르게 표시
var isMasked = $("#btn_unmask").attr("status") === "DETAIL";
// 마스킹 해제 상태일 때 스타일 변경
if (!isMasked) {
// 마스킹 해제된 필드들 하이라이트
$("#userName, #loginId, #mobileNumber, #ipWhitelist").addClass("unmasked-field");
// 마스킹 해제 상태 알림 표시
if (!$("#unmask-alert").length) {
$(".popup_content").prepend(
'<div class="alert alert-warning" id="unmask-alert">' +
'<i class="material-icons">warning</i> ' +
'현재 마스킹 해제된 상태로 조회중입니다' +
'</div>'
);
}
} else {
// 마스킹된 상태로 되돌리기
$(".unmasked-field").removeClass("unmasked-field");
$("#unmask-alert").remove();
}
}
function updateApprovers(approvers) {
var approversHtml = "";
approvers.sort((a, b) => a.ordinal - b.ordinal);
for (var i = 0; i < approvers.length; i++) {
var approver = approvers[i];
approversHtml += "<tr>";
approversHtml += "<td>" + approver.user.USERNAME + "</td>";
approversHtml += "<td>" + approver.approverStatusDescription + "</td>";
approversHtml += "<td>" + (approver.approvedDate ? new Date(approver.approvedDate).toLocaleString() : "") + "</td>";
approversHtml += "</tr>";
}
$("#approversTable tbody").html(approversHtml);
}
// 법인 정보 업데이트 함수
function updateOrgInfo(portalOrg) {
$("#orgName").text(portalOrg.orgName);
$("#orgStatusDescription").text(portalOrg.orgStatusDescription);
$("#serviceName").text(portalOrg.serviceName);
$("#corpRegNo").text(formatCorpRegNo(portalOrg.corpRegNo));
$("#compRegNo").text(formatCompanyRegNo(portalOrg.compRegNo));
$("#scPhoneNumber").text(portalOrg.scPhoneNumber);
$("#orgPhoneNumber").text(portalOrg.orgPhoneNumber);
$("#ceoName").text(portalOrg.ceoName);
$("#orgIndustryType").text(portalOrg.orgIndustryType || "");
$("#orgAddr").text(portalOrg.orgAddr);
$("#orgSectors").text(portalOrg.orgSectors || "");
$("#orgCode").text(portalOrg.orgCode);
$("#ipWhitelist").text(portalOrg.ipWhitelist || "");
}
</script>
</head>
<body>
<div class="popup_box">
<div class="title" id="approvalSubject" style="margin-top: 15px;"></div>
<div class="search_wrap">
<button type="button" class="cssbtn" id="btn_unmask" level="W" status="DETAIL"><i class="material-icons">lock_open</i> 마스킹해제</button>
</div>
<%--제목--%>
<div class="popup_content">
<table class="table_row" cellspacing="0">
<tr>
<th style="width:20%;">승인 유형</th>
<td style="width:30%;"><span id="approvalType"></span></td>
<th style="width:20%;">승인 상태</th>
<td style="width:30%;"><span id="approvalStatus"></span></td>
</tr>
<tr>
<th>요청자</th>
<td id="requesterName"></td>
<th>생성일</th>
<td id="createdDate"></td>
</tr>
<tr id="approvalDetailRow">
<th>상세 내용</th>
<td colspan="3">
<div id="approvalDetail" style="white-space: pre-wrap;"></div>
</td>
</tr>
</table>
<div class="title">사용자 정보</div>
<table class="table_row" cellspacing="0">
<tr>
<th style="width:20%;">이메일 아이디</th>
<td style="width:30%;" colspan="3"><span id="loginId"></span></td>
</tr>
<tr>
<th style="width:20%;">이름</th>
<td style="width:30%;"><span id="userName"></span></td>
<th style="width:20%;">권한</th>
<td style="width:30%;"><span id="roleCodeDescription"></span></td>
</tr>
<tr>
<th>핸드폰 번호</th>
<td><span id="mobileNumber"></span></td>
<th>사용자 상태</th>
<td><span id="userStatusDescription"></span></td>
</tr>
</table>
<div class="title">법인 정보</div>
<table class="table_row" cellspacing="0">
<tr>
<th style="width:20%;">법인명</th>
<td style="width:30%;"><span id="orgName"></span></td>
<th style="width:20%;">법인 상태</th>
<td style="width:30%;"><span id="orgStatusDescription"></span></td>
</tr>
<tr>
<th>제휴기관코드</th>
<td><span id="orgCode"></span></td>
<th>업태</th>
<td><span id="orgSectors"></span></td>
</tr>
<tr>
<th>서비스명</th>
<td><span id="serviceName"></span></td>
<th>업종</th>
<td><span id="orgIndustryType"></span></td>
</tr>
<tr>
<th>법인 등록 번호</th>
<td><span id="corpRegNo"></span></td>
<th>사업자 등록 번호</th>
<td><span id="compRegNo"></span></td>
</tr>
<tr>
<th>회사 전화번호</th>
<td><span id="orgPhoneNumber"></span></td>
<th>고객 센터 전화번호</th>
<td><span id="scPhoneNumber"></span></td>
</tr>
<tr>
<th>대표자 성명</th>
<td><span id="ceoName"></span></td>
<th>소재지</th>
<td><span id="orgAddr"></span></td>
</tr>
<tr>
<th>사업자 등록증</th>
<td colspan="3">
<span id="fileWrapper" style="display: none; cursor: pointer;">
<img src="${pageContext.request.contextPath}/images/icon_file.png" style="vertical-align: middle; margin-right: 5px;">
<span id="fileName" style="text-decoration: underline;"></span>
<input type="hidden" id="compRegFile"/>
</span>
</td>
</tr>
<tr>
<th>사용 서버 IP 대역</th>
<td colspan="3"><span id="ipWhitelist"></span></td>
</tr>
</table>
<div class="title">승인자 목록</div>
<table id="approversTable" class="table_row" cellspacing="0">
<thead>
<tr>
<th>승인자</th>
<th>상태</th>
<th>승인/거절 일시</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
<div class="popup_button">
<button type="button" class="cssbtn" style="display: none;" id="btn_user_approve" level="W"><i class="material-icons">check</i>승인</button>
<button type="button" class="cssbtn" style="display: none;" id="btn_user_reject" level="W"><i class="material-icons">close</i>반려</button>
<button type="button" class="cssbtn" style="display: none;" id="btn_user_redeploy" level="W"><i class="material-icons">close</i>재처리</button>
<button type="button" class="cssbtn" id="btn_close" level="R"><i class="material-icons">cancel</i> <%= localeMessage.getString("button.close") %>
</button>
</div>
</div>
</body>
</html>
@@ -0,0 +1,136 @@
<%@ page language="java" contentType="text/html; charset=utf-8" %>
<%@ page import="java.io.*" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ include file="/jsp/common/include/localemessage.jsp" %>
<%
response.setHeader("Pragma", "No-cache");
response.setHeader("Cache-Control", "no-cache");
response.setHeader("Expires", "0");
%>
<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<jsp:include page="/jsp/common/include/css.jsp"/>
<jsp:include page="/jsp/common/include/script.jsp"/>
<script language="javascript">
var url = '<c:url value="/onl/apim/approval/prodclient/clientMan.json" />';
var url_view = '<c:url value="/onl/apim/approval/prodclient/clientMan.view" />';
$(document).ready(function () {
var gridPostData = getSearchForJqgrid("cmd", "LIST");
$('#grid').jqGrid({
datatype: "json",
mtype: 'POST',
url: url,
postData: gridPostData,
colNames: [
'clientid',
'법인 명',
'<%= localeMessage.getString("clntMan.clntNm") %>',
'APP 상태'
],
colModel: [
{name: 'clientid', key: true, hidden: true },
{name: 'orgname', align: 'left', sortable: false},
{name: 'clientname', align: 'left', sortable: false},
{
name: 'appstatus',
align: 'center',
sortable: false,
formatter: function (cellvalue, options, rowObject) {
return cellvalue === '0' ? '차단' : '정상';
}
}
],
jsonReader: {
repeatitems: false
},
pager: $('#pager'),
page: '${param.page}',
rowNum: '${rmsDefaultRowNum}',
autoheight: true,
height: $("#container").height(),
autowidth: true,
viewrecords: true,
rowList: eval('[${rmsDefaultRowList}]'),
ondblClickRow: function (rowId) {
var rowData = $(this).getRowData(rowId);
var url2 = url_view;
url2 += '?cmd=DETAIL';
url2 += '&page=' + $(this).getGridParam("page");
url2 += '&returnUrl=' + getReturnUrl();
url2 += '&menuId=' + '${param.menuId}';
url2 += '&' + getSearchUrl();
url2 += '&clientId=' + rowData['clientid'];
goNav(url2);
}
});
resizeJqGridWidth('grid', 'content_middle', '1000');
$("#btn_search").click(function () {
var postData = getSearchForJqgrid("cmd", "LIST"); //jqgrid에서는 object 로
$("#grid").setGridParam({postData: postData, page: "1"}).trigger("reloadGrid");
});
$("#btn_new").click(function () {
var url2 = url_view;
url2 += '?cmd=DETAIL';
url2 += '&page=' + $("#grid").getGridParam("page");
url2 += '&returnUrl=' + getReturnUrl();
url2 += '&menuId=' + '${param.menuId}';
//검색값
url2 += '&' + getSearchUrl();
goNav(url2);
});
$("input[name^=search]").keydown(function (key) {
if (key.keyCode == 13) {
$("#btn_search").click();
}
});
buttonControl();
});
</script>
</head>
<body>
<div class="right_box">
<div class="content_top">
<ul class="path">
<li><a href="#">${rmsMenuPath}</a></li>
</ul>
</div><!-- end content_top -->
<div class="content_middle" id="content_middle">
<div class="search_wrap">
<button type="button" class="cssbtn" id="btn_new" level="W"><i
class="material-icons">add</i> <%= localeMessage.getString("button.new") %>
</button>
<button type="button" class="cssbtn" id="btn_search" level="R"><i
class="material-icons">search</i> <%= localeMessage.getString("button.search") %>
</button>
</div>
<div class="title" id="title">${rmsMenuName}</div>
<table class="search_condition" cellspacing=0;>
<tbody>
<tr>
<th style="width:180px;"><%= localeMessage.getString("clntMan.clntNm") %>
</th>
<td><input type="text" name="searchClientName" value="${param.searchClientName}"></td>
<th style="width:180px;"><%= localeMessage.getString("clntMan.clntId") %>
</th>
<td><input type="text" name="searchClientId" value="${param.searchClientId}"></td>
</tr>
</tbody>
</table>
<table id="grid"></table>
<div id="pager"></div>
</div><!-- end content_middle -->
</div><!-- end right_box -->
</body>
</html>
@@ -0,0 +1,401 @@
<%@ page language="java" contentType="text/html; charset=utf-8" %>
<%@ page import="java.io.*" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ include file="/jsp/common/include/localemessage.jsp" %>
<%
response.setHeader("Pragma", "No-cache");
response.setHeader("Cache-Control", "no-cache");
response.setHeader("Expires", "0");
%>
<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<jsp:include page="/jsp/common/include/css.jsp"/>
<jsp:include page="/jsp/common/include/script.jsp"/>
<script language="javascript">
var url = '<c:url value="/onl/apim/approval/prodclient/clientMan.json" />';
var api_url_view = '<c:url value="/onl/apim/apigroup/apiGroupMan.view" />';
var group_url_view = '<c:url value="/onl/admin/authserver/clientMan.view" />';
var isDetail = false;
function isValid() {
if ($('input[name=clientname]').val() == "") {
alert("CLIENT명을 입력하여 주십시요.");
$('input[name=clientname]').focus();
return false;
}
if ($('input[name=clientId]').val() == "") {
alert("CLIENT 아이디를 입력하여 주십시요.");
$('input[name=clientId]').focus();
return false;
}
return true;
}
function detail(key) {
if (!isDetail) return;
$.ajax({
type: "POST",
url: url,
dataType: "json",
data: {cmd: 'DETAIL', clientId: key},
success: function (json) {
var apiList = json["apiList"];
$("#selectedApiGrid").jqGrid("clearGridData");
$("#selectedApiGrid")[0].addJSONData(apiList);
var data = json;
$("#btn_gen_id").hide();
$('input[name=clientId]').css('width', '100%');
$('input[name=clientId]').attr('readonly', true);
$("#btn_clientId_byte").hide();
$("#btn_gen_secret").hide();
$('input[name=clientSecret]').css('width', '100%');
$('input[name=clientSecret]').attr('readonly', true);
$("#btn_clientSecret_byte").hide();
$("#ajaxForm input[type!=checkbox],#ajaxForm select,#ajaxForm textarea").each(function () {
var name = $(this).attr("name");
var tag = $(this).prop("tagName").toLowerCase();
$(tag + "[name=" + name + "]").val(data[name]);
});
// Set the appStatus dropdown value
if (json.appstatus !== undefined && json.appstatus !== null) {
$('select[name=appStatus]').val(json.appstatus);
} else {
$('select[name=appStatus]').val('1'); // Set to normal if no value
}
},
error: function (e) {
alert(e.responseText);
}
});
}
function init(key, callback) {
var selectedApiGrid = $("#selectedApiGrid");
selectedApiGrid.jqGrid({
datatype: "local",
colNames: ['API ID', 'API 이름'],
colModel: [
{name: 'apiId', index: 'apiId', width: 100, align: 'center'},
{name: 'apiName', index: 'apiName', width: 100, align: 'center'}
],
rowNum: 10,
rowList: [10, 20, 30],
pager: '#selectedApiGridPager',
sortname: 'apiId',
viewrecords: true,
sortorder: "asc",
caption: "선택된 API",
height: 200,
autowidth: true,
multiselect: true,
ondblClickRow: function (rowid, status, e) {
// selectedApiGrid.jqGrid('delRowData', rowid);
}
});
$.ajax({
type: "POST",
url: url,
dataType: "json",
data: {cmd: 'LIST_DETAIL_COMBO'},
success: function (json) {
json.portalOrgList.unshift({
id: "", // 실제 저장될 값은 빈 문자열
orgName: "미분류" // 화면에 표시될 텍스트
});
new makeOptions("id", "orgName")
.setObj($("select[name=orgid]"))
.setFormat(nameOptionFormat)
.setData(json.portalOrgList).rendering();
},
error: function (e) {
alert(e.responseText);
}
});
callback(key);
}
$(document).ready(function () {
var returnUrl = getReturnUrlForReturn();
var key = "${param.clientId}";
if (key != "" && key != "null") {
isDetail = true;
}
init(key, detail);
$("#btn_modify").click(function () {
if (!isValid()) {
return;
}
var postData = $('#ajaxForm').serializeArray();
if (isDetail) {
postData.push({name: "cmd", value: "UPDATE"});
} else {
postData.push({name: "cmd", value: "INSERT"});
}
var data = $("#selectedApiGrid").getRowData();
var gridData = [];
for (var i = 0; i < data.length; i++) {
gridData.push({apiId: data[i]['apiId']});
}
const orgName = $("select[name=orgid] option:selected").text();
postData.push({
name: "orgname",
value: orgName
});
postData.push({
name: "apiList",
value: JSON.stringify(gridData)
});
$.ajax({
type: "POST",
url: url,
data: postData,
success: function (args) {
alert("저장 되었습니다.");
goNav(returnUrl);//LIST로 이동
},
error: function (e) {
alert(e.responseText);
}
});
});
$("#btn_delete").click(function () {
if (confirm("삭제하시겠습니까?")) {
var postData = $('#ajaxForm').serializeArray();
postData.push({name: "cmd", value: "DELETE"});
$.ajax({
type: "POST",
url: url,
data: postData,
success: function (args) {
if (args.status == "error") {
alert("동기화중 오류입니다.\n확인하여 주십시요.\n" + args.message);
} else {
alert("삭제 되었습니다.");
goNav(returnUrl);//LIST로 이동
}
},
error: function (e) {
alert(e.responseText);
}
});
}
});
$("#btn_popup_api").click(function () {
const args = {};
const url2 = api_url_view += "?cmd=POPUP";
showModal(url2, args, 1280, 860, function () {
const popupFrame = args.self.frames[0];
const returnValue = popupFrame.returnValue;
const frameElement = popupFrame.frameElement
const parentElement = frameElement.parentNode; // 부모 노드를 가져옴
if (parentElement) { // 부모 노드가 존재하는지 확인
parentElement.removeChild(frameElement);
}
var rows = $("#selectedApiGrid").jqGrid('getRowData');
console.log(returnValue);
const apiId = returnValue.apiId;
var apiIdExists = rows.some(function (row) {
return row.apiId === apiId;
});
if (apiIdExists) {
return;
}
returnValue.apiName = returnValue.apiDesc;
var ids = $("#selectedApiGrid").jqGrid('getDataIDs');
var lastId = ids.length > 0 ? Math.max.apply(Math, ids) : 0;
var newId = lastId + 1;
$("#selectedApiGrid").jqGrid('addRowData', newId, returnValue, "last");
});
});
$("#btn_popup_api_group").click(function () {
const args = {};
const url2 = group_url_view += "?cmd=GROUP_POPUP";
showModal(url2, args, 1280, 860, function () {
const popupFrame = args.self.frames[0];
const returnValue = popupFrame.returnValue;
const frameElement = popupFrame.frameElement
const parentElement = frameElement.parentNode; // 부모 노드를 가져옴
if (parentElement) { // 부모 노드가 존재하는지 확인
parentElement.removeChild(frameElement);
}
var rows = $("#selectedApiGrid").jqGrid('getRowData');
console.log(returnValue);
if (!returnValue.apiGroupApiList || returnValue.apiGroupApiList.length === 0) {
return; // If apiGroupApiList is empty, do nothing
}
returnValue.apiGroupApiList.forEach(function (apiGroupApi) {
const apiId = apiGroupApi.apiId;
var apiIdExists = rows.some(function (row) {
return row.apiId === apiId;
});
if (apiIdExists) {
return;
}
apiGroupApi.apiName = apiGroupApi.apiDesc;
var ids = $("#selectedApiGrid").jqGrid('getDataIDs');
var lastId = ids.length > 0 ? Math.max.apply(Math, ids) : 0;
var newId = lastId + 1;
$("#selectedApiGrid").jqGrid('addRowData', newId, apiGroupApi, "last");
});
});
});
$("#btn_delete_api").click(function () {
var grid = $("#selectedApiGrid");
var selectedRowIds = grid.jqGrid('getGridParam', 'selarrrow'); // 선택된 행의 ID 배열을 가져옴
if (selectedRowIds.length > 0) {
// 선택된 행의 ID를 복사한 배열을 사용
var idsToDelete = selectedRowIds.slice();
for (var i = 0; i < idsToDelete.length; i++) {
grid.jqGrid('delRowData', idsToDelete[i]); // 선택된 각 행을 삭제
}
} else {
alert("Please select at least one row to delete.");
}
});
$("#btn_previous").click(function () {
goNav(returnUrl);//LIST로 이동
});
$("#btn_gen_id").click(function () {
//$('input[name=clientId]').val(generateString(32));
$('input[name=clientId]').val(generateString($("#btn_clientId_byte").val()));
});
$("#btn_gen_secret").click(function () {
//$('input[name=clientSecret]').val(generateString(128));
$('input[name=clientSecret]').val(generateString($("#btn_clientSecret_byte").val()));
});
buttonControl(isDetail);
titleControl(isDetail);
});
const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
function generateString(length) {
let result = '';
const charactersLength = characters.length;
for (let i = 0; i < length; i++) {
result += characters.charAt(Math.floor(Math.random() * charactersLength));
}
return result;
}
</script>
</head>
<body>
<div class="right_box">
<div class="content_top">
<ul class="path">
<li><a href="#">${rmsMenuPath}</a></li>
</ul>
</div><!-- end content_top -->
<div class="content_middle">
<div class="search_wrap">
<button type="button" class="cssbtn" id="btn_delete" level="W" status="DETAIL"><i class="material-icons">delete</i> <%= localeMessage.getString("button.delete") %>
</button>
<button type="button" class="cssbtn" id="btn_modify" level="W" status="DETAIL,NEW"><i
class="material-icons">save</i> <%= localeMessage.getString("button.modify") %>
</button>
<button type="button" class="cssbtn" id="btn_previous" level="R" status="DETAIL,NEW"><i
class="material-icons">arrow_back</i> <%= localeMessage.getString("button.previous") %>
</button>
</div>
<div class="title" id="title">${rmsMenuName}</div>
<form id="ajaxForm">
<table class="table_row" cellspacing="0">
<tr>
<th style="width:180px;"><%= localeMessage.getString("clntManDtl.clntNm") %> <small>(*)</small></th>
<td><input type="text" name="clientname"/></td>
</tr>
<tr>
<th><%= localeMessage.getString("clntManDtl.clntId") %> <small>(*)</small></th>
<td>
<input type="text" name="clientid" style="width: calc(100% - 142px);"/>
<select name="clientId_byte" id="btn_clientId_byte" style="width: 76px;">
<option value="32" selected="selected">32 byte</option>
<option value="64">64 byte</option>
<option value="128">128 byte</option>
<option value="256">256 byte</option>
</select>
<img src="<c:url value="/img/btn_pop_input.png"/>" id="btn_gen_id"/>
</td>
</tr>
<tr>
<th>APP 상태</th>
<td>
<div class="select-style">
<select name="appstatus">
<option value="1" selected>정상</option>
<option value="0">차단</option>
</select>
</div>
</td>
</tr>
<tr>
<th>법인</th>
<td>
<div class="select-style">
<select id="orgId" class="form-control" name="orgid">
</select>
</div>
</td>
</tr>
</table>
</form>
<div style="font-size:0;">
<div style="display: flex; align-items: center; justify-content: space-between; margin-bottom: 5px ">
<div class="table_row_title" style="margin-bottom: 0px">API</div>
<div style="text-align: end;">
<button type="button" class="cssbtn" id="btn_delete_api" level="W" status="DETAIL,NEW">
<i class="material-icons">delete</i> <%= localeMessage.getString("button.delete") %>
</button>
<button type="button" class="cssbtn" id="btn_popup_api" level="W" status="DETAIL,NEW">
<i class="material-icons">add</i> API <%= localeMessage.getString("button.add") %>
</button>
<button type="button" class="cssbtn" id="btn_popup_api_group" level="W" status="DETAIL,NEW">
<i class="material-icons">add</i> API 그룹<%= localeMessage.getString("button.add") %>
</button>
</div>
</div>
<div style="display:inline-block; width:calc(100%); vertical-align:top;">
<div id="selectedApiList" style="margin-top:10px;">
<table id="selectedApiGrid"></table>
</div>
</div>
</div>
</div><!-- end content_middle -->
</div><!-- end right_box -->
</body>
</html>
@@ -0,0 +1,138 @@
<%@ page language="java" contentType="text/html; charset=utf-8" %>
<%@ page import="java.io.*" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ include file="/jsp/common/include/localemessage.jsp" %>
<%
response.setHeader("Pragma", "No-cache");
response.setHeader("Cache-Control", "no-cache");
response.setHeader("Expires", "0");
%>
<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=euc-kr">
<jsp:include page="/jsp/common/include/css.jsp"/>
<jsp:include page="/jsp/common/include/script.jsp"/>
<link href="<c:url value='/addon/bootstrap-5.3.2/css/bootstrap.min.css'/>" rel="stylesheet"/>
<script src="<c:url value='/addon/bootstrap-5.3.2/js/bootstrap.bundle.min.js'/>"></script>
<script language="javascript">
var url = '<c:url value="/onl/apim/apigroup/apiGroupMan.json"/>';
var url_view = '<c:url value="/onl/apim/apigroup/apiGroupMan.view"/>';
var responseData = {};
function useFormatter(cellvalue, options, rowObject) {
if (cellvalue == null || cellvalue == '')
return '';
return cellvalue === '0' ? '미사용' : '사용';
}
function detail() {
var postData = getSearchForJqgrid("cmd", "LIST"); // jqGrid expects an object
$("#grid").setGridParam({url: url, postData: postData}).trigger("reloadGrid");
}
function search() {
var postData = getSearchForJqgrid("cmd", "LIST"); // jqGrid expects an object
$("#grid").setGridParam({url: url, postData: postData, page: 1}).trigger("reloadGrid");
}
function list() {
detail();
var gridPostData = getSearchForJqgrid("cmd", "LIST"); // jqGrid expects an object
$('#grid').jqGrid({
datatype: "json",
mtype: 'POST',
url: url,
postData: gridPostData,
colNames: ['API 그룹 명', '설명', 'id'],
colModel: [
{name: 'groupName', align: 'center', width: '80', sortable: false},
{name: 'groupDesc', align: 'left'},
{name: 'id', align: 'center', width: '40', hidden: true}
],
jsonReader: {
root: function (obj) {
responseData = obj.rows; // Store the response data
return obj.rows;
},
repeatitems: false
},
pager: $('#pager'),
page: '${param.page}',
rowNum: '${rmsDefaultRowNum}',
autoheight: true,
height: $("#container").height(),
autowidth: true,
viewrecords: true,
rowList: eval('[${rmsDefaultRowList}]'),
loadComplete: function(d) {
var colModel = $(this).getGridParam("colModel");
for (var i = 0; i < colModel.length; i++) {
$(this).setColProp(colModel[i].name, {sortable: false});
}
},
ondblClickRow: function(rowId) {
const rowData = $(this).getRowData(rowId);
$.ajax({
type : "POST",
url:url,
dataType:"json",
data:{cmd: 'DETAIL', apiGroupId : rowData.id},
success:function(json){
window.returnValue = json;
window.close();
},
error:function(e){
alert(e.responseText);
}
});
}
});
}
$(document).ready(function() {
list();
resizeJqGridWidth('grid', 'content_middle', '1000');
$("#btn_search").click(function() {
search();
});
$("input[name^=search]").keydown(function(key) {
if (key.keyCode == 13) {
$("#btn_search").click();
}
});
buttonControl();
});
</script>
</head>
<body>
<div>
<div class="content_middle" id="content_middle" style="margin-top: 0px">
<div class="search_wrap">
<button type="button" class="cssbtn" id="btn_search" level="R"><i class="material-icons">search</i> <%= localeMessage.getString("button.search") %>
</button>
</div>
<div class="title" id="title">${rmsMenuName}</div>
<table class="search_condition" cellspacing="0">
<tbody>
<tr>
<th style="width:180px;">API 그룹 명</th>
<td>
<input type="text" name="searchGroupName" value="${param.searchGroupName}">
</td>
<th style="width:180px;">설명</th>
<td>
<input type="text" name="searchGroupDesc" value="${param.searchGroupDesc}">
</td>
</tr>
</tbody>
</table>
<table id="grid"></table>
<div id="pager"></div>
</div><!-- end content_middle -->
</div><!-- end right_box -->
</body>
</html>
@@ -0,0 +1,103 @@
<%@ page language="java" contentType="text/html; charset=utf-8"%>
<%@ page import="java.io.*"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ include file="/jsp/common/include/localemessage.jsp" %>
<%
response.setHeader("Pragma", "No-cache");
response.setHeader("Cache-Control", "no-cache");
response.setHeader("Expires", "0");
%>
<html>
<head>
<title>Client 선택</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<jsp:include page="/jsp/common/include/css_custom.jsp"/>
<jsp:include page="/jsp/common/include/css.jsp"/>
<jsp:include page="/jsp/common/include/script.jsp"/>
</head>
<script language="javascript">
var url = '<c:url value="/onl/admin/authserver/clientMan.json" />';
$(document).ready(function() {
var gridPostData = getSearchForJqgrid("cmd","POPUP_LIST");
$('#grid').jqGrid({
datatype: "json",
mtype: 'POST',
url: url,
postData: gridPostData,
colNames: ['클라이언트명', '클라이언트ID', '스코프', 'GRANT타입', 'TOKEN유효시간(초)'],
colModel: [
{ name: 'CLIENTNAME', align: 'left', sortable: false },
{ name: 'CLIENTID', align: 'left', sortable: false },
{ name: 'SCOPE', align: 'left', sortable: false },
{ name: 'GRANTTYPES', align: 'left', sortable: false },
{ name: 'ACCESSTOKENVALIDITYSECONDS', align: 'center', sortable: false }
],
jsonReader: {
repeatitems: false
},
pager : $('#pager'),
page : '${param.page}',
rowNum: '${rmsDefaultRowNum}',
autoheight: true,
height: 'auto',
autowidth: true,
viewrecords: true,
shrinkToFit: true,
rowList: eval('[${rmsDefaultRowList}]'),
ondblClickRow: function(rowid) {
var rowData = $(this).getRowData(rowid);
var clientId = rowData['CLIENTID'];
if (window.opener && typeof window.opener.selectClient === "function") {
window.opener.selectClient(clientId);
window.close();
} else if (window.parent && typeof window.parent.selectClient === "function") {
window.parent.selectClient(clientId);
window.parent.closeModal();
}
}
});
resizeJqGridWidth('grid', 'popup_box', '100%');
$("#btn_search").click(function(){
var postData = getSearchForJqgrid("cmd","POPUP_LIST");
$("#grid").setGridParam({ postData: postData, page: 1 }).trigger("reloadGrid");
});
$("#btn_close").click(function(){
if (window.parent && typeof window.parent.closeModal === "function") {
window.parent.closeModal();
} else {
window.close();
}
});
$("input[name^=search]").keydown(function(key){
if (key.keyCode == 13){
$("#btn_search").click();
}
});
});
</script>
<body>
<div class="popup_box" >
<div class="search_wrap">
<button type="button" class="cssbtn" id="btn_search" level="R"><i class="material-icons">search</i> <%= localeMessage.getString("button.search") %></button>
<button type="button" class="cssbtn" id="btn_close" level="R"><i class="material-icons">cancel</i> <%= localeMessage.getString("button.close") %></button>
</div>
<div class="title">Client 선택</div>
<table class="search_condition" cellspacing="0">
<tr>
<th>클라이언트명</th>
<td><input type="text" name="searchClientName" value="${param.searchClientName}"></td>
<th>클라이언트ID</th>
<td><input type="text" name="searchClientId" value="${param.searchClientId}"></td>
</tr>
</table>
<!-- grid -->
<table id="grid"></table>
<div id="pager"></div>
</div><!-- end popup_box -->
</body>
</html>
@@ -0,0 +1,207 @@
<%@ page language="java" contentType="text/html; charset=utf-8"%>
<%@ page import="java.io.*"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib uri="http://www.springframework.org/tags" prefix="spring"%>
<%@ include file="/jsp/common/include/localemessage.jsp" %>
<%
response.setHeader("Pragma", "No-cache");
response.setHeader("Cache-Control", "no-cache");
response.setHeader("Expires", "0");
%>
<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<jsp:include page="/jsp/common/include/css.jsp"/>
<jsp:include page="/jsp/common/include/script.jsp"/>
<script language="javascript" >
var url = '<c:url value="/onl/apim/approvalline/portalApprovalLineMan.json" />';
var url_view = '<c:url value="/onl/apim/approvalline/portalApprovalLineMan.view" />';
var select_approvalType = "";
function buttonFormatter(cellvalue, options, rowObject) {
return '<button type="button" class="cssbtn" level="W" status="DETAIL" onclick="deleteRow(\''
+ options.rowId + '\')"><i class="material-icons">delete</i> <%= localeMessage.getString("button.delete") %></button>';
}
function formatApprovalLineUsers(cellvalue, options, rowObject){
if (cellvalue && Array.isArray(cellvalue) && rowObject.portalApprovalLineUsers.length > 0){
return cellvalue.map(user => user.userName).join(' → ');
}
return '';
}
function deleteRow(rowId) {
var rowData = $("#grid").jqGrid('getRowData', rowId);
var postData = {
id: rowData.id,
cmd: 'DELETE'
};
$.ajax({
type: "POST",
url: url,
data: postData,
success: function(response) {
alert("삭제되었습니다.");
$("#grid").trigger("reloadGrid");
},
error: function(e) {
alert("삭제 중 오류가 발생했습니다.");
}
});
}
function init(){
$.ajax({
type : "POST",
url:url,
dataType:"json",
data:{cmd: 'LIST_INIT_COMBO'},
success:function(json){
new makeOptions("CODE","NAME").setObj($("select[name=approvalType]"))
.setData(json.approvalTypeRows).setFormat(nameOptionFormat).rendering();
select_approvalType = ": ;"+getGridSelectText("CODE","NAME",json.approvalTypeRows);
$('#grid').jqGrid('setColProp', 'approvalType', { editoptions: { value: select_approvalType } });
$('#grid').trigger('reloadGrid');
},
error:function(e){
alert(e.responseText);
}
});
}
$(document).ready(function() {
init();
var gridPostData = getSearchForJqgrid("cmd","LIST"); //jqgrid에서는 object 로
$('#grid').jqGrid({
datatype:"json",
mtype: 'POST',
url: url,
postData : gridPostData,
colNames:[
'No.',
"id",
'<%= localeMessage.getString("portalApprovalLine.approvalName") %>',
'<%= localeMessage.getString("portalApprovalLine.approvalUserList") %>',
'<%= localeMessage.getString("portalApprovalLine.approvalType") %>'
],
colModel:[
{ name : 'rowNum' , align:'center' , width:'30', sortable:false },
{ name : 'id' , align:'center' , key:true, hidden:true},
{ name : 'approvalName' , align:'center' , width:"100"},
{ name : 'portalApprovalLineUsers' , align:'center' , width:"100", formatter: formatApprovalLineUsers},
{ name : 'approvalType' , align:'center' , width:"100", edittype: 'select' , editoptions: { value: select_approvalType }, formatter: "select"}
],
jsonReader: {
repeatitems:false
},
pager : $('#pager'),
page : '${param.page}',
rowNum : '${rmsDefaultRowNum}',
autoheight: true,
height: $("#container").height(),
autowidth: true,
viewrecords: true,
rowList : eval('[${rmsDefaultRowList}]'),
loadComplete:function (d){
var records = $(this).getGridParam('records');
var page = $(this).getGridParam('page');
var rowNum = $(this).getGridParam('rowNum');
var rows = $(this).getDataIDs();
var colModel = $(this).getGridParam("colModel");
for (var i = 0; i < rows.length; i++) {
var number = ((page - 1) * rowNum + i) + 1;
// var reverseNumber = records - ((page - 1) * rowNum + i);
$(this).setCell(rows[i], 'rowNum', number);
}
for(var i = 0 ; i< colModel.length; i++){
$(this).setColProp(colModel[i].name, {sortable : false});
}
$(this).jqGrid('setColProp', 'approvalUserIds', {
formatter: function(cellvalue, options, rowObject) {
return formatApprovalUsers(cellvalue, options, rowObject);
}
});
},
ondblClickRow: function(rowId) {
var rowData = $(this).getRowData(rowId);
var key = rowData['id'];
var args = {};
var url2 = url_view;
url2 = url2+'?cmd=DETAIL&status=DETAIL';
url2 += '&menuId='+'${param.menuId}';
url2 += '&id=' + key;
showModal(url2, args, 800, 650, function(){
$("#grid").trigger("reloadGrid");
});
},loadError: function (jqXHR, textStatus, errorThrown) {
if(jqXHR.status == 401) {
var location ='<%=request.getContextPath()%>/';
comloadError(jqXHR, textStatus, errorThrown ,location);
}
}
});
resizeJqGridWidth('grid','content_middle','1000');
$("#btn_search").click(function(){
var postData = getSearchForJqgrid("cmd","LIST");
$("#grid").setGridParam({ url:url,postData: postData ,page:1 }).trigger("reloadGrid");
});
$("#btn_new").click(function(){
var args = {};
var url2 = url_view;
url2 = url2+'?cmd=DETAIL&status=NEW';
showModal(url2, args, 800, 650, function(){
$("#grid").trigger("reloadGrid");
});
});
$("input[name^=search]").keydown(function(key){
if (key.keyCode == 13){
$("#btn_search").click();
}
});
buttonControl();
});
</script>
</head>
<body>
<div class="right_box">
<div class="content_top">
<ul class="path">
<li><a href="#">${rmsMenuPath}</a></li>
</ul>
</div><!-- end content_top -->
<div class="content_middle" id="content_middle">
<div class="search_wrap">
<button type="button" class="cssbtn" id="btn_new" level="W"><i class="material-icons">add</i> <%= localeMessage.getString("button.new") %></button>
</div>
<div class="title"><%= localeMessage.getString("portalApprovalLine.title") %></div>
<table id="grid" ></table>
<div id="pager"></div>
</div><!-- end content_middle -->
</div><!-- end right_box -->
</body>
</html>
@@ -0,0 +1,381 @@
<%@ page language="java" contentType="text/html; charset=utf-8"%>
<%@ page import="java.io.*"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib uri="http://www.springframework.org/tags" prefix="spring"%>
<%@ include file="/jsp/common/include/localemessage.jsp" %>
<%
response.setHeader("Pragma", "No-cache");
response.setHeader("Cache-Control", "no-cache");
response.setHeader("Expires", "0");
%>
<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<jsp:include page="/jsp/common/include/css.jsp"/>
<jsp:include page="/jsp/common/include/script.jsp"/>
<script language="javascript" >
var url = '<c:url value="/onl/apim/approvalline/portalApprovalLineMan.json" />';
var url_view = '<c:url value="/onl/apim/approvalline/portalApprovalLineMan.view" />';
var isDetail = false;
var globalVars = {
approverList: [],
usedApprovalTypes: [],
originalApprovalType: null,
originalApproverList: []
};
function init (callback){
$.ajax({
type : "POST",
url:url,
dataType:"json",
data:{ cmd: 'INIT_COMBO' },
success:function(json){
new makeOptions("CODE","NAME").setObj($("select[name=approvalType]"))
.setData(json.approvalTypeRows).setFormat(nameOptionFormat).rendering();
globalVars.usedApprovalTypes = json.usedApprovalTypes || [];
if(typeof callback === 'function') {
callback();
}
},
error:function(e){
alert(e.responseText);
}
});
}
function detail(key){
$.ajax({
type : "POST",
url:url,
dataType:"json",
data:{cmd: 'DETAIL', id: key},
success:function(data){
$("#ajaxForm input[type!=radio],#ajaxForm select,#ajaxForm textarea").each(function(){
var name = $(this).attr("name");
var tag = $(this).prop("tagName").toLowerCase();
$(tag+"[name="+name+"]").val(data[name]);
});
$("select[name=approvalType]").val(data.approvalType).prop("selected", true);
globalVars.originalApprovalType = data.approvalType;
if (Array.isArray(data.portalApprovalLineUsers)) {
globalVars.approverList = data.portalApprovalLineUsers.map(user => ({
userId: user.userId,
name: user.userName
}));
globalVars.originalApproverList = JSON.parse(JSON.stringify(globalVars.approverList));
generateUser($("#approverList"));
}
},
error:function(e){
alert(e.responseText);
}
});
}
function searchUser() {
$("#gridUser").setGridParam({
postData: {
cmd: 'SEARCH_USER',
username: $('#searchUserValue').val()
},
datatype: 'json'
}).trigger('reloadGrid', [{page: 1}]);
}
function addUser(id, name) {
var exists = globalVars.approverList.some(function(u){
return u.id === id;
});
if(!exists){
globalVars.approverList.push({
userId: id,
name: name
});
generateUser($("#approverList"));
$("#noApproverMsg").hide();
} else {
alert("이미 추가된 승인자입니다.");
}
}
function generateUser($selector) {
$selector.empty();
if (globalVars.approverList.length === 0){
$("#noApproverMsg").show();
} else {
$("#noApproverMsg").hide();
var $table = $('<table>').addClass('table_row');
globalVars.approverList.forEach(function(user, idx){
var $tr = $('<tr>').data('userId', user.userId);
var $td = $('<td>').css({
'display': 'flex',
'justify-content': 'space-between',
'align-items': 'center',
'padding': '0 5px'
});
var $span = $('<span>').text((idx + 1) + '. ' + user.name);
var $delBtn = $("<button>").attr({
class: "cssbtn smallBtn",
type: "button"
}).text("선택취소").css({
'margin-left': 'auto'
}).click(function() {
globalVars.approverList.splice(idx, 1);
generateUser($selector);
});
$td.append($span).append($delBtn);
$tr.append($td);
$table.append($tr);
});
$selector.append($table);
// 드래그 앤 드롭 기능 초기화
$table.sortable({
items: 'tr',
cursor: 'move',
update: function(event, ui) {
globalVars.approverList = $table.find('tr').map(function(idx,element) {
var name = $(element).find('span').text().split('. ')[1];
$(element).find('span').text((idx + 1) + '. ' + name);
return {
userId: $(element).data('userId'),
name: name,
approvalOrder: idx + 1
};
}).get();
updateApprovalUserList();
}
});
}
updateApprovalUserList();
}
function updateApprovalUserList() {
globalVars.approverList.forEach((user, idx) => {
user.approvalOrder = idx + 1; // 순서를 idx+1로 설정
});
var approvalUserList = globalVars.approverList.map(user => user.name).join(' → ');
$('input[name=portalApprovalLineUsers]').val(approvalUserList);
$('#portalApprovalLineUsersJson').val(JSON.stringify(globalVars.approverList));
console.log("Updated list:", approvalUserList);
console.log("Current approverList with order:", globalVars.approverList);
}
$(document).ready(function() {
var key ="${param.id}";
isDetail = key != "" && key != "null";
if (isDetail){
$("#title").append(" 수정");
buttonControl(true);
} else {
$("#title").append(" 등록");
$("#btn_modify").html('<i class="material-icons">save</i> <%= localeMessage.getString("button.register") %>');
buttonControl(false);
}
init(function(){
if (isDetail) {
detail(key);
}
});
$("#gridUser").jqGrid({
datatype: 'json',
mtype:'POST',
url: url,
postData: { cmd: 'SEARCH_USER', username: '' },
colNames: ["사용자 ID", "사용자 이름"],
colModel: [
{ name: 'USERID', index: '사용자 ID', key: true , width: 200, align:'center'},
{ name: 'USERNAME', index: '사용자 이름' , width: 200, align:'center'}
],
viewrecords: true,
height: 'auto',
rowNum: 10,
pager: '#pagerUser',
jsonReader: {
root: "rows",
page: "page",
total: "total",
records: "records",
repeatitems: false,
id: "USERID"
},
ondblClickRow: function(rowid, iRow, iCol, e) {
var rowData = $(this).getRowData(rowid);
addUser(rowData.USERID, rowData.USERNAME);
},
loadComplete: function() {
// 그리드 로드 완료 후 크기 조정
$(this).setGridWidth($(this).closest('.grid_wrap').width());
}
});
$("#btn_modify").click(function(){
if (!checkRequired("ajaxForm")) return;
var formData = $('#ajaxForm').serializeArray();
var postData = {};
formData.forEach(function(field) {
postData[field.name] = field.value;
});
var approvalType = $("select[name=approvalType]").val();
// 사용 중인 approvalType 체크
if (approvalType !== globalVars.originalApprovalType
&& globalVars.usedApprovalTypes.includes(approvalType)) {
alert("선택하신 승인 타입은 이미 사용 중입니다. \n다른 타입을 선택해 주세요.");
return;
}
var uniqueApprovers = new Set(globalVars.approverList.map(a => a.userId));
if (uniqueApprovers.size !== globalVars.approverList.length) {
alert("승인자 목록에 중복된 사용자가 있습니다. \n확인 후 다시 시도해주세요.");
return;
}
if (!confirm("<%= localeMessage.getString("common.checkSave")%>")) return;
postData.portalApprovalLineUsers = $('#portalApprovalLineUsersJson').val();
postData.cmd = isDetail ? "UPDATE" : "INSERT";
$.ajax({
type : "POST",
url:url,
data:postData,
success:function(){
alert("<%= localeMessage.getString("common.saveMsg") %>");
$("#btn_close").trigger("click");
},
error: function(xhr, status, error) {
console.error("Error during save:", status, error);
alert("저장 중 오류가 발생했습니다. \n나중에 다시 시도해 주세요.");
}
});
});
var originalApproverList = [];
$("#btn_close").click(function(){
window.close();
});
$("#btn_delete").click(function(){
if(!confirm("<%= localeMessage.getString("common.confirmMsg")%>")) return;
$.ajax({
type : "POST",
url:url,
data:{cmd: 'DELETE', id: $('input[name=id]').val() },
success:function(){
alert("<%= localeMessage.getString("common.deleteMsg") %>");
$("#btn_close").trigger("click");
},
error:function(xhr, status, error){
console.error("Error deleting record:", error);
alert("삭제 중 오류가 발생했습니다. \n나중에 다시 시도해 주세요.");
}
});
});
$("#btn_search").click(function(){
searchUser();
});
$("input[name^=search]").keydown(function(key){
if (key.keyCode == 13){
$("#btn_search").click();
}
});
});
</script>
</head>
<body>
<div class="popup_box">
<div class="search_wrap">
<button type="button" class="cssbtn" id="btn_modify" level="W" status="DETAIL,NEW"><i class="material-icons">save</i> <%= localeMessage.getString("button.modify") %></button>
<button type="button" class="cssbtn" id="btn_delete" level="W" status="DETAIL"><i class="material-icons">delete</i> <%= localeMessage.getString("button.delete") %></button>
<button type="button" class="cssbtn" id="btn_close" level="R"><i class="material-icons">cancel</i> <%= localeMessage.getString("button.close") %></button>
</div>
<div class="title" id ="title"><%= localeMessage.getString("portalApprovalLine.title2") %></div>
<form id="ajaxForm">
<input type="hidden" name="id">
<input type="hidden" id="portalApprovalLineUsersJson">
<table class="table_row" cellspacing="0">
<tr>
<th style="width:25%; min-width:100px;"><%= localeMessage.getString("portalApprovalLine.approvalName") %> <font color="red"> *</font></th>
<td><input type="text" name="approvalName" data-required data-warning="승인이름을 입력하여 주십시요."/></td>
</tr>
<tr>
<th><%= localeMessage.getString("portalApprovalLine.approvalType") %> <font color="red"> *</font></th>
<td>
<div class="select-style" style="position: relative; width: 100%;">
<select name="approvalType" data-required data-warning="승인타입을 입력하여 주십시오" id="approvalType"/>
</div>
</td>
</tr>
<tr>
<th><%= localeMessage.getString("portalApprovalLine.approvalUserList") %> <font color="red"> *</font></th>
<td><input type="text" name=portalApprovalLineUsers data-required data-warning="승인자를 선택하여 주십시요." /></td></td>
</tr>
</table>
<div style="padding:20px 0px 0px 0px;">
<div class="title" ><%= localeMessage.getString("portalApprovalLine.title3") %></div>
<div style="padding:5px 0;">
<input type="text" id="searchUserValue" name="searchUserValue" placeholder="사용자 검색하기" style="width:39%; margin-right: 3px; display:inline-block;">
<button type="button" class="cssbtn" id="btn_search" level="R" status="DETAIL,NEW"><i class="material-icons">search</i> <%= localeMessage.getString("button.search") %></button>
</div>
</div>
<div style="display: flex;">
<div class="width1 grid_wrap" style="margin-right:40px;">
<table id="gridUser"class="table_row" cellspacing="0" ></table>
<div id="pagerUser" class="pagerUser"></div>
</div>
<div style="flex-grow:1;">
<span id="noApproverMsg" style="display: flex; justify-content: center; align-items: center;">
<h2>승인자를 선택해 주세요</h2>
</span>
<div id="approverListContainer">
<ul id="approverList">
<!-- 승인자 리스트가 여기에 동적으로 추가 -->
</ul>
</div>
</div>
</div>
</form>
</div><!-- end popup_box -->
</body>
</html>
@@ -0,0 +1,150 @@
<%@ page language="java" contentType="text/html; charset=utf-8"%>
<%@ page import="java.io.*"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib uri="http://www.springframework.org/tags" prefix="spring"%>
<%@ include file="/jsp/common/include/localemessage.jsp" %>
<%
response.setHeader("Pragma", "No-cache");
response.setHeader("Cache-Control", "no-cache");
response.setHeader("Expires", "0");
%>
<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<jsp:include page="/jsp/common/include/css.jsp"/>
<jsp:include page="/jsp/common/include/script.jsp"/>
<script language="javascript" >
var url = '<c:url value="/onl/apim/portalfaq/portalFaqMan.json" />';
var url_view = '<c:url value="/onl/apim/portalfaq/portalFaqMan.view" />';
function formatuseYn(cellvalue, options, rowObject) {
return cellvalue === 'N'
? '<span style="color: red;">미사용</span>'
: '<span>사용</span>';
}
$(document).ready(function() {
$('#grid').jqGrid({
datatype:"json",
mtype: 'POST',
url: url,
postData : { cmd : 'LIST',
searchSubjectDetail: $('input[name=searchSubjectDetail]').val()
},
colNames:['id', 'No.', '제목', '사용', '마지막 수정일', '등록일', '등록자'],
colModel:[
{ name : 'id' , align:'center', key:true, hidden:true},
{ name : 'rowNum' , align:'center', width:50, sortable:false },
{ name : 'faqQuestion' , align:'left' , width:300 },
{ name : 'useYn' , align:'center', width:60, formatter: formatuseYn },
{ name : 'lastModifiedDate' , align:'center', width:100, formatter: timeStampFormat },
{ name : 'createdDate' , align:'center', width:100, formatter: timeStampFormat },
{ name : 'createdByName' , align:'center', width:70 }
],
jsonReader: {
repeatitems:false
},
pager : $('#pager'),
page : '${param.page}',
rowNum : '${rmsDefaultRowNum}',
autoheight: true,
height: $("#container").height(),
autowidth: true,
viewrecords: true,
rowList : eval('[${rmsDefaultRowList}]'),
ondblClickRow: function(rowId) {
var rowData = $(this).getRowData(rowId);
var id = rowData['id'];
var url2 = url_view;
url2 += '?cmd=DETAIL';
url2 += '&page='+$(this).getGridParam("page");
url2 += '&returnUrl='+getReturnUrl();
url2 += '&menuId='+'${param.menuId}';
url2 += '&id='+id;
goNav(url2);
},
gridComplete: function() {
var records = $(this).getGridParam('records');
var page = $(this).getGridParam('page');
var rowNum = $(this).getGridParam('rowNum');
var rows = $(this).getDataIDs();
for (var i = 0; i < rows.length; i++) {
var number = ((page - 1) * rowNum + i) + 1;
// var reverseNumber = records - ((page - 1) * rowNum + i);
$(this).setCell(rows[i], 'rowNum', number);
}
},
loadError: function (jqXHR, textStatus, errorThrown) {
var location ='<%=request.getContextPath()%>/';
comloadError(jqXHR, textStatus, errorThrown ,location);
}
});
resizeJqGridWidth('grid','content_middle','1000');
$("#btn_search").click(function(){
var postData = getSearchForJqgrid("cmd","LIST");
$("#grid").setGridParam({ url:url,postData: postData ,page:1 }).trigger("reloadGrid");
});
$("#btn_new").click(function(){
var url2 = url_view;
url2 += '?cmd=DETAIL';
url2 += '&page='+$("#grid").getGridParam("page");
url2 += '&returnUrl='+getReturnUrl();
url2 += '&menuId='+'${param.menuId}';
goNav(url2);
});
$("input[name^=search]").keydown(function(key){
if (key.keyCode == 13){
$("#btn_search").click();
}
});
buttonControl();
});
</script>
</head>
<body>
<div class="right_box">
<div class="content_top">
<ul class="path">
<li><a href="#">${rmsMenuPath}</a></li>
</ul>
</div><!-- end content_top -->
<div class="content_middle" id="content_middle">
<div class="search_wrap">
<button type="button" class="cssbtn" id="btn_new" level="W"><i class="material-icons">add</i> <%= localeMessage.getString("button.new") %></button>
<button type="button" class="cssbtn" id="btn_search" level="R"><i class="material-icons">search</i> <%= localeMessage.getString("button.search") %></button>
</div>
<div class="title">FAQ 목록</div>
<form id="ajaxForm" onsubmit="return false;">
<table class="search_condition" cellspacing=0;>
<tbody>
<tr>
<th style="width:180px;">사용여부</th>
<td>
<div class="select-style">
<select name="searchUseYn">
<option value="">전체</option>
<option value="Y">사용</option>
<option value="N">미사용</option>
</select>
</div>
</td>
<th style="width:180px;">제목/내용</th>
<td><input type="text" name="searchQuestionOrAnswer"></td>
</tr>
</tbody>
</table>
</form>
<table id="grid" ></table>
<div id="pager"></div>
</div><!-- end content_middle -->
</div><!-- end right_box -->
</body>
</html>
@@ -0,0 +1,210 @@
<%@ page language="java" contentType="text/html; charset=utf-8"%>
<%@ page import="java.io.*"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib uri="http://www.springframework.org/tags" prefix="spring"%>
<%@ include file="/jsp/common/include/localemessage.jsp" %>
<%
response.setHeader("Pragma", "No-cache");
response.setHeader("Cache-Control", "no-cache");
response.setHeader("Expires", "0");
%>
<html>
<head>
<title>FAQ 상세</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<jsp:include page="/jsp/common/include/css.jsp"/>
<jsp:include page="/jsp/common/include/script.jsp"/>
<script language="javascript">
var url = '<c:url value="/onl/apim/portalfaq/portalFaqMan.json" />';
var url_view = '<c:url value="/onl/apim/portalfaq/portalFaqMan.view" />';
var isDetail = false;
function decodeHTMLEntities(text) {
var textArea = document.createElement('textarea');
textArea.innerHTML = text;
return textArea.value;
}
function detail(key) {
if (!isDetail) return;
$.ajax({
type: "POST",
url: url,
dataType: "json",
data: {cmd: 'DETAIL', id: key},
success: function (json) {
var data = json;
$("#id").val(key);
$("#faqQuestion").val(data.faqQuestion);
$("#useYn").prop("checked", data.useYn === "Y");
var decodedContent = decodeHTMLEntities(data.faqAnswer);
$('#faqAnswer').summernote('code', decodedContent);
$("#createdByName").text(data.createdByName);
$("#createdDate").text(timeStampFormat(data.createdDate));
$("#lastModifiedDate").text(timeStampFormat(data.lastModifiedDate));
},
error: function (e) {
alert(e.responseText);
}
});
}
$(document).ready(function() {
var returnUrl = getReturnUrlForReturn();
var key = "${param.id}";
isDetail = key != "" && key != "null";
if (isDetail) {
$("#title").append(" 수정");
buttonControl(true);
} else {
$("#title").append(" 등록");
$("#btn_modify").html('<i class="material-icons">save</i> <%= localeMessage.getString("button.register") %>');
buttonControl(false);
}
$('#faqAnswer').summernote({
placeholder: '여기에 답변을 입력하세요.',
height: 300,
toolbar: [
['style', ['style']],
['font', ['bold', 'underline', 'clear']],
['color', ['color']],
['para', ['ul', 'ol', 'paragraph']],
['table', ['table']],
['insert', ['link', 'picture']],
['view', ['fullscreen', 'codeview', 'help']]
],
callbacks: {
onInit: function() {
$('.note-editable').on('keydown', function(e) {
if (e.keyCode === 8) {
e.stopPropagation();
}
});
}
}
});
if (key) {
detail(key);
}
$("#btn_modify").click(function() {
if (!checkRequired("ajaxForm")) return;
// Summernote 에디터 내용 검증
var faqAnswer = $('#faqAnswer').summernote('code');
if (faqAnswer === "" || faqAnswer === "<p><br></p>" || faqAnswer === "<p></p>") {
alert("답변을 입력하여 주십시오.");
$('#faqAnswer').summernote('focus');
return;
}
if (confirm("<%= localeMessage.getString("common.checkSave")%>") != true)
return;
var postData = $('#ajaxForm').serializeArray();
postData = postData.filter(item => item.name !== "useYn");
postData.push({name: "useYn", value: $("#useYn").is(":checked") ? "Y" : "N"});
if (isDetail) {
postData.push({ name: "cmd", value: "UPDATE" });
} else {
postData.push({ name: "cmd", value: "INSERT" });
}
$.ajax({
type: "POST",
url: url,
data: postData,
success: function (json) {
alert("<%= localeMessage.getString("common.saveMsg") %>");
goNav(returnUrl);
},
error: function (e) {
alert(e.responseText);
}
});
});
$("#btn_delete").click(function() {
if (confirm("<%= localeMessage.getString("common.confirmMsg")%>")) {
var postData = $('#ajaxForm').serializeArray();
postData.push({name: "cmd", value: "DELETE"});
$.ajax({
type: "POST",
url: url,
data: postData,
success: function (args) {
alert("<%= localeMessage.getString("common.deleteMsg") %>");
goNav(returnUrl);
},
error: function (e) {
alert(e.responseText);
}
});
}
});
$("#btn_previous").click(function() {
goNav(returnUrl);
});
});
</script>
</head>
<body>
<div class="right_box">
<div class="content_top">
<ul class="path">
<li><a href="#">${rmsMenuPath}</a></li>
</ul>
</div><!-- end content_top -->
<div class="content_middle">
<div class="search_wrap">
<button type="button" class="cssbtn" id="btn_modify" level="W" status="DETAIL,NEW"><i class="material-icons">save</i> <%= localeMessage.getString("button.modify") %></button>
<button type="button" class="cssbtn" id="btn_delete" level="W" status="DETAIL"><i class="material-icons">delete</i> <%= localeMessage.getString("button.delete") %></button>
<button type="button" class="cssbtn" id="btn_previous" level="R" status="DETAIL,NEW"><i class="material-icons">arrow_back</i> <%= localeMessage.getString("button.previous") %></button>
</div>
<div class="title" id="title">FAQ</div>
<form id="ajaxForm">
<input type="hidden" name="id" id="id">
<table class="table_row" cellspacing="0">
<tr>
<th style="width:20%;">사용여부</th>
<td>
<input type="checkbox" name="useYn" id="useYn" value="Y" ${portalFaqUI.useYn eq 'Y' ? 'checked' : ''}> 사용
</td>
</tr>
<tr>
<th style="width:20%;">질문 <font color="red">*</font></th>
<td><input type="text" id="faqQuestion" name="faqQuestion" style="width:100%" data-required data-warning="질문을 입력하여 주십시오."/></td>
</tr>
<tr>
<th style="width:20%;">답변 <font color="red">*</font></th>
<td>
<textarea id="faqAnswer" name="faqAnswer" style="width:100%;height:300px" data-required data-warning="답변을 입력하여 주십시오."></textarea>
</td>
</tr>
<tr>
<th style="width:20%;">등록자</th>
<td id="createdByName"></td>
</tr>
<tr>
<th style="width:20%;">등록일</th>
<td id="createdDate"></td>
</tr>
<tr>
<th style="width:20%;">최종수정일</th>
<td id="lastModifiedDate"></td>
</tr>
</table>
</form>
</div>
</div>
</body>
</html>
@@ -0,0 +1,192 @@
<%@ page language="java" contentType="text/html; charset=utf-8"%>
<%@ page import="java.io.*"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib uri="http://www.springframework.org/tags" prefix="spring"%>
<%@ include file="/jsp/common/include/localemessage.jsp" %>
<%
response.setHeader("Pragma", "No-cache");
response.setHeader("Cache-Control", "no-cache");
response.setHeader("Expires", "0");
%>
<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<jsp:include page="/jsp/common/include/css.jsp"/>
<jsp:include page="/jsp/common/include/script.jsp"/>
<script language="javascript" >
var url = '<c:url value="/onl/apim/portalinquiry/portalInquiryMan.json" />';
var url_view = '<c:url value="/onl/apim/portalinquiry/portalInquiryMan.view" />';
var select_orgId = "";
function formatInquiryStatus(cellvalue, options, rowObject) {
return cellvalue === 'PENDING'
? '<span style="color: red;">문의중</span>'
: '<span>답변완료</span>';
}
function formatFile(cellvalue, options, rowObject) {
var iconPath = '${pageContext.request.contextPath}/images/icon_file.png';
var icon = rowObject.hasAttachment ? '<img src="' + iconPath + '" alt="File Attached" style="vertical-align: middle; margin-left: 5px; width: 16px; height: 16px;">' : '';
return cellvalue + icon;
}
function init(){
$.ajax({
type : "POST",
url:url,
dataType:"json",
data:{cmd: 'LIST_INIT_COMBO'},
success:function(json){
new makeOptions("CODE","NAME")
.setObj($("select[name=searchOrgId]"))
.setNoValueInclude(true)
.setNoValue("", "<%=localeMessage.getString("combo.all")%>")
.setData(json.orgRows)
.setFormat(nameOptionFormat).rendering();
putSelectFromParam();
select_orgId = ": ;" + getGridSelectText("CODE", "NAME", json.orgRows);
},
error:function(e){
alert(e.responseText);
}
});
}
$(document).ready(function() {
$('#grid').jqGrid({
datatype:"json",
mtype: 'POST',
url: url,
postData : { cmd : 'LIST' },
colNames:['id', 'No.', '제목', '법인명', '상태', '작성자', '등록일', '답변자','답변일'],
colModel:[
{ name : 'id' , align:'center', key:true, hidden:true},
{ name : 'rowNum' , align:'center', width:50, sortable:false },
{ name : 'inquirySubject' , align:'left' , width:200 , formatter: formatFile},
{ name : 'orgName' , align:'center' , width:100 , },
{ name : 'inquiryStatus' , align:'center', width:70, formatter: formatInquiryStatus },
{ name : 'inquirer.userName', align:'center', width:70 },
{ name : 'createdDate' , align:'center', width:100, formatter: timeStampFormat },
{ name : 'responderName' , align:'center', width:70 },
{ name : 'responseDate' , align:'center', width:100, formatter: timeStampFormat }
],
jsonReader: {
repeatitems:false
},
pager : $('#pager'),
page : '${param.page}',
rowNum : '${rmsDefaultRowNum}',
autoheight: true,
height: $("#container").height(),
autowidth: true,
viewrecords: true,
rowList : eval('[${rmsDefaultRowList}]'),
ondblClickRow: function(rowId) {
var rowData = $(this).getRowData(rowId);
var id = rowData['id'];
var url2 = url_view;
url2 += '?cmd=DETAIL';
url2 += '&page='+$(this).getGridParam("page");
url2 += '&returnUrl='+getReturnUrl();
url2 += '&menuId='+'${param.menuId}';
url2 += '&id='+id;
goNav(url2);
},
gridComplete: function() {
var records = $(this).getGridParam('records');
var page = $(this).getGridParam('page');
var rowNum = $(this).getGridParam('rowNum');
var rows = $(this).getDataIDs();
var colModel = $(this).getGridParam("colModel");
for (var i = 0; i < rows.length; i++) {
var number = ((page - 1) * rowNum + i) + 1;
// var reverseNumber = records - ((page - 1) * rowNum + i);
$(this).setCell(rows[i], 'rowNum', number);
}
},
loadError: function (jqXHR, textStatus, errorThrown) {
var location ='<%=request.getContextPath()%>/';
comloadError(jqXHR, textStatus, errorThrown ,location);
}
});
init();
resizeJqGridWidth('grid','content_middle','1000');
$("#btn_search").click(function(){
var postData = getSearchForJqgrid("cmd","LIST");
$("#grid").setGridParam({ url:url,postData: postData ,page:1 }).trigger("reloadGrid");
});
$("#btn_new").click(function(){
var url2 = url_view;
url2 += '?cmd=DETAIL';
url2 += '&page='+$("#grid").getGridParam("page");
url2 += '&returnUrl='+getReturnUrl();
url2 += '&menuId='+'${param.menuId}';
goNav(url2);
});
$("input[name^=search]").keydown(function(key){
if (key.keyCode == 13){
$("#btn_search").click();
}
});
buttonControl();
});
</script>
</head>
<body>
<div class="right_box">
<div class="content_top">
<ul class="path">
<li><a href="#">${rmsMenuPath}</a></li>
</ul>
</div><!-- end content_top -->
<div class="content_middle" id="content_middle">
<div class="search_wrap">
<button type="button" class="cssbtn" id="btn_search" level="R"><i class="material-icons">search</i> <%= localeMessage.getString("button.search") %></button>
</div>
<div class="title">Q&A 목록<span class="tooltip">Q&A를 관리합니다.</span></div>
<form id="ajaxForm" onsubmit="return false;">
<table class="search_condition" cellspacing=0;>
<tbody>
<tr>
<th style="width:150px;">답변여부</th>
<td style="width:150px;">
<div class="select-style">
<select name="searchInquiryStatus">
<option value="">전체</option>
<option value="PENDING">문의중</option>
<option value="RESPONDED">답변완료</option>
</select>
</div>
</td>
<th style="width:150px;">법인명</th>
<td style="width:250px;">
<div class="select-style">
<select name="searchOrgId"></select>
</div>
</td>
<th style="width:150px;">작성자</th>
<td style="width:150px;"><input type="text" name="searchInquiryUserName"></td>
</tr>
<tr>
<th>제목/내용</th>
<td colspan="5"><input type="text" name="searchSubjectDetail"></td>
</tr>
</tbody>
</table>
</form>
<table id="grid" ></table>
<div id="pager"></div>
</div><!-- end content_middle -->
</div><!-- end right_box -->
</body>
</html>
@@ -0,0 +1,245 @@
<%@ page language="java" contentType="text/html; charset=utf-8"%>
<%@ page import="java.io.*"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib uri="http://www.springframework.org/tags" prefix="spring"%>
<%@ include file="/jsp/common/include/localemessage.jsp" %>
<%
response.setHeader("Pragma", "No-cache");
response.setHeader("Cache-Control", "no-cache");
response.setHeader("Expires", "0");
%>
<html>
<head>
<title>Q&A 문의</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<jsp:include page="/jsp/common/include/css.jsp"/>
<jsp:include page="/jsp/common/include/script.jsp"/>
<style>
.inquiry-section {
margin-bottom: 15px;
border: 1px solid #e0e0e0;
padding: 20px;
border-radius: 5px;
}
.response-section {
margin-bottom: 30px;
border: 1px solid #e0e0e0; /* 동일한 박스 스타일 */
padding: 20px;
border-radius: 5px;
}
.section-title {
font-size: 18px;
font-weight: bold;
margin-bottom: 15px;
padding-bottom: 10px;
border-bottom: 2px solid #e0e0e0; /* 제목 아래 줄 긋기 */
}
.info-row {
margin-bottom: 10px;
display: flex;
}
.info-label {
font-weight: bold;
width: 80px;
}
.info-content {
flex: 1;
padding-left: 5px;
border-radius: 4px;
}
#responseDetail {
width: 100%;
min-height: 200px;
}
.required-mark {
color: red;
margin-left: 2px;
font-weight: bold;
}
</style>
<script language="javascript">
var url = '<c:url value="/onl/apim/portalinquiry/portalInquiryMan.json" />';
var url_view = '<c:url value="/onl/apim/portalinquiry/portalInquiryMan.view" />';
var file_download = '<c:url value="/file/download.do" />';
function decodeHTMLEntities(text) {
var textArea = document.createElement('textarea');
textArea.innerHTML = text;
return textArea.value;
}
function detail(key) {
$.ajax({
type: "POST",
url: url,
dataType: "json",
data: {cmd: 'DETAIL', id: key},
success: function (data) {
$("#id").val(key);
$("#inquirySubject").text(data.inquirySubject);
$("#inquiryDetail").html(data.inquiryDetail);
$("#inquiryStatus").text(data.inquiryStatus === 'PENDING' ? '문의중' : '답변완료');
$("#inquirer").text(data.inquirer.userName);
$("#createdDate").text(timeStampFormat(data.createdDate));
$("#responder").text(data.responderName || '');
$("#responseDate").text(timeStampFormat(data.responseDate));
var decodedContent = decodeHTMLEntities(data.responseDetail);
$("#responseDetail").summernote('code', decodedContent || '');
// 첨부 파일 표시
displayAttachFiles(data.fileInfo);
},
error: function (e) {
alert(e.responseText);
}
});
}
$(document).ready(function () {
var returnUrl = getReturnUrlForReturn();
var key = "${param.id}";
$('#responseDetail').summernote({
height: 200,
toolbar: [
['style', ['style']],
['font', ['bold', 'underline', 'clear']],
['color', ['color']],
['para', ['ul', 'ol', 'paragraph']],
['table', ['table']],
['insert', ['link']],
['view', ['codeview', 'help']]
],
callbacks: {
onInit: function () {
$('.note-editable').on('keydown', function (e) {
if (e.keyCode === 8) {
e.stopPropagation();
}
});
}
}
});
if (key) {
detail(key);
}
$("#btn_modify").click(function () {
if (!checkRequired("ajaxForm")) return;
if (!confirm("<%= localeMessage.getString("common.checkSave")%>")) return;
var postData = $('#ajaxForm').serializeArray();
postData.push({name: "cmd", value: "INSERT"});
$.ajax({
type: "POST",
url: url,
data: postData,
success: function (json) {
alert("<%= localeMessage.getString("common.saveMsg") %>");
goNav(returnUrl);
},
error: function (e) {
alert(e.responseText);
}
});
});
$("#btn_previous").click(function () {
goNav(returnUrl);
});
});
function displayAttachFiles(fileInfo) {
var $attachFileRow = $('#attachFileRow');
var $attachFiles = $('#attachFiles');
if (fileInfo && fileInfo.fileDetails && fileInfo.fileDetails.length > 0) {
var attachFilesHtml = '';
fileInfo.fileDetails.forEach(function(file) {
attachFilesHtml += '<span style="cursor: pointer;" onclick="downloadFile(\'' + file.fileId + '\', \'' + file.fileSn + '\')">';
attachFilesHtml += file.originalFileName + '.' + file.fileExtension;
var iconPath = '${pageContext.request.contextPath}/images/icon_file.png';
attachFilesHtml += '<img src="' + iconPath + '" style="vertical-align: middle; margin-left: 5px; height: 1.2em">';
attachFilesHtml += '</span><br>';
});
$attachFiles.html(attachFilesHtml);
$attachFileRow.show().css("cursor", "pointer");
} else {
$attachFileRow.hide();
}
}
function downloadFile(fileId, fileSn) {
window.location.href = file_download + '?fileId=' + fileId + '&fileSn=' + fileSn;
}
</script>
</head>
<body>
<div class="right_box">
<div class="content_top">
<ul class="path">
<li><a href="#">${rmsMenuPath}</a></li>
</ul>
</div>
<div class="content_middle">
<div class="search_wrap">
<button type="button" class="cssbtn" id="btn_modify" level="W" status="DETAIL,NEW"><i class="material-icons">save</i> <%= localeMessage.getString("button.modify") %></button>
<button type="button" class="cssbtn" id="btn_previous" level="R" status="DETAIL,NEW"><i class="material-icons">arrow_back</i> <%= localeMessage.getString("button.previous") %></button>
</div>
<div class="title">Q&A 상세</div>
<form id="ajaxForm">
<div class="inquiry-section">
<div class="section-title" id="inquirySubject"></div>
<div class="info-row">
<div class="info-label">작성자</div>
<div id="inquirer" class="info-content"></div>
</div>
<div class="info-row">
<div class="info-label">작성일</div>
<div id="createdDate" class="info-content"></div>
</div>
<div class="info-row" id="attachFileRow" style="display: none;">
<div class="info-label">첨부파일</div>
<div id="attachFiles" class="info-content"></div>
</div>
<div class="info-row">
<div class="info-label">문의 내용</div>
<div id="inquiryDetail" class="info-content" style="white-space: pre-line;"></div>
</div>
</div>
<!-- 답변 작성 부분 -->
<div class="response-section">
<div class="info-row">
<div class="info-label">답변자</div>
<div id="responder" class="info-content"></div>
</div>
<div class="info-row">
<div class="info-label">답변일</div>
<div id="responseDate" class="info-content"></div>
</div>
<div class="info-row">
<div class="info-label">답변 내용<span class="required-mark">*</span></div>
<div style="flex: 1; padding-top: 5px;">
<textarea id="responseDetail" name="responseDetail" data-required data-warning="답변 내용을 입력하여 주십시오."></textarea>
</div>
</div>
</div>
<input type="hidden" name="id" id="id">
</form>
</div>
</div>
</body>
</html>
@@ -0,0 +1,201 @@
<%@ page language="java" contentType="text/html; charset=utf-8"%>
<%@ page import="java.io.*"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ include file="/jsp/common/include/localemessage.jsp" %>
<%
response.setHeader("Pragma", "No-cache");
response.setHeader("Cache-Control", "no-cache");
response.setHeader("Expires", "0");
%>
<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<jsp:include page="/jsp/common/include/css.jsp"/>
<jsp:include page="/jsp/common/include/script.jsp"/>
<script language="javascript">
var url = '<c:url value="/onl/apim/portalmain/portalMainMan.json"/>';
var url_view = '<c:url value="/onl/apim/portalmain/portalMainMan.view"/>';
var isDetail = false;
function selectService(selectedServices) {
if(!selectedServices) {
return;
}
// 먼저 기존 그리드의 모든 데이터를 지웁니다
$("#serviceGrid").jqGrid('clearGridData');
// 선택된 서비스들만 다시 추가합니다
selectedServices.forEach(function(service) {
$("#serviceGrid").jqGrid('addRowData', service.id, service, "last");
});
}
function componentRenderingInit() {
$('#serviceGrid').jqGrid({
datatype: "json",
colNames: ['서비스 ID',
'서비스명',
'서비스 설명'
],
colModel: [
{ name: 'id', align: 'center', width:'100', key:true},
{ name: 'groupName', align: 'left', width:'150'},
{ name: 'groupDesc', align: 'left'}
],
rowNum: 10000,
autoheight: true,
height: "160",
autowidth: true,
multiselect: true,
viewrecords: true
});
}
function detail() {
$.ajax({
type: "POST",
url: url,
dataType: "json",
data: {cmd: 'DETAIL'},
success: function(json) {
var serviceList = json.services || [];
var keywordList = json.searchTags || '';
$("#serviceGrid").jqGrid('clearGridData');
// 각 서비스의 고유 ID를 행 ID로 사용
serviceList.forEach(function(service) {
$("#serviceGrid").jqGrid('addRowData', service.id, service);
});
// 키워드 리스트를 콤마로 구분된 문자열로 변환하여 input에 설정
$("#keywordList").val(keywordList);
},
error: function(e) {
alert(e.responseText);
}
});
}
$(document).ready(function() {
componentRenderingInit();
detail();
$("#btn_save").click(function() {
var serviceData = $("#serviceGrid").jqGrid('getRowData');
var keywordString = $("#keywordList").val();
var serviceIds = [];
for(var i=0; i<serviceData.length; i++) {
serviceIds.push({id: serviceData[i].id});
}
let postData = [];
postData.push({name: "services", value: JSON.stringify(serviceIds)});
postData.push({name: "searchTags", value: keywordString});
postData.push({name: "cmd", value: "INSERT"});
$.ajax({
type: "POST",
url: url,
data: postData,
success: function(args) {
alert("저장되었습니다.");
detail();
},
error: function(e) {
alert(e.responseText);
}
});
});
$("#btn_add_service").click(function() {
// 현재 선택된 서비스 목록 가져오기
var currentServices = $("#serviceGrid").jqGrid('getRowData');
var selectedIds = currentServices.map(function(service) {
return service.id;
}).join(',');
const popupUrl = url_view + "?cmd=POPUP&selectedIds=" + encodeURIComponent(selectedIds);
const args = {
title: 'API 그룹 선택',
callback: function(selectedData) {
if(selectedData) {
$("#serviceGrid").jqGrid('clearGridData');
selectedData.forEach(function(service) {
$("#serviceGrid").jqGrid('addRowData', service.id, service, "last");
});
}
}
};
showModal(popupUrl, args, 1280, 860);
});
$("#btn_delete_service").click(function() {
var selectedIds = $("#serviceGrid").jqGrid('getGridParam', 'selarrrow');
if (selectedIds.length > 0) {
// 선택된 행의 ID를 복사한 배열을 사용
var idsToDelete = selectedIds.slice();
for (var i = 0; i < idsToDelete.length; i++) {
$("#serviceGrid").jqGrid('delRowData', idsToDelete[i]); // 선택된 각 행을 삭제
}
} else {
alert("Please select at least one row to delete.");
}
});
});
</script>
</head>
<body>
<div class="right_box">
<div class="content_top">
<ul class="path">
<li><a href="#">${rmsMenuPath}</a></li>
</ul>
</div>
<div class="content_middle">
<div class="search_wrap">
<button type="button" class="cssbtn" id="btn_save" level="W">
<i class="material-icons">save</i> <%= localeMessage.getString("button.modify") %>
</button>
</div>
<div class="title">포털 메인 관리</div>
<div style="margin-top:15px;">
<div style="display: flex; align-items: center; justify-content: space-between; margin-bottom: 5px">
<div class="table_row_title" style="margin-bottom: 0px">메인 서비스 목록</div>
<div style="text-align: end;">
<button type="button" class="cssbtn" id="btn_delete_service" level="W">
<i class="material-icons">delete</i> <%= localeMessage.getString("button.delete") %>
</button>
<button type="button" class="cssbtn" id="btn_add_service" level="W">
<i class="material-icons">add</i> <%= localeMessage.getString("button.add") %>
</button>
</div>
</div>
<table id="serviceGrid"></table>
</div>
<div style="margin-top:15px;">
<div class="table_row_title">메인 키워드 목록</div>
<table class="table_row" cellspacing="0">
<tr>
<th style="width:180px;">키워드</th>
<td>
<input type="text" id="keywordList" style="width:100%" placeholder="쉼표(,)로 구분하여 입력">
<div class="help-text" style="color:#666; font-size:12px; margin-top:5px;">
예시: #인증, #대출, #예금
</div>
</td>
</tr>
</table>
</div>
</div>
</div>
</body>
</html>
@@ -0,0 +1,155 @@
<%-- portalMainManPopup.jsp --%>
<%@ page language="java" contentType="text/html; charset=utf-8" %>
<%@ page import="java.io.*" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ include file="/jsp/common/include/localemessage.jsp" %>
<%
response.setHeader("Pragma", "No-cache");
response.setHeader("Cache-Control", "no-cache");
response.setHeader("Expires", "0");
%>
<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<jsp:include page="/jsp/common/include/css.jsp"/>
<jsp:include page="/jsp/common/include/script.jsp"/>
<script language="javascript">
var url = '<c:url value="/onl/apim/apigroup/apiGroupMan.json"/>';
function search() {
var postData = getSearchForJqgrid("cmd", "LIST");
$("#grid").setGridParam({postData: postData, page: "1"}).trigger("reloadGrid");
}
function list() {
var gridPostData = getSearchForJqgrid("cmd","LIST"); //jqgrid에서는 object 로
$('#grid').jqGrid({
mtype: 'POST',
datatype: "json",
url: url,
postData: gridPostData,
colNames: ['서비스 ID', '서비스명', '서비스 설명', '공개여부'],
colModel: [
{name: 'id', align: 'center', width: '100'},
{name: 'groupName', align: 'left', width: '150'},
{name: 'groupDesc', align: 'left'},
{
name: 'displayYn', align: 'center', width: '60', formatter: function(cellvalue) {
return cellvalue === '1' ? 'Y' : 'N';
}
}
],
jsonReader: {
repeatitems: false
},
pager: '#pager',
rowNum: '${rmsDefaultRowNum}',
autoheight: true,
height: $("#container").height(),
autowidth: true,
viewrecords: true,
rowList: eval('[${rmsDefaultRowList}]'),
multiselect: true,
loadComplete: function() {
try {
// URL에서 selectedIds 파라미터 가져오기
var urlParams = new URLSearchParams(window.location.search);
var selectedIds = urlParams.get('selectedIds');
if(selectedIds) {
selectedIds = selectedIds.split(',');
var ids = $(this).jqGrid('getDataIDs');
ids.forEach(function(id) {
var rowData = $(this).jqGrid('getRowData', id);
if(selectedIds.includes(rowData.id)) {
$(this).jqGrid('setSelection', id, true);
}
}.bind(this));
}
} catch(e) {
console.error("Failed to sync with parent window:", e);
}
},
ondblClickRow: function(rowId) {
var rowData = $(this).jqGrid('getRowData', rowId);
if (window.dialogArguments && window.dialogArguments.callback) {
window.dialogArguments.callback([rowData]);
}
window.close();
}
});
}
$(document).ready(function() {
$("#btn_search").click(function() {
search();
});
$("#btn_save").click(function() {
var selectedRows = $("#grid").jqGrid('getGridParam', 'selarrrow');
if(selectedRows.length === 0) {
alert("선택된 서비스가 없습니다.");
return;
}
// 선택된 모든 행의 데이터를 배열로 수집
var selectedData = selectedRows.map(function(rowId) {
return $("#grid").jqGrid('getRowData', rowId);
});
if(window.dialogArguments && window.dialogArguments.callback) {
window.dialogArguments.callback(selectedData);
}
window.close();
});
$("input[name^=search]").keydown(function(key) {
if (key.keyCode == 13) {
$("#btn_search").click();
}
});
list();
resizeJqGridWidth('grid', 'content_middle', '1000');
});
</script>
</head>
<body>
<div>
<div class="content_middle" id="content_middle" style="margin-top: 0px">
<div class="search_wrap">
<button type="button" class="cssbtn" id="btn_search" level="R">
<i class="material-icons">search</i> <%= localeMessage.getString("button.search") %>
</button>
<button type="button" class="cssbtn" id="btn_save" level="R">
<i class="material-icons">check</i> <%= localeMessage.getString("button.check") %>
</button>
</div>
<div class="title">API 그룹 선택</div>
<table class="search_condition" cellspacing="0">
<tbody>
<tr>
<th style="width:180px;">서비스명</th>
<td>
<input type="text" name="searchGroupName">
</td>
<th style="width:180px;">서비스 설명</th>
<td>
<input type="text" name="searchGroupDesc">
</td>
</tr>
</tbody>
</table>
<table id="grid"></table>
<div id="pager"></div>
</div>
</div>
</body>
</html>
@@ -0,0 +1,167 @@
<%@ page language="java" contentType="text/html; charset=utf-8"%>
<%@ page import="java.io.*"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib uri="http://www.springframework.org/tags" prefix="spring"%>
<%@ include file="/jsp/common/include/localemessage.jsp" %>
<%
response.setHeader("Pragma", "No-cache");
response.setHeader("Cache-Control", "no-cache");
response.setHeader("Expires", "0");
%>
<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<jsp:include page="/jsp/common/include/css.jsp"/>
<jsp:include page="/jsp/common/include/script.jsp"/>
<script language="javascript" >
var url = '<c:url value="/onl/apim/portalnotice/portalNoticeMan.json" />';
var url_view = '<c:url value="/onl/apim/portalnotice/portalNoticeMan.view" />';
function formatuseYn(cellvalue, options, rowObject) {
return cellvalue === 'N'
? '<span style="color: red;">미사용</span>'
: '<span>사용</span>';
}
function formatFile(cellvalue, options, rowObject) {
var iconPath = '${pageContext.request.contextPath}/images/icon_file.png';
var icon = rowObject.hasAttachment ? '<img src="' + iconPath + '" alt="File Attached" style="vertical-align: middle; margin-left: 5px; width: 16px; height: 16px;">' : '';
return cellvalue + icon;
}
$(document).ready(function() {
$('#grid').jqGrid({
datatype:"json",
mtype: 'POST',
url: url,
postData : { cmd : 'LIST',
searchUseYn: $('select[name=searchUseYn]').val(),
searchNoticeSubject: $('input[name=searchNoticeSubject]').val(),
searchNoticeDetail: $('input[name=searchNoticeDetail]').val()
},
colNames:['id', 'No.', '제목', '사용', '마지막 수정일', '등록일', '등록자', '조회수'],
colModel:[
{ name : 'id' , align:'center', key:true, hidden:true},
{ name : 'rowNum' , align:'center', width:80 },
{ name : 'noticeSubject' , align:'left' , width:200 , formatter: formatFile },
{ name : 'useYn' , align:'center', width:60, formatter: formatuseYn },
{ name : 'lastModifiedDate', align:'center', width:120 , formatter: timeStampFormat},
{ name : 'createdDate' , align:'center', width:120, formatter: timeStampFormat },
{ name : 'inquirerName' , align:'center', width:100 },
{ name : 'readCount' , align:'center', width:80 }
],
jsonReader: {
repeatitems:false
},
pager : $('#pager'),
page : '${param.page}',
rowNum : '${rmsDefaultRowNum}',
autoheight: true,
height: $("#container").height(),
autowidth: true,
viewrecords: true,
rowList : eval('[${rmsDefaultRowList}]'),
ondblClickRow: function(rowId) {
var rowData = $(this).getRowData(rowId);
var id = rowData['id'];
var url2 = url_view;
url2 += '?cmd=DETAIL';
url2 += '&page='+$(this).getGridParam("page");
url2 += '&returnUrl='+getReturnUrl();
url2 += '&menuId='+'${param.menuId}';
url2 += '&id='+id;
goNav(url2);
},
gridComplete:function (d){
var records = $(this).getGridParam('records');
var page = $(this).getGridParam('page');
var rowNum = $(this).getGridParam('rowNum');
var rows = $(this).getDataIDs();
for (var i = 0; i < rows.length; i++) {
var number = ((page - 1) * rowNum + i) + 1;
// var reverseNumber = records - ((page - 1) * rowNum + i);
$(this).setCell(rows[i], 'rowNum', number);
}
var colModel = $(this).getGridParam("colModel");
var ids = jQuery("#grid").jqGrid('getDataIDs');
for(var i = 0 ; i< colModel.length; i++){
$(this).setColProp(colModel[i].name, {sortable : false});
}
},
loadError: function (jqXHR, textStatus, errorThrown) {
var location ='<%=request.getContextPath()%>/';
comloadError(jqXHR, textStatus, errorThrown ,location);
}
});
resizeJqGridWidth('grid','content_middle','1000');
$("#btn_search").click(function(){
var postData = getSearchForJqgrid("cmd","LIST");
$("#grid").setGridParam({ url:url,postData: postData ,page:1 }).trigger("reloadGrid");
});
$("#btn_new").click(function(){
var url2 = url_view;
url2 += '?cmd=DETAIL';
url2 += '&page='+$("#grid").getGridParam("page");
url2 += '&returnUrl='+getReturnUrl();
url2 += '&menuId='+'${param.menuId}';
goNav(url2);
});
$("select[name=searchUseYn], input[name^=search]").keydown(function(key){
if (key.keyCode == 13){
$("#btn_search").click();
}
});
buttonControl();
});
</script>
</head>
<body>
<div class="right_box">
<div class="content_top">
<ul class="path">
<li><a href="#">${rmsMenuPath}</a></li>
</ul>
</div><!-- end content_top -->
<div class="content_middle" id="content_middle">
<div class="search_wrap">
<button type="button" class="cssbtn" id="btn_new" level="W"><i class="material-icons">add</i> <%= localeMessage.getString("button.new") %></button>
<button type="button" class="cssbtn" id="btn_search" level="R"><i class="material-icons">search</i> <%= localeMessage.getString("button.search") %></button>
</div>
<div class="title">공지사항 목록<span class="tooltip">공지사항을 관리합니다.</span></div>
<form id="ajaxForm" onsubmit="return false;">
<table class="search_condition" cellspacing=0;>
<tbody>
<tr>
<th style="width:180px;">사용여부</th>
<td>
<div class="select-style">
<select name="searchUseYn">
<option value="">전체</option>
<option value="Y">사용</option>
<option value="N">미사용</option>
</select>
</div>
</td>
<th style="width:180px;">제목/내용</th>
<td><input type="text" name="searchSubjectDetail"></td>
</tr>
</tbody>
</table>
</form>
<table id="grid" ></table>
<div id="pager"></div>
</div><!-- end content_middle -->
</div><!-- end right_box -->
</body>
</html>
@@ -0,0 +1,293 @@
<%@ page language="java" contentType="text/html; charset=utf-8"%>
<%@ page import="java.io.*"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib uri="http://www.springframework.org/tags" prefix="spring"%>
<%@ include file="/jsp/common/include/localemessage.jsp" %>
<%
response.setHeader("Pragma", "No-cache");
response.setHeader("Cache-Control", "no-cache");
response.setHeader("Expires", "0");
%>
<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<jsp:include page="/jsp/common/include/css.jsp"/>
<jsp:include page="/jsp/common/include/script.jsp"/>
<script language="javascript" >
var url = '<c:url value="/onl/apim/portalnotice/portalNoticeMan.json" />';
var url_view = '<c:url value="/onl/apim/portalnotice/portalNoticeMan.view" />';
var file_download = '<c:url value="/file/download.do" />';
var isDetail = false;
var fileInfo = null;
function init() {
// 초기화 로직
}
function decodeHTMLEntities(text) {
var textArea = document.createElement('textarea');
textArea.innerHTML = text;
return textArea.value;
}
function formatFileSize(bytes) {
if(bytes == 0) return '0 Bytes';
var k = 1024,
sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB'],
i = Math.floor(Math.log(bytes) / Math.log(k));
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
}
function displayAttachFile(file) {
var $attachFiles = $('#attachFiles');
$attachFiles.empty();
if (file) {
var iconPath = '${pageContext.request.contextPath}/images/icon_file.png';
var fileItem = $('<div>').addClass('file-item');
$('<img>').attr('src', iconPath).css({'marginLeft': '15px','marginRight': '5px' ,'height': '1.2em'}).appendTo(fileItem);
var fileNameSpan = $('<span>')
.addClass('fileName')
.text(file.originalFileName + '.' + file.fileExtension + ' (' + formatFileSize(file.size) + ')')
.css('cursor', 'pointer')
.on('click', function() {
if (file.fileId) {
downloadFile(file.fileId);
}
});
fileNameSpan.appendTo(fileItem);
$('<button>').text('X').addClass('delete-file').css('marginLeft', '15px')
.on('click', function() {
fileInfo = null;
displayAttachFile(null);
// 폼에 삭제 플래그 추가
$('<input>').attr({
type: 'hidden',
name: 'fileDeleted',
value: 'true'
}).appendTo('#ajaxForm');
})
.appendTo(fileItem);
fileItem.appendTo($attachFiles);
}
}
function downloadFile(fileId) {
if (fileId) {
var fileSn = 1; // 단일 파일이므로 시리얼 넘버를 1로 고정
window.location.href = file_download + '?fileId=' + fileId + '&fileSn=' + fileSn;
} else {
console.log("File not yet uploaded or doesn't have an ID");
}
}
function detail(key) {
if (!isDetail) return;
$.ajax({
type: "POST",
url: url,
dataType: "json",
data: {cmd: 'DETAIL', id: key},
success: function (data) {
$("#id").val(key);
$("#noticeSubject").val(data.noticeSubject);
$("#useYn").prop("checked", data.useYn === "Y");
var decodedContent = decodeHTMLEntities(data.noticeDetail);
$('#contents').summernote('code', decodedContent);
// 파일 정보 표시
if (data.fileInfo) {
fileInfo = {
originalFileName: data.fileInfo.fileDetails[0].originalFileName,
fileExtension: data.fileInfo.fileDetails[0].fileExtension,
fileId: data.fileInfo.fileDetails[0].fileId,
size: data.fileInfo.fileDetails[0].fileSize
};
displayAttachFile(fileInfo);
}
},
error: function (e) {
alert(e.responseText);
}
});
}
$(document).ready(function () {
var returnUrl = getReturnUrlForReturn();
var key = "${param.id}";
isDetail = key != "" && key != "null";
if (isDetail) {
$("#title").append(" 수정");
buttonControl(true);
} else {
$("#title").append(" 등록");
$("#btn_modify").html('<i class="material-icons">save</i> <%= localeMessage.getString("button.register") %>');
buttonControl(false);
}
init();
$('#contents').summernote({
placeholder: '여기에 내용을 입력하세요.',
height: 300,
toolbar: [
['style', ['style']],
['font', ['bold', 'underline', 'clear']],
['color', ['color']],
['para', ['ul', 'ol', 'paragraph']],
['table', ['table']],
['insert', ['link']],
['view', ['codeview', 'help']]
],
callbacks: {
onInit: function() {
$('.note-editable').on('keydown', function(e) {
if (e.keyCode === 8) {
e.stopPropagation();
}
});
}
}
});
if (key) {
detail(key);
}
$('#fileInput').change(function(e) {
var file = e.target.files[0];
if (file) {
fileInfo = {
originalFileName: file.name.split('.').slice(0, -1).join('.'),
fileExtension: file.name.split('.').pop(),
file: file,
size: file.size
};
displayAttachFile(fileInfo);
}
this.value = ''; // 입력 필드 초기화
});
$('#addFile').click(function() {
$('#fileInput').click();
});
$("#btn_modify").click(function () {
if (!checkRequired("ajaxForm")) return;
if (confirm("<%= localeMessage.getString("common.checkSave")%>") != true)
return;
var formData = new FormData($("#ajaxForm")[0]);
formData.set("useYn", $("#useYn").is(":checked") ? "Y" : "N");
formData.set("noticeDetail", $('#contents').summernote('code'));
formData.append("cmd", isDetail ? "UPDATE" : "INSERT");
// 파일 처리
if (fileInfo && fileInfo.file) {
formData.set("files", fileInfo.file);
formData.set("fileName", fileInfo.originalFileName + '.' + fileInfo.fileExtension);
}
$.ajax({
type: "POST",
url: url,
data: formData,
processData: false,
contentType: false,
success: function (json) {
alert("<%= localeMessage.getString("common.saveMsg") %>");
goNav(returnUrl);
},
error: function (e) {
alert(e.responseText);
}
});
});
$("#btn_delete").click(function () {
if (confirm("<%= localeMessage.getString("common.confirmMsg")%>")) {
var postData = $('#ajaxForm').serializeArray();
postData.push({name: "cmd", value: "DELETE"});
$.ajax({
type: "POST",
url: url,
data: postData,
success: function (args) {
alert("<%= localeMessage.getString("common.deleteMsg") %>");
goNav(returnUrl);
},
error: function (e) {
alert(e.responseText);
}
});
}
});
$("#btn_previous").click(function () {
goNav(returnUrl);
});
});
</script>
</head>
<body>
<div class="right_box">
<div class="content_top">
<ul class="path">
<li><a href="#">${rmsMenuPath}</a></li>
</ul>
</div><!-- end content_top -->
<div class="content_middle">
<div class="search_wrap">
<button type="button" class="cssbtn" id="btn_modify" level="W" status="DETAIL,NEW"><i class="material-icons">save</i> <%= localeMessage.getString("button.modify") %></button>
<button type="button" class="cssbtn" id="btn_delete" level="W" status="DETAIL"><i class="material-icons">delete</i> <%= localeMessage.getString("button.delete") %></button>
<button type="button" class="cssbtn" id="btn_previous" level="R" status="DETAIL,NEW"><i class="material-icons">arrow_back</i> <%= localeMessage.getString("button.previous") %></button>
</div>
<div class="title" id="title">공지사항</div>
<form id="ajaxForm" enctype="multipart/form-data" accept-charset="UTF-8">
<input type="hidden" name="id" id="id">
<table class="table_row" cellspacing="0">
<tr>
<th style="width:20%;">사용여부</th>
<td>
<input type="checkbox" name="useYn" id="useYn" value="Y" ${portalNoticeUI.useYn eq 'Y' ? 'checked' : ''}> 사용</td>
</tr>
<tr>
<th style="width:20%;">제목 <font color="red">*</font></th>
<td><input type="text" id="noticeSubject" name="noticeSubject" style="width:100%" data-required data-warning="제목을 입력하여 주십시오."/></td>
</tr>
<tr>
<th style="width:20%;">본문 <font color="red">*</font></th>
<td>
<textarea id="contents" name="noticeDetail" style="width:100%;height:300px" data-required data-warning="본문을 입력하여 주십시오."></textarea>
</td>
</tr>
<tr>
<th style="width:20%;">첨부파일</th>
<td>
<div style="margin: 5px 0px; display: inline-block;">
<input type="file" id="fileInput" name="files" style="display:none;" />
<button type="button" id="addFile" class="cssbtn smallBtn">파일 선택</button>
</div>
<div id="attachFiles" style="margin: 5px 0px; display: inline-block;"></div>
</td>
</tr>
</table>
</form>
</div>
</div>
</body>
</html>
@@ -0,0 +1,238 @@
<%@ page language="java" contentType="text/html; charset=utf-8"%>
<%@ page import="java.io.*"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib uri="http://www.springframework.org/tags" prefix="spring"%>
<%@ include file="/jsp/common/include/localemessage.jsp" %>
<%
response.setHeader("Pragma", "No-cache");
response.setHeader("Cache-Control", "no-cache");
response.setHeader("Expires", "0");
%>
<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<jsp:include page="/jsp/common/include/css.jsp"/>
<jsp:include page="/jsp/common/include/script.jsp"/>
<script language="javascript" >
var url = '<c:url value="/onl/apim/portalorg/portalOrgMan.json" />';
var url_view = '<c:url value="/onl/apim/portalorg/portalOrgMan.view" />';
var select_approvalStatus = "";
var select_status = "";
/* var select_orgType = ""; */
function getGridSelectText(key, value, data) {
if (!Array.isArray(data) || data.length === 0) {
return "";
}
return data
.filter(item => item[key] !== undefined && item[value] !== undefined)
.map(item => String(item[key]) + ":" + String(item[value]))
.join(';');
}
function formatCompanyRegNo(text) {
return text.replace(/(\d{3})(\d{2})(\d{5})/, "$1-$2-$3");
}
function init(){
$.ajax({
type : "POST",
url:url,
dataType:"json",
data:{cmd: 'LIST_INIT_COMBO'},
success:function(json){
const comboConfigs = [
{name: 'searchOrgStatus', data: json.orgStatusRows },
{name: 'searchApprovalStatus', data: json.approvalStatusRows },
];
comboConfigs.forEach(function(config) {
new makeOptions("CODE","NAME")
.setObj($("select[name=" + config.name + "]"))
.setNoValueInclude(true)
.setNoValue("", "<%=localeMessage.getString("combo.all")%>")
.setData(config.data)
.setFormat(nameOptionFormat).rendering();
});
putSelectFromParam();
select_approvalStatus = ": ;" + getGridSelectText("CODE", "NAME", json.approvalStatusRows);
select_status = ": ;" + getGridSelectText("CODE", "NAME", json.orgStatusRows);
initializeGrid();
},
error:function(e){
alert(e.responseText);
}
});
}
function initializeGrid() {
var gridPostData = getSearchForJqgrid("cmd","LIST"); //jqgrid에서는 object 로
$('#grid').jqGrid({
datatype:"json",
mtype: 'POST',
url: url,
postData : gridPostData,
colNames:['No.',
"id",
'<%= localeMessage.getString("portalOrg.orgName") %>',
'<%= localeMessage.getString("portalOrg.orgCode") %>',
'<%= localeMessage.getString("portalOrg.compRegNo") %>',
'<%= localeMessage.getString("portalUser.createOn") %>',
'<%= localeMessage.getString("portalOrg.orgStatus") %>',
'<%= localeMessage.getString("portalUser.approvalStatus") %>'
],
colModel:[
{ name : 'rowNum' , align:'center' , width:'30', sortable:false },
{ name : 'id' , align:'center' , key:true, hidden:true},
{ name : 'orgName' , align:'center' , width:"80"},
{ name : 'orgCode' , align:'center' , width:"80"},
{ name : 'compRegNo' , align:'center' , formatter:formatCompanyRegNo },
{ name : 'createdDate' , align:'center' , width:"90", formatter: timeStampFormat },
{ name : 'orgStatus' , align:'center' , width:'60',editoptions: { value: select_status }, formatter: "select"},
{ name : 'approvalStatus' , align:'center' , width:"60", edittype: 'select' , editoptions: { value: select_approvalStatus }, formatter: "select"}
],
jsonReader: {
repeatitems:false
},
pager : $('#pager'),
page : '${param.page}',
rowNum : '${rmsDefaultRowNum}',
autoheight: true,
height: $("#container").height(),
autowidth: true,
viewrecords: true,
rowList : eval('[${rmsDefaultRowList}]'),
loadComplete:function (d){
var records = $(this).getGridParam('records');
var page = $(this).getGridParam('page');
var rowNum = $(this).getGridParam('rowNum');
var rows = $(this).getDataIDs();
var colModel = $(this).getGridParam("colModel");
for (var i = 0; i < rows.length; i++) {
var number = ((page - 1) * rowNum + i) + 1;
// var reverseNumber = records - ((page - 1) * rowNum + i);
$(this).setCell(rows[i], 'rowNum', number);
}
for(var i = 0 ; i< colModel.length; i++){
$(this).setColProp(colModel[i].name, {sortable : false});
}
},
ondblClickRow: function(rowId) {
var rowData = $(this).getRowData(rowId);
var key = rowData['id'];
var args = {};
var url2 = url_view;
url2 += '?cmd=DETAIL';
url2 += '&page='+$(this).getGridParam("page");
url2 += '&returnUrl='+getReturnUrl();
url2 += '&menuId='+'${param.menuId}';
url2 += '&id=' + key;
goNav(url2);
},loadError: function (jqXHR, textStatus, errorThrown) {
if(jqXHR.status == 401) {
var location ='<%=request.getContextPath()%>/';
comloadError(jqXHR, textStatus, errorThrown ,location);
}
}
});
resizeJqGridWidth('grid','content_middle','1000');
}
$(document).ready(function() {
$("input[name=searchStartYYYYMMDD],input[name=searchEndYYYYMMDD]").inputmask("yyyy-mm-dd",{'autoUnmask':true});
init();
$("#btn_search").click(function(){
var postData = getSearchForJqgrid("cmd","LIST");
$("#grid").setGridParam({ url:url, postData: postData, page:1 }).trigger("reloadGrid");
});
$("#btn_new").click(function(){
var url2 = url_view;
url2 += '?cmd=DETAIL';
url2 += '&page='+$("#grid").getGridParam("page");
url2 += '&returnUrl='+getReturnUrl();
url2 += '&menuId='+'${param.menuId}';
goNav(url2);
});
$("input[name^=search]").keydown(function(key){
if (key.keyCode == 13){
$("#btn_search").click();
}
});
$("#startDatepicker").datepicker();
$("#endDatepicker").datepicker();
buttonControl();
});
</script>
</head>
<body>
<div class="right_box">
<div class="content_top">
<ul class="path">
<li><a href="#">${rmsMenuPath}</a></li>
</ul>
</div><!-- end content_top -->
<div class="content_middle" id="content_middle">
<div class="search_wrap">
<button type="button" class="cssbtn" id="btn_new" level="W"><i class="material-icons">add</i> <%= localeMessage.getString("button.new") %></button>
<button type="button" class="cssbtn" id="btn_search" level="R"><i class="material-icons">search</i> <%= localeMessage.getString("button.search") %></button>
</div>
<%--법인정보관리--%>
<div class="title"><%= localeMessage.getString("portalOrg.title") %></div>
<table class="search_condition" cellspacing=0;>
<tbody>
<tr>
<th style="width:10%;"><%= localeMessage.getString("portalOrg.orgName") %></th>
<td style="width:15%;">
<input type="text" name="searchOrgName" value="${param.searchOrgName}">
</td>
<th style="width:10%;"><%= localeMessage.getString("portalOrg.compRegNo") %></th>
<td style="width:15%;">
<input type="text" name="searchOrgCompRegNo" value="${param.searchOrgCompRegNo}">
</td>
<th style="width:10%;"><%= localeMessage.getString("portalOrg.orgStatus") %></th>
<td style="width:15%;">
<div class="select-style">
<select type="text" name="searchOrgStatus" value="${param.searchOrgStatus}"></select>
</div>
</td>
<th style="width:10%;"><%= localeMessage.getString("portalUser.approvalStatus") %></th>
<td style="width:15%;">
<div class="select-style">
<select type="text" name="searchApprovalStatus" value="${param.searchApprovalStatus}"></select>
</div>
</td>
</tr>
</tbody>
</table>
<table id="grid" ></table>
<div id="pager"></div>
</div><!-- end content_middle -->
</div><!-- end right_box -->
</body>
</html>
@@ -0,0 +1,826 @@
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ page import="java.io.*"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib uri="http://www.springframework.org/tags" prefix="spring"%>
<%@ include file="/jsp/common/include/localemessage.jsp" %>
<%
response.setHeader("Pragma", "No-cache");
response.setHeader("Cache-Control", "no-cache");
response.setHeader("Expires", "0");
%>
<%!
public String getRequiredLabel(String label) {
return label + " <span class=\"required-mark\">*</span>";
}
%>
<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<jsp:include page="/jsp/common/include/css.jsp"/>
<jsp:include page="/jsp/common/include/script.jsp"/>
<jsp:include page="/jsp/common/include/portal.jsp"/>
<script language="javascript" >
var url = '<c:url value="/onl/apim/portalorg/portalOrgMan.json" />';
var url_view = '<c:url value="/onl/apim/portalorg/portalOrgMan.view" />';
var file_download = '<c:url value="/file/download.do" />';
let originalOrgStatus = '';
function addIpToTable(ipValue, rowNum) {
var newRow = $('<tr>')
.append($('<td>').text(rowNum))
.append($('<td>').text(ipValue))
.append($('<td>').html(
'<button type="button" class="cssbtn smallBtn" onclick="deleteIp(this)">' +
'<i class="material-icons">delete</i>삭제' +
'</button>'
));
$("#ipListBody").append(newRow);
}
window.deleteIp = function(btn) {
$(btn).closest('tr').remove();
// 번호 재정렬
$("#ipListBody tr").each(function(index) {
$(this).find("td:first").text(index + 1);
});
updateIpWhitelist();
};
function updateIpWhitelist() {
var ips = $("#ipListBody tr").map(function() {
return $(this).find("td:eq(1)").text().trim();
}).get();
$("#ipWhitelist").val(ips.join(','));
}
function init(){
$.ajax({
type : "POST",
url:url,
dataType:"json",
data:{cmd: 'LIST_INIT_COMBO'},
success:function(json){
populateSelectOptions("orgStatus", json.orgStatusRows);
populateSelectOptions("approvalStatus", json.approvalStatusRows);
var key = "${param.id}";
if (key != "" && key != "null") {
detail(key);
}
if(typeof callback === 'function') {
callback();
}
if(!isDetail) {
$("select[name=orgStatus]").val("READY").prop("disabled", true);
$("select[name=approvalStatus]").val("PENDING").prop("disabled", true);
}
},
error:function(e){
alert(e.responseText);
}
});
}
// 선택박스 옵션 세팅 함수
function populateSelectOptions(elementName, data) {
new makeOptions("CODE", "NAME")
.setObj($("select[name=" + elementName + "]"))
.setData(data)
.setFormat(nameOptionFormat)
.rendering();
}
function detail(key){
if (!isDetail) return;
$.ajax({
type : "POST",
url:url,
dataType:"json",
data:{cmd: 'DETAIL', id : key},
success:function(json) {
var portalOrgData = json.portalOrg;
var corporateManagerData = json.corporateManager;
$("#ajaxForm input[type!=radio],#ajaxForm select,#ajaxForm textarea").each(function () {
var name = $(this).attr("name");
var tag = $(this).prop("tagName").toLowerCase();
$(tag + "[name=" + name + "]").val(portalOrgData[name]);
});
$("#orgName").val(portalOrgData.orgName);
$("#orgCode").val(portalOrgData.orgCode);
$("#orgStatus").val(portalOrgData.orgStatus);
originalOrgStatus = portalOrgData.orgStatus;
if(originalOrgStatus === 'REMOVED') {
$("#btn_delete").hide();
}
$("#approvalStatus").val(portalOrgData.approvalStatus);
$("#compRegNo").val(formatCompanyRegNo(portalOrgData.compRegNo));
$("#corpRegNo").val(formatCorpRegNo(portalOrgData.corpRegNo));
$("#createdDate").inputmask("9999-99-99 99:99:99", {'autoUnmask': true});
// 전화번호 처리
if (portalOrgData.scPhoneNumber) {
var scPhoneParts = portalOrgData.scPhoneNumber.split('-');
if (scPhoneParts.length === 3) {
$("#scPhonePrefix").val(scPhoneParts[0]);
$("#scPhoneMiddle").val(scPhoneParts[1]);
$("#scPhoneLast").val(scPhoneParts[2]);
}
}
if (portalOrgData.orgPhoneNumber) {
var orgPhoneParts = portalOrgData.orgPhoneNumber.split('-');
if (orgPhoneParts.length === 3) {
$("#orgPhonePrefix").val(orgPhoneParts[0]);
$("#orgPhoneMiddle").val(orgPhoneParts[1]);
$("#orgPhoneLast").val(orgPhoneParts[2]);
}
}
if (corporateManagerData) {
$("#userName").text(corporateManagerData.userName);
$("#userStatusDescription").text(corporateManagerData.userStatusDescription);
$("#emailAddr").text(corporateManagerData.emailAddr);
$("#mobileNumber").text(corporateManagerData.mobileNumber);
// 법인 관리자 정보가 있을 때 관련 UI 요소 표시
$("#managerInfoSection").show();
} else {
// 법인 관리자 정보가 없을 때 관련 UI 요소 숨김 또는 메시지 표시
$("#managerInfoSection").hide();
$("#noManagerMessage").show();
}
if (portalOrgData.ipWhitelist) {
var ipList = portalOrgData.ipWhitelist.split(',');
ipList.forEach(function(ip, index) {
var trimmedIp = ip.trim();
if (trimmedIp) {
addIpToTable(trimmedIp, index + 1);
}
});
}
// 파일 정보 표시
if (portalOrgData.compRegFile) {
$("#fileName").text(portalOrgData.fileName);
if (portalOrgData.fileName) {
$("#fileWrapper").show().off('click').on('click', function() {
downloadFile(portalOrgData.compRegFile, '1'); // fileSn은 단일 파일이므로 '1'로 고정
});
$("#compRegFile").val(portalOrgData.compRegFile);
} else {
$("#fileWrapper").hide();
}
} else {
$("#fileName").text("");
$("#fileWrapper").hide();
}
},
error:function(e){
alert(e.responseText);
}
});
}
function downloadFile(fileId, fileSn) {
window.location.href = file_download + '?fileId=' + fileId + '&fileSn=' + fileSn;
}
$(document).ready(function() {
var returnUrl = getReturnUrlForReturn();
var key ="${param.id}";
isDetail = key !== "" && key !== "null";
if (isDetail){
$("#title").append(" 수정")
$("#btn_modify").prop('disabled', true);
$("#btn_unmask").show();
buttonControl(true);
} else {
$("#title").append(" 등록")
$("#managerInfoSectionTitle").hide();
$("#btn_modify").html('<i class="material-icons">save</i> <%= localeMessage.getString("button.register") %></button>');
$("#btn_unmask").hide();
buttonControl(false);
}
init();
/* 사업자 등록번호 마스킹 */
$("input[name=compRegNo]").inputmask("999-99-99999");
$("input[name=corpRegNo]").inputmask("999999-9999999");
// 전화번호 입력 필드 이벤트 처리
$("#scPhoneMiddle, #scPhoneLast, #orgPhoneMiddle, #orgPhoneLast").on({
'input': function() {
this.value = this.value.replace(/[^0-9]/g, ''); // 숫자 외 문자 제거
// 자동 포커스 이동
if (this.value.length === this.maxLength) {
var nextId = this.id.includes('Middle') ?
this.id.replace('Middle', 'Last') : null;
if (nextId) {
$('#' + nextId).focus();
}
}
},
'paste': function(e) {
// 붙여넣기 시 숫자만 허용
e.preventDefault();
var pastedData = (e.originalEvent.clipboardData || window.clipboardData).getData('text');
this.value = pastedData.replace(/[^0-9]/g, '').slice(0, 4);
}
});
// 파일 선택 버튼 클릭 이벤트
$("#uploadButton").click(function() {
$("#compRegFileUpload").click();
});
$("#compRegFileUpload").change(function() {
var fileInput = this;
var $hiddenFile = $("#compRegFile");
if (fileInput.files.length > 0) {
var file = fileInput.files[0];
// 파일 크기 체크 (10MB)
if (file.size > 10 * 1024 * 1024) {
alert("파일 크기는 10MB 이내로 등록해 주세요.");
fileInput.value = "";
return;
}
// 파일 확장자 체크
var allowedExtensions = ['.pdf','.doc','.docx','.xls','.xlsx','.ppt','.pptx','.hwp','.gif','.jpg','.jpeg','.png'];
var fileExt = file.name.toLowerCase().substring(file.name.lastIndexOf('.'));
if (!allowedExtensions.includes(fileExt)) {
alert("허용된 파일 형식이 아닙니다.\n문서파일(pdf, doc, docx, xls, xlsx, ppt, pptx, hwp)과 이미지 파일(gif, jpg, png)만 등록 가능합니다.");
fileInput.value = "";
return;
}
// 파일이 정상적인 경우
$("#fileName").text(file.name);
$("#fileWrapper").show();
} else {
// 파일 선택이 취소되고 기존 파일도 없는 경우
if (!isDetail || !$hiddenFile.val()) {
$("#fileName").text("");
$("#fileWrapper").hide();
$hiddenFile.val("");
}
// isDetail이고 기존 파일이 있는 경우는 기존 상태 유지
}
});
$("#orgStatus").change(function() {
const newStatus = $(this).val();
if (newStatus === 'REMOVED' && originalOrgStatus !== 'REMOVED') {
if (!confirm("해당 법인을 탈퇴 처리하시겠습니까?")) {
$(this).val(originalOrgStatus);
return;
}
}
});
$("#ipInput").on('input', function(e) {
// 숫자와 점만 허용하고 나머지는 즉시 제거
this.value = this.value.replace(/[^0-9.]/g, '');
let value = this.value;
// 연속된 점을 하나로
value = value.replace(/\.{2,}/g, '.');
// 최대 3개의 점만 허용
let dots = value.match(/\./g) || [];
if (dots.length > 3) {
value = value.substring(0, value.lastIndexOf('.'));
}
// 각 파트의 유효성 검사
let parts = value.split('.');
parts = parts.map((part, index) => {
if (part === '') return part;
// leading zeros 제거 후 숫자 변환
let num = parseInt(part, 10);
// 0-255 범위 체크
if (isNaN(num) || num < 0 || num > 255) {
return '';
}
// 숫자를 문자열로 변환
let result = num.toString();
// 마지막 파트가 아니고 값이 있으면 점 추가
if (index < parts.length - 1 && result) {
result += '.';
}
return result;
});
// 결과 설정
this.value = parts.join('');
});
// IP 추가 버튼 클릭
$("#btn_add_ip").click(function() {
addIp();
});
// IP 입력 필드에서 엔터키 처리
$("#ipInput").keypress(function(e) {
if(e.keyCode == 13) {
e.preventDefault();
addIp();
}
});
// IP 추가 함수
function addIp() {
var ipValue = $("#ipInput").val().trim();
//var ipRegex = /^(\d{1,3}\.){3}\d{1,3}$/;
var ipRegex = /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/;
if (!ipRegex.test(ipValue)) {
alert("올바른 IP 주소 형식이 아닙니다.");
return;
}
// IP 범위 검사 (0-255)
var parts = ipValue.split('.');
if (!parts.every(part => {
var num = parseInt(part);
return num >= 0 && num <= 255;
})) {
alert("IP 주소의 각 부분은 0-255 사이의 값이어야 합니다.");
return;
}
// 중복 체크
var existingIps = $("#ipListBody tr").map(function() {
return $(this).find("td:eq(1)").text();
}).get();
if (existingIps.includes(ipValue)) {
alert("이미 추가된 IP 주소입니다.");
return;
}
// 새로운 행 추가
var rowNum = $("#ipListBody tr").length + 1;
addIpToTable(ipValue, rowNum);
$("#ipInput").val('');
updateIpWhitelist();
}
$("#downloadButton").click(function() {
var fileId = $("#compRegFile").val();
downloadFile(fileId, '1'); // fileSn은 '1'로 가정
});
$("#btn_unmask").click(function () {
if (!isDetail) {
alert("등록된 정보만 마스킹 해제할 수 있습니다.");
return;
}
var reason = prompt("마스킹 해제 사유를 입력해 주세요");
if (reason != null && reason.trim() !== '') {
$.ajax({
type: "POST",
url: url,
dataType: "json",
data: {
cmd: "UNMASK",
id: key,
reason: reason // reason 파라미터 추가
},
success: function (json) {
var portalOrgData = json.portalOrg;
var corporateManagerData = json.corporateManager;
// 마스킹 해제된 데이터를 화면에 반영
$("#orgName").val(portalOrgData.orgName);
$("#orgCode").val(portalOrgData.orgCode);
$("#compRegNo").val(portalOrgData.compRegNo);
$("#corpRegNo").val(portalOrgData.corpRegNo);
$("#ceoName").val(portalOrgData.ceoName);
$("#orgAddr").val(portalOrgData.orgAddr);
$("#ipListBody").empty(); // 기존 IP 목록 삭제
if (portalOrgData.ipWhitelist) {
var ipList = portalOrgData.ipWhitelist.split(',');
ipList.forEach(function(ip, index) {
var trimmedIp = ip.trim();
if (trimmedIp) {
addIpToTable(trimmedIp, index + 1);
}
});
$("#ipWhitelist").val(portalOrgData.ipWhitelist);
}
if (corporateManagerData) {
$("#userName").text(corporateManagerData.userName);
$("#userStatusDescription").text(corporateManagerData.userStatusDescription);
$("#emailAddr").text(corporateManagerData.emailAddr);
$("#mobileNumber").text(corporateManagerData.mobileNumber);
}
// 마스킹 해제 성공 시 수정 버튼 활성화
$("#btn_modify").prop('disabled', false);
$("#btn_unmask").prop('disabled', true); // 마스킹 해제 버튼 비활성화
alert("마스킹 해제가 완료되었습니다. 이제 데이터를 수정할 수 있습니다.");
},
error: function (e) {
alert("마스킹 해제 중 오류가 발생했습니다. " + e.responseText);
}
});
} else if (reason !== null) {
alert("마스킹 해제 사유를 입력해 주세요.");
}
});
$("#btn_modify").click(function(){
if (!checkRequired("ajaxForm")) return;
// 전화번호 조합하여 hidden input에 설정
var scPrefix = $("#scPhonePrefix").val();
var scMiddle = $("#scPhoneMiddle").val();
var scLast = $("#scPhoneLast").val();
var orgPrefix = $("#orgPhonePrefix").val();
var orgMiddle = $("#orgPhoneMiddle").val();
var orgLast = $("#orgPhoneLast").val();
// 전화번호 유효성 검사
if (scPrefix === "") {
alert("고객센터 전화번호 앞자리를 선택해주세요.");
$("#scPhonePrefix").focus();
return;
}
if (orgPrefix === "") {
alert("회사 전화번호 앞자리를 선택해주세요.");
$("#orgPhonePrefix").focus();
return;
}
if (!scMiddle || !scLast || scMiddle.length < 3 || scLast.length < 4) {
alert("올바른 고객센터 전화번호를 입력하여 주십시오.");
return;
}
if (!orgMiddle || !orgLast || orgMiddle.length < 3 || orgLast.length < 4) {
alert("올바른 회사 전화번호를 입력하여 주십시오.");
return;
}
// hidden input에 전체 전화번호 설정
$("input[name=scPhoneNumber]").val([scPrefix, scMiddle, scLast].join('-'));
$("input[name=orgPhoneNumber]").val([orgPrefix, orgMiddle, orgLast].join('-'));
// 파일 체크
var fileInput = document.getElementById('compRegFileUpload');
if (fileInput.files.length > 0) {
var file = fileInput.files[0];
if (file.size > 10 * 1024 * 1024) {
alert("파일 크기는 10MB 이내로 등록해 주세요.");
return;
}
var allowedExtensions = ['.pdf','.doc','.docx','.xls','.xlsx','.ppt','.pptx','.hwp','.gif','.jpg','.jpeg','.png'];
var fileExt = file.name.toLowerCase().substring(file.name.lastIndexOf('.'));
if (!allowedExtensions.includes(fileExt)) {
alert("허용된 파일 형식이 아닙니다.\n문서파일(pdf, doc, docx, xls, xlsx, ppt, pptx, hwp)과 이미지 파일(gif, jpg, png)만 등록 가능합니다.");
return;
}
}
if (confirm("<%= localeMessage.getString("common.checkSave")%>") !== true)
return;
// FormData 생성 전에 분리된 전화번호 필드 제거
$("#scPhonePrefix, #scPhoneMiddle, #scPhoneLast, #orgPhonePrefix, #orgPhoneMiddle, #orgPhoneLast").removeAttr('name');
var formData = new FormData($("#ajaxForm")[0]);
// 파일명 처리 - 새 파일이 있으면 새 파일명, 없으면 기존 파일명 유지
if (fileInput.files.length > 0) {
formData.set("fileName", fileInput.files[0].name);
} else if ($("#fileName").text()) {
formData.set("fileName", $("#fileName").text());
}
// 등록번호 하이픈 제거
var numberFields = ['compRegNo','corpRegNo'];
numberFields.forEach(function(field) {
var value = formData.get(field);
if (value) {
formData.set(field, removeHyphen(value));
}
});
var ipWhitelist = $("#ipWhitelist").val().trim();
if (ipWhitelist) {
var ipRegex = /^(\d{1,3}\.){3}\d{1,3}$/;
var ips = ipWhitelist.split(',').map(ip => ip.trim()).filter(ip => ip);
if (!ips.every(ip => ipRegex.test(ip))) {
alert("올바른 IP 주소 형식이 아닙니다.");
return;
}
}
// cmd 파라미터 추가
formData.append("cmd", isDetail ? "UPDATE" : "INSERT");
$.ajax({
type : "POST",
url:url,
data: formData,
processData: false,
contentType: false,
success:function(json){
alert("<%= localeMessage.getString("common.saveMsg") %>");
goNav(returnUrl);
},
error:function(e){
alert(e.responseText);
}
});
});
$("#btn_previous").click(function() {
goNav(returnUrl);
});
$("#btn_delete").click(function(){
if(confirm("<%= localeMessage.getString("common.confirmMsg")%>")){
var postData = $('#ajaxForm').serializeArray();
postData.push({name: "cmd" , value:"DELETE"});
$.ajax({
type : "POST",
url:url,
data:postData,
success:function(args){
alert("<%= localeMessage.getString("common.deleteMsg") %>");
goNav(returnUrl);
},
error:function(e){
alert(e.responseText);
}
});
}else{
return false;
}
});
});
</script>
</head>
<body>
<div class="right_box">
<div class="content_top">
<ul class="path">
<li><a href="#">${rmsMenuPath}</a></li>
</ul>
</div><!-- end content_top -->
<div class="content_middle">
<div class="search_wrap">
<button type="button" class="cssbtn" id="btn_unmask" level="W" status="DETAIL"><i class="material-icons">lock_open</i> 마스킹해제</button>
<button type="button" class="cssbtn" id="btn_modify" level="W" status="DETAIL,NEW"><i class="material-icons">save</i> <%= localeMessage.getString("button.modify") %></button>
<button type="button" class="cssbtn" id="btn_delete" level="W" status="DETAIL"><i class="material-icons">delete</i> <%= localeMessage.getString("button.delete") %></button>
<button type="button" class="cssbtn" id="btn_previous" level="R" status="DETAIL,NEW"><i class="material-icons">arrow_back</i> <%= localeMessage.getString("button.previous") %></button>
</div>
<div class="title" id ="title"><%= localeMessage.getString("portalOrgDetail.title") %></div>
<form id="ajaxForm" enctype="multipart/form-data" accept-charset="UTF-8">
<input type="hidden" name="id">
<table class="table_row" cellspacing="0">
<tr>
<th style="width:15%;"><%= getRequiredLabel(localeMessage.getString("portalOrg.orgName")) %></th>
<td colspan="3" style="width:35%;">
<input type="text" name="orgName" id="orgName" maxlength="50" data-required data-warning="법인명을 입력하여 주십시오."/>
</td>
<th style="width:15%;"><%= localeMessage.getString("portalOrg.orgSectors") %></th> <%--업태--%>
<td style="width:35%;"><input type="text" name="orgSectors" id="orgSectors" maxlength="50" /></td>
</tr>
<tr>
<th style="width:15%;"><%= getRequiredLabel(localeMessage.getString("portalOrg.orgCode")) %></th>
<td colspan="3" style="width:35%;">
<input type="text" name="orgCode" id="orgCode" readonly/>
</td>
<th><%= localeMessage.getString("portalOrg.orgIndustryType") %></th> <%--업종--%>
<td><input type="text" name="orgIndustryType" id="orgIndustryType" maxlength="50" /></td>
</tr>
<tr>
<th><%= getRequiredLabel(localeMessage.getString("portalOrg.compRegNo")) %></th>
<td colspan="3">
<input type="text" name="compRegNo" id ="compRegNo" data-required data-warning="사업자 등록번호를 입력하여 주십시오."/>
</td>
<th ><%= getRequiredLabel(localeMessage.getString("portalOrg.ceoName")) %></th>
<td>
<input type="text" name="ceoName" id="ceoName" maxlength="50"
data-required data-warning="대표자 성명을 입력하여 주십시오." />
</td>
</tr>
<tr>
<th><%= getRequiredLabel(localeMessage.getString("portalOrg.corpRegNo")) %></th>
<td colspan="3">
<input type="text" name="corpRegNo" id="corpRegNo"
data-required data-warning="법인등록번호를 입력하여 주십시오."/>
</td>
<th><%= getRequiredLabel(localeMessage.getString("portalOrg.orgAddr")) %></th>
<td>
<input type="text" name="orgAddr" id="orgAddr" maxlength="255"
data-required data-warning="사업장 소재지를 입력하여 주십시오."/>
</td>
</tr>
<tr>
<th style="width:15%;"><%= localeMessage.getString("portalUser.approvalStatus") %></th>
<td style="width:10%;"><div class="select-style"><select name="approvalStatus"/></div></td>
<th style="width:15%;"><%= localeMessage.getString("portalOrg.orgStatus") %></th>
<td style="width:10%;"><div class="select-style"><select name="orgStatus" id="orgStatus" /></div></td>
<th><%= getRequiredLabel(localeMessage.getString("portalOrg.serviceName")) %></th>
<td>
<input type="text" name="serviceName" id="serviceName" maxlength="36"
data-required data-warning="서비스명을 입력하여 주십시오."/>
</td>
</tr>
<tr>
<th><%= getRequiredLabel(localeMessage.getString("portalOrg.scPhoneNumber")) %></th>
<td colspan="3">
<div class="input-group" style="width: 60%; display: flex;">
<div class="select-style" style="width: 25%; display: inline-block;">
<select id="scPhonePrefix" name="scPhonePrefix" style="padding-left: 10px;"
data-required data-warning="고객센터 전화번호 앞자리를 선택해주세요.">
<option value="국번없음">국번없음</option>
<option value="02">02</option>
<option value="031">031</option>
<option value="032">032</option>
<option value="033">033</option>
<option value="041">041</option>
<option value="042">042</option>
<option value="043">043</option>
<option value="044">044</option>
<option value="051">051</option>
<option value="052">052</option>
<option value="053">053</option>
<option value="054">054</option>
<option value="055">055</option>
<option value="061">061</option>
<option value="062">062</option>
<option value="063">063</option>
<option value="064">064</option>
<option value="070">070</option>
</select>
</div>
<span class="mx-2">-</span>
<input type="text" id="scPhoneMiddle" name="scPhoneMiddle" maxlength="4" style="width: 20%; text-align: center;"
data-required data-warning="고객센터 전화번호 중간자리를 입력하여 주십시오." />
<span class="mx-2">-</span>
<input type="text" id="scPhoneLast" name="scPhoneLast" maxlength="4" style="width: 20%; text-align: center;"
data-required data-warning="고객센터 전화번호 끝자리를 입력하여 주십시오." />
<input type="hidden" name="scPhoneNumber"/>
</div>
</td>
<th><%= getRequiredLabel(localeMessage.getString("portalOrg.orgPhoneNumber")) %></th>
<td>
<div class="input-group" style="width: 60%; display: flex;">
<div class="select-style" style="width: 25%; display: inline-block;">
<select id="orgPhonePrefix" name="orgPhonePrefix" style="padding-left: 10px;"
data-required data-warning="회사 전화번호 앞자리를 선택해주세요." >
<option value="국번없음">국번없음</option>
<option value="02">02</option>
<option value="031">031</option>
<option value="032">032</option>
<option value="033">033</option>
<option value="041">041</option>
<option value="042">042</option>
<option value="043">043</option>
<option value="044">044</option>
<option value="051">051</option>
<option value="052">052</option>
<option value="053">053</option>
<option value="054">054</option>
<option value="055">055</option>
<option value="061">061</option>
<option value="062">062</option>
<option value="063">063</option>
<option value="064">064</option>
<option value="070">070</option>
</select>
</div>
<span class="mx-2">-</span>
<input type="text" id="orgPhoneMiddle" name="orgPhoneMiddle" maxlength="4" style="width: 20%; text-align: center;"
data-required data-warning="회사 전화번호 중간자리를 입력하여 주십시오." />
<span class="mx-2">-</span>
<input type="text" id="orgPhoneLast" name="orgPhoneLast" maxlength="4" style="width: 20%; text-align: center;"
data-required data-warning="회사 전화번호 끝자리를 입력하여 주십시오." />
<input type="hidden" name="orgPhoneNumber"/>
</div>
</td>
</tr>
<tr><%--사업자등록증--%>
<th><%= localeMessage.getString("portalOrg.compRegFile") %></th>
<td colspan="5" style="padding-top: 5px; padding-bottom: 5px;">
<input type="file" name="compRegFileUpload" id="compRegFileUpload" style="display: none;"
accept=".pdf,.doc,.docx,.xls,.xlsx,.ppt,.pptx,.hwp,.gif,.jpg,.jpeg,.png" />
<button type="button" id="uploadButton" class="smallBtn cssbtn">파일 선택</button>
<div style="display: inline-block; margin-left: 10px;">
<span id="fileWrapper" style="display: none; cursor: pointer;">
<img src="${pageContext.request.contextPath}/images/icon_file.png"
style="vertical-align: middle; margin-right: 5px; font-size: 0.7rem;">
<span id="fileName" style="text-decoration: underline;" name="fileName"></span>
</span>
</div>
<input type="hidden" name="compRegFile" id="compRegFile" />
<div class="file-description" style="margin-top: 5px; color: #666; font-size: 0.7rem;">
첨부파일은 10MB 이내로 등록해 주세요.<br>
문서파일과 이미지 파일만 등록 가능합니다. (pdf, doc, docx, xls, xlsx, ppt, pptx, hwp, gif, jpg, png)
</div>
</td>
</tr>
</table>
<%--법인 관리자정보--%>
<div id="managerInfoSectionTitle" class="title" style="margin-top: 50px;"><%= localeMessage.getString("portalOrg.portalUser.title") %></div>
<div id="managerInfoSection" style="display: none;" >
<table class="table_row" cellspacing="0">
<tr>
<th style="width:15%;"><%= localeMessage.getString("portalUser.name") %></th>
<td style="width:35%;" id="userName"></td>
<th style="width:15%;"><%= localeMessage.getString("portalUser.userStatus") %></th> <%--계정상태--%>
<td style="width:35%;" id="userStatusDescription"></td>
</tr>
<tr>
<th><%= localeMessage.getString("portalUser.emailAddr") %></th> <%--이메일 아이디--%>
<td id="emailAddr"></td>
<th><%= localeMessage.getString("portalUser.mobile") %></th> <%--핸드폰 번호--%>
<td id="mobileNumber"></td>
</tr>
</table>
</div>
<div id="noManagerMessage" style="display: none; font-size: 0.8rem;">
<p><%= localeMessage.getString("portalOrg.noManagerMsg") %></p>
</div>
<div id="ipWhitelistList" style="margin-top: 50px;">
<div class="title" style="margin-top: 10px">사용 서버 IP 대역 (화이트리스트)</div>
<table class="table_row" cellspacing="0" style="width:50%;">
<tr>
<th style="width:15%;"><%= localeMessage.getString("portalOrg.ipWhitelist") %></th>
<td>
<div style="display: flex; align-items: center;">
<input type="text" id="ipInput" style="width:200px; margin-right: 10px;" maxlength="15" placeholder="xxx.xxx.xxx.xxx">
<button type="button" class="cssbtn smallBtn" id="btn_add_ip"><i class="material-icons">add</i> IP 추가</button>
</div>
</td>
</tr>
</table>
<!-- IP 목록 테이블 -->
<table class="table_row" cellspacing="0" style="margin-top: 10px; width:50%;">
<thead>
<tr>
<th style="width:10%;">No</th>
<th>IP</th>
<th style="width:20%;">삭제</th>
</tr>
</thead>
<tbody id="ipListBody">
<!-- 동적으로 추가될 IP 목록 -->
</tbody>
</table>
<input type="hidden" name="ipWhitelist" id="ipWhitelist">
</div>
</form>
</div>
</div>
</body>
</html>
@@ -0,0 +1,144 @@
<%@ page language="java" contentType="text/html; charset=utf-8"%>
<%@ page import="java.io.*"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib uri="http://www.springframework.org/tags" prefix="spring"%>
<%@ include file="/jsp/common/include/localemessage.jsp" %>
<%
response.setHeader("Pragma", "No-cache");
response.setHeader("Cache-Control", "no-cache");
response.setHeader("Expires", "0");
%>
<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<jsp:include page="/jsp/common/include/css.jsp"/>
<jsp:include page="/jsp/common/include/script.jsp"/>
<script language="javascript" >
var url ='<c:url value="/onl/apim/portalpartnership/portalPartnershipMan.json" />';
var url_view ='<c:url value="/onl/apim/portalpartnership/portalPartnershipMan.view" />';
function formatFile(cellvalue, options, rowObject) {
var iconPath = '${pageContext.request.contextPath}/images/icon_file.png';
var icon = rowObject.hasAttachment ?
'<img src="' + iconPath + '" alt="File Attached" style="vertical-align: middle; margin-left: 5px; width: 16px; height: 16px;">' :
'';
return cellvalue + icon;
}
$(document).ready(function() {
$('#grid').jqGrid({
datatype:"json",
mtype: 'POST',
url: url,
postData : { cmd : 'LIST',
searchBizSubject: $('input[name=searchBizSubject]').val() ,
searchBizDetail: $('input[name=searchBizDetail]').val()
},
colNames:['No.', 'ID', '제목', '작성자', '작성일시'],
colModel:[
{ name : 'rowNum' , align:'center', width: 40, sortable: false },
{ name : 'id' , align:'center', key: true, hidden: true},
{ name : 'bizSubject' , align:'center', width: 150, formatter: formatFile },
{ name : 'createdByName' , align:'center' ,width: 80},
{ name : 'createdDate' , align:'center', width: 100, formatter: timeStampFormat }
],
jsonReader: {
repeatitems:false
},
pager : $('#pager'),
page : '${param.page}',
rowNum : '${rmsDefaultRowNum}',
autoheight: true,
height: $("#container").height(),
autowidth: true,
viewrecords: true,
rowList : eval('[${rmsDefaultRowList}]'),
ondblClickRow: function(rowId) {
var rowData = $(this).getRowData(rowId);
var id = rowData['id'];
var url2 = url_view;
url2 += '?cmd=DETAIL';
url2 += '&page='+$(this).getGridParam("page");
url2 += '&returnUrl='+getReturnUrl();
url2 += '&menuId='+'${param.menuId}';
url2 += '&id='+id;
goNav(url2);
},
gridComplete:function (d){
var records = $(this).getGridParam('records');
var page = $(this).getGridParam('page');
var rowNum = $(this).getGridParam('rowNum');
var rows = $(this).getDataIDs();
var colModel = $(this).getGridParam("colModel");
for (var i = 0; i < rows.length; i++) {
var number = ((page - 1) * rowNum + i) + 1;
// var reverseNumber = records - ((page - 1) * rowNum + i);
$(this).setCell(rows[i], 'rowNum', number);
}
for(var i = 0 ; i< colModel.length; i++){
$(this).setColProp(colModel[i].name, {sortable : false});
}
},loadError: function (jqXHR, textStatus, errorThrown) {
var location ='<%=request.getContextPath()%>/';
comloadError(jqXHR, textStatus, errorThrown ,location);
}
});
resizeJqGridWidth('grid','content_middle','1000');
$("#btn_search").click(function(){
var postData = getSearchForJqgrid("cmd","LIST"); //jqgrid에서는 object 로
$("#grid").setGridParam({ url:url,postData: postData ,page:1 }).trigger("reloadGrid");
});
$("input[name^=search]").keydown(function(key){
if (key.keyCode == 13){
$("#btn_search").click();
}
});
buttonControl();
});
</script>
</head>
<body>
<div class="right_box">
<div class="content_top">
<ul class="path">
<li><a href="#">${rmsMenuPath}</a></li>
</ul>
</div><!-- end content_top -->
<div class="content_middle" id="content_middle">
<div class="search_wrap">
<button type="button" class="cssbtn" id="btn_search" level="R" ><i class="material-icons">search</i> <%= localeMessage.getString("button.search") %></button>
</div>
<div class="title">사업제휴 신청 목록</div>
<form id="ajaxForm" onsubmit="return false;">
<table class="search_condition" cellspacing=0;>
<tbody>
<tr>
<th style="width:180px;">제목</th>
<td><input type="text" name="searchBizSubject" value="${param.searchBizSubject}"></td>
<th style="width:180px;">내용</th>
<td><input type="text" name="searchBizDetail" value="${param.searchBizDetail}"></td>
</tr>
</tbody>
</table>
</form>
<table id="grid" ></table>
<div id="pager"></div>
</div><!-- end content_middle -->
</div><!-- end right_box -->
</body>
</html>
@@ -0,0 +1,178 @@
<%@ page language="java" contentType="text/html; charset=utf-8"%>
<%@ page import="java.io.*"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib uri="http://www.springframework.org/tags" prefix="spring"%>
<%@ include file="/jsp/common/include/localemessage.jsp" %>
<%
response.setHeader("Pragma", "No-cache");
response.setHeader("Cache-Control", "no-cache");
response.setHeader("Expires", "0");
%>
<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<jsp:include page="/jsp/common/include/css.jsp"/>
<jsp:include page="/jsp/common/include/script.jsp"/>
<jsp:include page="/jsp/common/include/portal.jsp"/>
<script language="javascript" >
var url ='<c:url value="/onl/apim/portalpartnership/portalPartnershipMan.json" />';
var url_view ='<c:url value="/onl/apim/portalpartnership/portalPartnershipMan.view" />';
var file_download = '<c:url value="/file/download.do" />';
var isDetail = false;
function formatFileSize(bytes) {
if(bytes == 0) return '0 Bytes';
var k = 1024,
sizes = ['Bytes', 'KB', 'MB', 'GB'],
i = Math.floor(Math.log(bytes) / Math.log(k));
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
}
function detail(key){
if (!isDetail)return;
$.ajax({
type : "POST",
url:url,
dataType:"json",
data:{cmd: 'DETAIL', id : key},
success:function(data){
$("#bizSubject").text(data.bizSubject);
$("#bizDetail").html(data.bizDetail);
$("#createdByName").text(data.createdByName);
$("#createdById").text(data.createdById);
$("#createdDate").text(timeStampFormat(data.createdDate));
// 첨부파일 처리
if(data.hasAttachment && data.fileInfo) {
$("#fileRow").show();
var iconPath = '${pageContext.request.contextPath}/images/icon_file.png';
var fileLink = $('<span class="file-item" style="cursor:pointer">').click(function() {
downloadFile(data.fileInfo.fileId);
});
$('<img>').attr('src', iconPath)
.css({ 'marginRight': '5px', 'height': '1.2em', 'verticalAlign': 'middle'})
.appendTo(fileLink);
$('<span>').text(data.fileInfo.fileDetails[0].originalFileName + '.' +
data.fileInfo.fileDetails[0].fileExtension + ' (' +
formatFileSize(data.fileInfo.fileDetails[0].fileSize) + ')')
.appendTo(fileLink);
$("#fileArea").empty().append(fileLink);
} else {
$("#fileRow").hide();
}
},
error:function(e){
alert(e.responseText);
}
});
}
function downloadFile(fileId) {
if (fileId) {
var fileSn = 1;
window.location.href = file_download + '?fileId=' + fileId + '&fileSn=' + fileSn;
}
}
$(document).ready(function() {
var key = "${param.id}";
if (key && key !=="null"){
isDetail = true;
detail(key);
}
$("#btn_previous").click(function(){
var returnUrl = getReturnUrlForReturn();
goNav(returnUrl);//LIST로 이동
});
$("#btn_unmask").click(function () {
const reason = prompt("마스킹 해제 사유를 입력하세요:");
if (reason && reason.trim() !== "") {
$.ajax({
type: "POST",
url: url,
dataType: "json",
data: {
cmd: "UNMASK",
id: key,
reason: reason
},
success: function (data) {
$("#createdByName").text(data.createdByName);
$("#createdById").text(data.createdById);
$("#btn_unmask").hide();
},
error: function (xhr, status, error) {
alert("서버 요청 중 오류가 발생했습니다. 다시 시도해 주세요.");
}
});
} else if (unmaskReason !== null) {
alert("마스킹 해제 사유를 입력해야 합니다.");
}
});
buttonControl();
});
</script>
</head>
<body>
<div class="right_box">
<div class="content_top">
<ul class="path">
<li><a href="#">${rmsMenuPath}</a></li>
</ul>
</div><!-- end content_top -->
<div class="content_middle">
<div class="search_wrap">
<button type="button" class="cssbtn" id="btn_unmask" level="W" status="DETAIL"><i class="material-icons">lock_open</i> 마스킹해제</button>
<button type="button" class="cssbtn" id="btn_previous" level="R" status="DETAIL,NEW"><i class="material-icons">arrow_back</i> <%= localeMessage.getString("button.previous") %></button>
</div>
<div class="title">사업제휴 신청 상세</div>
<table id="grid" ></table>
<div id="pager"></div>
<form id="ajaxForm">
<table class="table_row" cellspacing="0">
<tr>
<th style="width:10%;">작성자</th>
<td id="createdByName" style="width:40%;"></td>
<th style="width:10%;">작성일</th>
<td id="createdDate" style="width:40%;"></td>
</tr>
<tr>
<th style="width:10%;">작성자 아이디</th>
<td id="createdById" colspan="3"></td>
</tr>
<tr>
<th style="width:10%;">사업 제목</th>
<td colspan="5" id="bizSubject"></td>
</tr>
<tr id="fileRow">
<th>첨부파일</th>
<td colspan="5" id="fileArea"></td>
</tr>
<tr>
<th>사업 내용</th>
<td colspan="5">
<div id="bizDetail" style="min-height: 200px; padding-top: 10px;"></div>
</td>
</td>
</tr>
</table>
</form>
</div><!-- end content_middle -->
</div><!-- end right_box -->
</body>
</html>
@@ -0,0 +1,350 @@
<%@ page language="java" contentType="text/html; charset=utf-8" %>
<%@ page import="java.io.*" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib uri="http://www.springframework.org/tags" prefix="spring" %>
<%@ include file="/jsp/common/include/localemessage.jsp" %>
<%
response.setHeader("Pragma", "No-cache");
response.setHeader("Cache-Control", "no-cache");
response.setHeader("Expires", "0");
%>
<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<jsp:include page="/jsp/common/include/css.jsp"/>
<jsp:include page="/jsp/common/include/script.jsp"/>
<script language="javascript">
var url = '<c:url value="/onl/apim/portalproperty/propertyMan.json" />';
var url_view = '<c:url value="/onl/apim/portalproperty/propertyMan.view" />';
var lastsel2;
function isValid() {
if ($('input[name=prptyGroupName]').val() == "") {
alert("<%= localeMessage.getString("propertyDetail.checkRequired4") %>");
$('input[name=prptyGroupName]').focus();
return false;
}
if ($('input[name=prptyGroupDesc]').val() == "") {
alert("<%= localeMessage.getString("propertyDetail.checkRequired1") %>");
$('input[name=prptyGroupDesc]').focus();
return false;
}
return true;
}
function isValidGrid() {
if ($('input[name=prptyName]').val() == "") {
alert("<%= localeMessage.getString("propertyDetail.checkRequired2") %>");
return false;
} else if ($('input[name=prpty2Val]').val() == "") {
alert("<%= localeMessage.getString("propertyDetail.checkRequired3") %>");
return false;
}
//중복체크
if ($("#grid tr#" + lastsel2).attr("editable") == 1) { //editable=1 means row in edit mode
$("#grid").saveRow(lastsel2, false, "clientArray");
}
var data = $("#grid").getRowData();
for (var i = 0; i < data.length; i++) {
if (data[i]['PRPTYNAME'] == $('input[name=prptyName]').val()) {
alert("<%= localeMessage.getString("propertyDetail.checkDuplicate") %>");
return false;
}
}
return true;
}
function checkDuplicatePrptyName(data) {
var prptyNameSet = new Set();
for (var i = 0; i < data.length; i++) {
if (prptyNameSet.has(data[i].PRPTYNAME)) {
return true; // 중복 발견
}
prptyNameSet.add(data[i].PRPTYNAME);
}
return false;
}
function unformatterFunction(cellvalue, options, rowObject) {
return "";
}
function formatterFunction(cellvalue, options, rowObject) {
var rowId = options["rowId"];
return "<button type='button' class='cssbtn smallBtn2' id='btn_pop_delete' style='vertical-align:middle; font-weight:bold;' name='img_" + rowId + "'>delete</button>";
}
function gridRendering() {
$('#grid').jqGrid({
datatype: "local",
loadonce: true,
rowNum: 1000,
editurl: "clientArray",
colNames: ['<%= localeMessage.getString("propertyDetail.propertyKey") %>',
'<%= localeMessage.getString("propertyDetail.propertyValue") %>',
'<%= localeMessage.getString("propertyDetail.delYn") %>'],
colModel: [{name: 'PRPTYNAME', width: 50, align: 'left', editable: true},
{name: 'PRPTY2VAL', width: 200, align: 'left', editable: true},
{
name: 'DELETEYN',
width: 20,
align: 'center',
unformat: unformatterFunction,
formatter: formatterFunction
}],
jsonReader: {
repeatitems: false
},
loadComplete: function () {
},
onSelectRow: function (rowid, status) {
if (lastsel2 != undefined) {
if ($("#grid tr#" + lastsel2).attr("editable") == 1) { //editable=1 means row in edit mode
$("#grid").saveRow(lastsel2, false, "clientArray");
}
}
$('#grid').restoreRow(lastsel2);
$('#grid').editRow(rowid, true);
lastsel2 = rowid;
},
onSortCol: function () {
return 'stop'; //정렬 방지
},
height: '500',
autowidth: true,
//autoheight : true,
viewrecords: true
,
loadError: function (jqXHR, textStatus, errorThrown) {
var location = '<%=request.getContextPath()%>/';
comloadError(jqXHR, textStatus, errorThrown, location);
}
});
resizeJqGridWidth('grid', 'title', '1000');
}
function init(key, callback) {
if (typeof callback === 'function') {
callback(key);
}
}
function detail(key) {
$.ajax({
type: "POST",
url: url,
dataType: "json",
data: {
cmd: 'DETAIL',
prptyGroupName: key
},
success: function (json) {
$("input[name=prptyGroupName]").val(json.PRPTYGROUPNAME).attr('readonly', true);
$("input[name=prptyGroupDesc]").val(json.PRPTYGROUPDESC);
$("#grid")[0].addJSONData(json.gridData);
$("button[name*=img]").click(function () {
var name = $(this).attr("name");
var rowId = name.split("_")[1];
$('#grid').jqGrid('delRowData', rowId);
});
},
error: function (e) {
alert(e.responseText);
}
});
}
$(document).ready(function () {
var returnUrl = getReturnUrlForReturn();
var key = "Portal";
gridRendering();
init(key, detail);
$("#btn_modify").click(function () {
if (!isValid()) return;
if (confirm("<%= localeMessage.getString("common.checkModify")%>") != true)
return;
if ($("#grid tr#" + lastsel2).attr("editable") == 1) { //editable=1 means row in edit mode
$("#grid").saveRow(lastsel2, false, "clientArray");
}
var data = $("#grid").getRowData();
// PrptyName 중복 체크
if (checkDuplicatePrptyName(data)) {
alert("<%= localeMessage.getString("propertyDetail.checkDuplicate") %>");
return;
}
var prptyGroupNameValue = $("input[name=prptyGroupName]").val();
var gridData = new Array();
for (var i = 0; i < data.length; i++) {
data[i]["PRPTYGROUPNAME"] = prptyGroupNameValue;
gridData.push(data[i]);
}
//공통부만 form으로 구성
var postData = $('#ajaxForm').serializeArray();
postData.push({
name: "gridData",
value: JSON.stringify(gridData)
});
postData.push({
name: "cmd",
value: "UPDATE"
});
$.ajax({
type: "POST",
url: url,
data: postData,
success: function (args) {
alert("<%= localeMessage.getString("common.saveMsg") %>");
goNav(returnUrl);//LIST로 이동
},
error: function (e) {
alert(e.responseText);
}
});
});
<%--$("#btn_delete").click(function () {--%>
<%-- if (confirm('<%=localeMessage.getString("common.confirmMsg")%>') != true)--%>
<%-- return;--%>
<%-- var postData = $('#ajaxForm').serializeArray();--%>
<%-- postData.push({--%>
<%-- name: "cmd",--%>
<%-- value: "DELETE"--%>
<%-- });--%>
<%-- $.ajax({--%>
<%-- type: "POST",--%>
<%-- url: url,--%>
<%-- data: postData,--%>
<%-- success: function (args) {--%>
<%-- alert("<%= localeMessage.getString("common.deleteMsg") %>");--%>
<%-- goNav(returnUrl);//LIST로 이동--%>
<%-- },--%>
<%-- error: function (e) {--%>
<%-- alert(e.responseText);--%>
<%-- }--%>
<%-- });--%>
<%--});--%>
$("#btn_previous").click(function () {
goNav(returnUrl);//LIST로 이동
});
$("#btn_pop_input").click(function () {
if (!isValidGrid()) {
return;
}
var data = new Object();
data["PRPTYNAME"] = $("input[name=prptyName]").val();
data["PRPTY2VAL"] = $("input[name=prpty2Val]").val();
var rows = $("#grid")[0].rows;
var index = Number($(rows[rows.length - 1]).attr("id"));
if (isNaN(index))
index = 0;
var rowid = index + 1;
$("#grid").jqGrid('addRow', {
rowID: rowid,
initdata: data,
position: "last", //first, last
useDefValues: false,
useFormatter: false,
addRowParams: {
extraparam: {}
}
});
$("#" + $('#grid').jqGrid('getGridParam', 'selrow')).focus();
$("button[name=img_" + rowid + "]").click(function () {
var name = $(this).attr("name");
var rowId = name.split("_")[1];
$('#grid').jqGrid('delRowData', rowId);
});
});
buttonControl(key);
titleControl(key);
});
</script>
</head>
<body>
<div class="right_box">
<div class="content_top">
<ul class="path">
<li><a href="#">${rmsMenuPath}</a></li>
</ul>
</div><!-- end content_top -->
<div class="content_middle" id="title">
<div class="search_wrap">
<%-- <button type="button" class="cssbtn" id="btn_delete" level="W" status="DETAIL">--%>
<%-- <i class="material-icons">delete</i> <%= localeMessage.getString("button.delete") %>--%>
<%-- </button>--%>
<button type="button" class="cssbtn" id="btn_modify" level="W" status="DETAIL,NEW">
<i class="material-icons">save</i> <%= localeMessage.getString("button.modify") %>
</button>
</div>
<div class="title"><%= localeMessage.getString("portalPropDetail.title") %>
</div>
<form id="ajaxForm">
<table class="table_row" cellspacing="0">
<tr>
<th style="width:180px;"><%= localeMessage.getString("property.propertyGroupName") %> *</th>
<td><input type="text" name="prptyGroupName"/>
</td>
</tr>
<tr>
<th><%= localeMessage.getString("property.propertyGroupDesc") %> *</th>
<td><input type="text" name="prptyGroupDesc"/>
</td>
</tr>
</table>
</form>
<table class="table_row" cellspacing="0">
<tr>
<th style="width:180px;"><%= localeMessage.getString("propertyDetail.propertyKey") %>
</th>
<td>
<input type="text" name="prptyName" style="width:calc(100% - 70px);"/>
<button type="button" class="cssbtn smallBtn2" id="btn_pop_input"
style="vertical-align:middle; font-weight:bold;"><i
class="material-icons">input</i><%= localeMessage.getString("button.input") %>
</button>
</td>
</tr>
<tr>
<th><%= localeMessage.getString("propertyDetail.propertyValue") %>
</th>
<td colspan="3"><input type="text" name="prpty2Val"/>
</td>
</tr>
</table>
<!-- grid -->
<table id="grid"></table>
</div><!-- end content_middle -->
</div><!-- end right_box -->
</body>
</html>
@@ -0,0 +1,269 @@
<%@ page language="java" contentType="text/html; charset=utf-8"%>
<%@ page import="java.io.*"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib uri="http://www.springframework.org/tags" prefix="spring"%>
<%@ include file="/jsp/common/include/localemessage.jsp" %>
<%
response.setHeader("Pragma", "No-cache");
response.setHeader("Cache-Control", "no-cache");
response.setHeader("Expires", "0");
%>
<!DOCTYPE html>
<html>
<head>
<title>API 통계 목록</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<jsp:include page="/jsp/common/include/css.jsp"/>
<jsp:include page="/jsp/common/include/script.jsp"/>
<jsp:include page="/jsp/common/include/portal.jsp"/>
<script language="javascript">
var url = '<c:url value="/onl/apim/portalstatistics/portalStatisticsApiTableMan.json" />';
var grid;
$(document).ready(function() {
// Datepicker 초기화
$("input[name=startDate], input[name=endDate]").datepicker({
format: "yyyy-mm-dd",
autoclose: true,
todayHighlight: true,
language: "ko"
});
function setActiveDateRangeButton() {
var startDate = $("input[name=startDate]").datepicker('getDate');
var endDate = $("input[name=endDate]").datepicker('getDate');
var diffDays = Math.floor((endDate - startDate) / (1000 * 60 * 60 * 24));
$('.btn-date-range').removeClass('active');
if (diffDays === 30) {
$('#btn_month').addClass('active');
} else if (diffDays === 7) {
$('#btn_week').addClass('active');
} else if (diffDays === 0) {
$('#btn_today').addClass('active');
}
}
function setDateRange(days) {
var now = new Date();
var endDate = now;
var startDate = new Date(now.getFullYear(), now.getMonth(), now.getDate() - days);
$("input[name=startDate]").datepicker('setDate', startDate);
$("input[name=endDate]").datepicker('setDate', endDate);
setActiveDateRangeButton();
}
$("#btn_month").click(function() {
setDateRange(30);
loadData();
});
$("#btn_week").click(function() {
setDateRange(7);
loadData();
});
$("#btn_today").click(function() {
setDateRange(0);
loadData();
});
setDateRange(0);
function initGrid(data) {
if (grid) {
grid.destroy();
}
var columns = [
{ id: 'apiName', name: 'API 명', sort: true,
formatter: (cell) => gridjs.html('<b>'+cell+'</b>')},
{
id: 'totalRequests',
name: '총 요청 수',
sort: true,
formatter: (cell) => gridjs.html('<span style="color: #0a53be;">'+cell+'</span>')
},
{
id: 'totalFailures',
name: '오류 건수',
sort: true,
formatter: (cell) => gridjs.html('<span style="color: #dc3545;">'+cell+'</span>')
},
{
id: 'successRate',
name: '성공 률 (%)',
sort: true
}
];
grid = new gridjs.Grid({
columns: columns,
data: data,
sort: true,
pagination: {
limit: 10
},
search: true,
style: {
table: {
border: '3px solid #ccc'
},
th: {
'background-color': 'rgba(0, 0, 0, 0.1)',
color: '#000',
'border-bottom': '3px solid #ccc',
'text-align': 'center'
},
td: {
'text-align': 'center'
}
}
}).render(document.getElementById('wrapper'));
addExportButton(grid);
}
function updateSummary(summary) {
$("#totalApis").text(summary.totalApis);
$("#totalRequests").text(summary.totalRequests.toLocaleString());
$("#totalFailures").text(summary.totalFailures.toLocaleString());
$("#overallSuccessRate").text(summary.overallSuccessRate.toFixed(2));
}
function loadData() {
var startDate = $("input[name=startDate]").val().replace(/-/g, '');
var endDate = $("input[name=endDate]").val().replace(/-/g, '');
$.ajax({
url: url,
type: "POST",
data: {
cmd: "LIST",
startDate: startDate,
endDate: endDate
},
success: function(response) {
updateSummary(response.summary);
initGrid(response.apiStats);
},
error: function(xhr, status, error) {
console.error("Error fetching data:", error);
alert("데이터를 불러오는 중 오류가 발생했습니다.");
}
});
}
$("#btn_search").click(function (){
setActiveDateRangeButton();
loadData();
});
loadData(); // 초기 데이터 로드
});
</script>
</head>
<body>
<div class="right_box">
<div class="content_top">
<ul class="path">
<li><a href="#">${rmsMenuPath}</a></li>
</ul>
</div>
<div class="content_middle" id="content_middle">
<h2 class="mb-4">API 별 통계 목록</h2>
<div class="row mb-4">
<div class="col-md-3 mb-3">
<div class="card text-center h-100">
<div class="card-body">
<i class="bi bi-hdd-stack card-icon text-primary"></i>
<h5 class="card-title">총 API 수</h5>
<p class="card-text">
<span id="totalApis">0</span> 개
</p>
</div>
</div>
</div>
<div class="col-md-3 mb-3">
<div class="card text-center h-100">
<div class="card-body">
<i class="bi bi-arrow-repeat card-icon text-success"></i>
<h5 class="card-title">총 요청 수</h5>
<p class="card-text">
<span id="totalRequests">0</span>
</p>
</div>
</div>
</div>
<div class="col-md-3 mb-3">
<div class="card text-center h-100">
<div class="card-body">
<i class="bi bi-exclamation-triangle card-icon text-danger"></i>
<h5 class="card-title">총 실패 수</h5>
<p class="card-text">
<span id="totalFailures">0</span>
</p>
</div>
</div>
</div>
<div class="col-md-3 mb-3">
<div class="card text-center h-100">
<div class="card-body">
<i class="bi bi-graph-up card-icon text-info"></i>
<h5 class="card-title">전체 성공률</h5>
<p class="card-text">
<span id="overallSuccessRate">0</span>%
</p>
</div>
</div>
</div>
</div>
<div class="search-panel mb-4">
<h5 class="mb-3">검색 조건</h5>
<div class="row g-3 align-items-center">
<div class="col-md-3">
<div class="input-group">
<span class="input-group-text"><i class="bi bi-calendar"></i></span>
<input type="text" name="startDate" class="form-control" data-required data-warning="시작 날짜를 입력하여 주십시오." placeholder="시작 날짜"/>
</div>
</div>
<div class="col-auto">
<span>~</span>
</div>
<div class="col-md-3">
<div class="input-group">
<span class="input-group-text"><i class="bi bi-calendar"></i></span>
<input type="text" name="endDate" class="form-control" data-required data-warning="종료 날짜를 입력하여 주십시오." placeholder="종료 날짜"/>
</div>
</div>
<div class="col-auto">
<button type="button" id="btn_month" class="btn btn-outline-secondary btn-date-range">
<i class="bi bi-calendar-month"></i> 한달
</button>
<button type="button" id="btn_week" class="btn btn-outline-secondary btn-date-range">
<i class="bi bi-calendar-week"></i> 한주
</button>
<button type="button" id="btn_today" class="btn btn-outline-secondary btn-date-range">
<i class="bi bi-calendar-day"></i> 금일
</button>
</div>
<div class="col-auto">
<button type="button" id="btn_search" class="btn btn-primary">
<i class="bi bi-search"></i> 조회
</button>
</div>
</div>
</div>
<div id="wrapper"></div>
</div>
</div>
</body>
</html>
@@ -0,0 +1,262 @@
<%@ page language="java" contentType="text/html; charset=utf-8"%>
<%@ page import="java.io.*"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib uri="http://www.springframework.org/tags" prefix="spring"%>
<%@ include file="/jsp/common/include/localemessage.jsp" %>
<%
response.setHeader("Pragma", "No-cache");
response.setHeader("Cache-Control", "no-cache");
response.setHeader("Expires", "0");
%>
<!DOCTYPE html>
<html>
<head>
<title>앱별 통계 목록</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<jsp:include page="/jsp/common/include/css.jsp"/>
<jsp:include page="/jsp/common/include/script.jsp"/>
<jsp:include page="/jsp/common/include/portal.jsp"/>
<script language="javascript">
var url = '<c:url value="/onl/apim/portalstatistics/portalStatisticsAppTableMan.json" />';
var grid;
$(document).ready(function() {
// Datepicker 초기화
$("input[name=startDate], input[name=endDate]").datepicker({
format: "yyyy-mm-dd",
autoclose: true,
todayHighlight: true,
language: "ko"
});
function setActiveDateRangeButton() {
var startDate = $("input[name=startDate]").datepicker('getDate');
var endDate = $("input[name=endDate]").datepicker('getDate');
var diffDays = Math.floor((endDate - startDate) / (1000 * 60 * 60 * 24));
$('.btn-date-range').removeClass('active');
if (diffDays === 30) {
$('#btn_month').addClass('active');
} else if (diffDays === 7) {
$('#btn_week').addClass('active');
} else if (diffDays === 0) {
$('#btn_today').addClass('active');
}
}
function setDateRange(days) {
var now = new Date();
var endDate = now;
var startDate = new Date(now.getFullYear(), now.getMonth(), now.getDate() - days);
$("input[name=startDate]").datepicker('setDate', startDate);
$("input[name=endDate]").datepicker('setDate', endDate);
setActiveDateRangeButton();
}
$("#btn_month").click(function() {
setDateRange(30);
loadData();
});
$("#btn_week").click(function() {
setDateRange(7);
loadData();
});
$("#btn_today").click(function() {
setDateRange(0);
loadData();
});
setDateRange(0);
function initGrid(data) {
if (grid) {
grid.destroy();
}
var columns = [
{ id: 'appName', name: 'APP 명', sort: true,
formatter: (cell) => gridjs.html('<b>'+cell+'</b>')
},
{ id: 'totalRequests', name: '총 요청 수', sort: true,
formatter: (cell) => gridjs.html('<span style="color: #0a53be;">'+cell+'</span>')
},
{ id: 'totalFailures', name: '오류 건수', sort: true,
formatter: (cell) => gridjs.html('<span style="color: #dc3545;">'+cell+'</span>')
},
{ id: 'successRate', name: '성공 률 (%)', sort: true,
formatter: (cell) => gridjs.html('<span style="color: #198754;">'+cell+'%</span>')
}
];
grid = new gridjs.Grid({
columns: columns,
data: data,
sort: true,
pagination: {
limit: 10
},
search: true,
style: {
table: {
border: '3px solid #ccc'
},
th: {
'background-color': 'rgba(0, 0, 0, 0.1)',
color: '#000',
'border-bottom': '3px solid #ccc',
'text-align': 'center'
},
td: {
'text-align': 'center'
}
}
}).render(document.getElementById('wrapper'));
addExportButton(grid);
}
function updateSummary(summary) {
$("#totalApps").text(summary.totalApps);
$("#totalRequests").text(summary.totalRequests.toLocaleString());
$("#totalFailures").text(summary.totalFailures.toLocaleString());
$("#overallSuccessRate").text(summary.overallSuccessRate.toFixed(2));
}
function loadData() {
var startDate = $("input[name=startDate]").val().replace(/-/g, '');
var endDate = $("input[name=endDate]").val().replace(/-/g, '');
$.ajax({
url: url,
type: "POST",
data: {
cmd: "LIST",
startDate: startDate,
endDate: endDate
},
success: function(response) {
updateSummary(response.summary);
initGrid(response.appStats);
},
error: function(xhr, status, error) {
console.error("Error fetching data:", error);
alert("데이터를 불러오는 중 오류가 발생했습니다.");
}
});
}
$("#btn_search").click(function (){
setActiveDateRangeButton();
loadData();
});
loadData(); // 초기 데이터 로드
});
</script>
</head>
<body>
<div class="right_box">
<div class="content_top">
<ul class="path">
<li><a href="#">${rmsMenuPath}</a></li>
</ul>
</div>
<div class="content_middle" id="content_middle">
<h2 class="mb-4">APP 별 통계 목록</h2>
<div class="row mb-4">
<div class="col-md-3 mb-3">
<div class="card text-center h-100">
<div class="card-body">
<i class="bi bi-window-stack card-icon text-primary"></i>
<h5 class="card-title">총 앱 수</h5>
<p class="card-text">
<span id="totalApps">0</span> 개
</p>
</div>
</div>
</div>
<div class="col-md-3 mb-3">
<div class="card text-center h-100">
<div class="card-body">
<i class="bi bi-arrow-repeat card-icon text-success"></i>
<h5 class="card-title">총 요청 수</h5>
<p class="card-text">
<span id="totalRequests">0</span>
</p>
</div>
</div>
</div>
<div class="col-md-3 mb-3">
<div class="card text-center h-100">
<div class="card-body">
<i class="bi bi-exclamation-triangle card-icon text-danger"></i>
<h5 class="card-title">총 실패 수</h5>
<p class="card-text">
<span id="totalFailures">0</span>
</p>
</div>
</div>
</div>
<div class="col-md-3 mb-3">
<div class="card text-center h-100">
<div class="card-body">
<i class="bi bi-graph-up card-icon text-info"></i>
<h5 class="card-title">전체 성공률</h5>
<p class="card-text">
<span id="overallSuccessRate">0</span>%
</p>
</div>
</div>
</div>
</div>
<div class="search-panel mb-4">
<h5 class="mb-3">검색 조건</h5>
<div class="row g-3 align-items-center">
<div class="col-md-3">
<div class="input-group">
<span class="input-group-text"><i class="bi bi-calendar"></i></span>
<input type="text" name="startDate" class="form-control" data-required data-warning="시작 날짜를 입력하여 주십시오." placeholder="시작 날짜"/>
</div>
</div>
<div class="col-auto">
<span>~</span>
</div>
<div class="col-md-3">
<div class="input-group">
<span class="input-group-text"><i class="bi bi-calendar"></i></span>
<input type="text" name="endDate" class="form-control" data-required data-warning="종료 날짜를 입력하여 주십시오." placeholder="종료 날짜"/>
</div>
</div>
<div class="col-auto">
<button type="button" id="btn_month" class="btn btn-outline-secondary btn-date-range">
<i class="bi bi-calendar-month"></i> 한달
</button>
<button type="button" id="btn_week" class="btn btn-outline-secondary btn-date-range">
<i class="bi bi-calendar-week"></i> 한주
</button>
<button type="button" id="btn_today" class="btn btn-outline-secondary btn-date-range">
<i class="bi bi-calendar-day"></i> 금일
</button>
</div>
<div class="col-auto">
<button type="button" id="btn_search" class="btn btn-primary">
<i class="bi bi-search"></i> 조회
</button>
</div>
</div>
</div>
<div id="wrapper"></div>
</div>
</div>
</body>
</html>
@@ -0,0 +1,288 @@
<%@ page language="java" contentType="text/html; charset=utf-8"%>
<%@ page import="java.io.*"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib uri="http://www.springframework.org/tags" prefix="spring"%>
<%@ include file="/jsp/common/include/localemessage.jsp" %>
<%
response.setHeader("Pragma", "No-cache");
response.setHeader("Cache-Control", "no-cache");
response.setHeader("Expires", "0");
%>
<!DOCTYPE html>
<html>
<head>
<title>일별 API 통계 목록</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<jsp:include page="/jsp/common/include/css.jsp"/>
<jsp:include page="/jsp/common/include/script.jsp"/>
<jsp:include page="/jsp/common/include/portal.jsp"/>
<script language="javascript">
var url = '<c:url value="/onl/apim/portalstatistics/portalStatisticsDailyApiTableMan.json" />';
var url_view = '<c:url value="/onl/apim/portalstatistics/portalStatisticsDailyApiTableMan.view" />';
var grid;
$(document).ready(function() {
// Datepicker 초기화
$("input[name=startDate], input[name=endDate]").datepicker({
format: "yyyy-mm-dd",
autoclose: true,
todayHighlight: true,
language: "ko"
});
function setActiveDateRangeButton() {
var startDate = $("input[name=startDate]").datepicker('getDate');
var endDate = $("input[name=endDate]").datepicker('getDate');
var diffDays = Math.floor((endDate - startDate) / (1000 * 60 * 60 * 24));
$('.btn-date-range').removeClass('active');
if (diffDays === 30) {
$('#btn_month').addClass('active');
} else if (diffDays === 7) {
$('#btn_week').addClass('active');
}
}
function setDateRange(days) {
var now = new Date();
var endDate = now;
var startDate = new Date(now.getFullYear(), now.getMonth(), now.getDate() - days);
$("input[name=startDate]").datepicker('setDate', startDate);
$("input[name=endDate]").datepicker('setDate', endDate);
setActiveDateRangeButton();
}
$("#btn_month").click(function() {
setDateRange(30);
loadData();
});
$("#btn_week").click(function() {
setDateRange(7);
loadData();
});
setDateRange(30);
function initGrid(data) {
if (grid) {
grid.destroy();
}
var columns = [
{ id: 'apiName', name: 'API 명', sort: true,
formatter: (cell) => gridjs.html('<b>'+cell+'</b>'),
width: '150px' // Set a fixed width for the name column
}
];
var dates = Object.keys(data[0]).filter(key => key !== 'apiName');
dates.forEach(date => {
columns.push({
id: date,
name: date,
sort: true,
formatter: (cell) => {
if (cell === undefined || cell === null) {
return '0';
}
return gridjs.html('<span style="color: #0a53be;">'+cell.toLocaleString()+'</span>');
},
width: '100px' // Set a fixed minimum width
});
});
grid = new gridjs.Grid({
columns: columns,
data: data,
sort: true,
pagination: {
limit: 10
},
search: true,
style: {
table: {
border: '3px solid #ccc'
},
th: {
'background-color': 'rgba(0, 0, 0, 0.1)',
color: '#000',
'border-bottom': '3px solid #ccc',
'text-align': 'center'
},
td: {
'text-align': 'center'
}
}
}).render(document.getElementById('wrapper'));
addExportButton(grid);
}
function updateSummary(summary) {
$("#totalApis").text(summary.totalApis);
$("#monthlyRequests").text(summary.monthlyRequests.toLocaleString());
$("#weeklyRequests").text(summary.weeklyRequests.toLocaleString());
$("#dailyRequests").text(summary.dailyRequests.toLocaleString());
$("#topApis").html(summary.topApis.join("<br>"));
}
function loadData() {
var startDate = $("input[name=startDate]").val().replace(/-/g, '');
var endDate = $("input[name=endDate]").val().replace(/-/g, '');
var appId = $("select[name=appSelect]").val();
$.ajax({
url: url,
type: "POST",
data: {
cmd: "LIST",
startDate: startDate,
endDate: endDate,
appId: appId === "all" ? null : appId
},
success: function(response) {
updateSummary(response.summary);
initGrid(response.dailyStats);
},
error: function(xhr, status, error) {
console.error("Error fetching data:", error);
alert("데이터를 불러오는 중 오류가 발생했습니다.");
}
});
}
$("#btn_search").click(function (){
setActiveDateRangeButton();
loadData();
});
// 초기 콤보박스 데이터 로드
$.ajax({
url: url,
type: "POST",
data: { cmd: "LIST_INIT_COMBO" },
success: function(response) {
var appSelect = $("select[name=appSelect]");
appSelect.empty();
appSelect.append($("<option>").val("all").text("전체"));
response.appList.forEach(function(app) {
appSelect.append($("<option>").val(app.appId).text(app.appName));
});
appSelect.select2({
theme: 'bootstrap'
});
},
error: function(xhr, status, error) {
console.error("Error loading combo data:", error);
alert("콤보박스 데이터를 불러오는 중 오류가 발생했습니다.");
}
});
loadData(); // 초기 데이터 로드
});
</script>
</head>
<body>
<div class="right_box">
<div class="content_top">
<ul class="path">
<li><a href="#">${rmsMenuPath}</a></li>
</ul>
</div>
<div class="content_middle" id="content_middle">
<h2 class="mb-4">일자 별 API 통계 목록</h2>
<div class="row mb-4">
<div class="col-md-4 mb-3">
<div class="card text-center h-100">
<div class="card-body">
<i class="bi bi-hdd-stack card-icon text-primary"></i>
<h5 class="card-title">이용 API</h5>
<p class="card-text">
<span id="totalApis">0</span> 건
</p>
</div>
</div>
</div>
<div class="col-md-4 mb-3">
<div class="card text-center h-100">
<div class="card-body">
<i class="bi bi-graph-up card-icon text-success"></i>
<h5 class="card-title">API 사용량</h5>
<div class="row">
<div class="col-sm-4">
<p class="card-text"><span id="monthlyRequests">0</span></p>
<p class="text-muted">월간</p>
</div>
<div class="col-sm-4">
<p class="card-text"><span id="weeklyRequests">0</span></p>
<p class="text-muted">주간</p>
</div>
<div class="col-sm-4">
<p class="card-text"><span id="dailyRequests">0</span></p>
<p class="text-muted">일간</p>
</div>
</div>
</div>
</div>
</div>
<div class="col-md-4 mb-3">
<div class="card text-center h-100">
<div class="card-body">
<i class="bi bi-star card-icon text-warning"></i>
<h5 class="card-title">주 사용 API</h5>
<p class="text-muted" id="topApis"></p>
</div>
</div>
</div>
</div>
<div class="search-panel mb-4">
<h5 class="mb-3">검색 조건</h5>
<div class="row g-3 align-items-center">
<div class="col-md-3">
<select name="appSelect" class="form-select">
<option value="all">전체</option>
</select>
</div>
<div class="col-md-3">
<div class="input-group">
<span class="input-group-text"><i class="bi bi-calendar"></i></span>
<input type="text" name="startDate" class="form-control" data-required data-warning="시작 날짜를 입력하여 주십시오." placeholder="시작 날짜"/>
</div>
</div>
<div class="col-auto">
<span>~</span>
</div>
<div class="col-md-3">
<div class="input-group">
<span class="input-group-text"><i class="bi bi-calendar"></i></span>
<input type="text" name="endDate" class="form-control" data-required data-warning="종료 날짜를 입력하여 주십시오." placeholder="종료 날짜"/>
</div>
</div>
<div class="col-auto">
<button type="button" id="btn_month" class="btn btn-outline-secondary btn-date-range">
<i class="bi bi-calendar-month"></i> 한달
</button>
<button type="button" id="btn_week" class="btn btn-outline-secondary btn-date-range">
<i class="bi bi-calendar-week"></i> 한주
</button>
</div>
<div class="col-auto">
<button type="button" id="btn_search" class="btn btn-primary">
<i class="bi bi-search"></i> 조회
</button>
</div>
</div>
</div>
<div id="wrapper"></div>
</div>
</div>
</body>
</html>
@@ -0,0 +1,258 @@
<%@ page language="java" contentType="text/html; charset=utf-8"%>
<%@ page import="java.io.*"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib uri="http://www.springframework.org/tags" prefix="spring"%>
<%@ include file="/jsp/common/include/localemessage.jsp" %>
<%
response.setHeader("Pragma", "No-cache");
response.setHeader("Cache-Control", "no-cache");
response.setHeader("Expires", "0");
%>
<!DOCTYPE html>
<html>
<head>
<title>일별 앱 통계 목록</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<jsp:include page="/jsp/common/include/css.jsp"/>
<jsp:include page="/jsp/common/include/script.jsp"/>
<jsp:include page="/jsp/common/include/portal.jsp"/>
<script language="javascript">
var url = '<c:url value="/onl/apim/portalstatistics/portalStatisticsDailyAppTableMan.json" />';
var grid;
$(document).ready(function() {
// Datepicker 초기화
$("input[name=startDate], input[name=endDate]").datepicker({
format: "yyyy-mm-dd",
autoclose: true,
todayHighlight: true,
language: "ko"
});
function setActiveDateRangeButton() {
var startDate = $("input[name=startDate]").datepicker('getDate');
var endDate = $("input[name=endDate]").datepicker('getDate');
var diffDays = Math.floor((endDate - startDate) / (1000 * 60 * 60 * 24));
$('.btn-date-range').removeClass('active');
if (diffDays === 30) {
$('#btn_month').addClass('active');
} else if (diffDays === 7) {
$('#btn_week').addClass('active');
}
}
function setDateRange(days) {
var now = new Date();
var endDate = now;
var startDate = new Date(now.getFullYear(), now.getMonth(), now.getDate() - days);
$("input[name=startDate]").datepicker('setDate', startDate);
$("input[name=endDate]").datepicker('setDate', endDate);
setActiveDateRangeButton();
}
$("#btn_month").click(function() {
setDateRange(30);
loadData();
});
$("#btn_week").click(function() {
setDateRange(7);
loadData();
});
setDateRange(30);
function initGrid(data) {
if (grid) {
grid.destroy();
}
var columns = [
{ id: 'appName', name: 'APP 명', sort: true,
formatter: (cell) => gridjs.html('<b>'+cell+'</b>'),
width: '150px'
}
];
var dates = Object.keys(data[0]).filter(key => key !== 'appName');
dates.forEach(date => {
columns.push({
id: date,
name: date,
sort: true,
formatter: (cell) => {
if (cell === undefined || cell === null) {
return '0';
}
return gridjs.html('<span style="color: #0a53be;">'+cell.toLocaleString()+'</span>');
},
width: '100px' // Set a fixed minimum width
});
});
grid = new gridjs.Grid({
columns: columns,
data: data,
sort: true,
pagination: {
limit: 10
},
search: true,
style: {
table: {
border: '3px solid #ccc'
},
th: {
'background-color': 'rgba(0, 0, 0, 0.1)',
color: '#000',
'border-bottom': '3px solid #ccc',
'text-align': 'center'
},
td: {
'text-align': 'center'
}
}
}).render(document.getElementById('wrapper'));
addExportButton(grid);
}
function updateSummary(summary) {
$("#totalApps").text(summary.totalApps);
$("#monthlyRequests").text(summary.monthlyRequests.toLocaleString());
$("#weeklyRequests").text(summary.weeklyRequests.toLocaleString());
$("#dailyRequests").text(summary.dailyRequests.toLocaleString());
$("#topApps").html(summary.topApps.join("<br>"));
}
function loadData() {
var startDate = $("input[name=startDate]").val().replace(/-/g, '');
var endDate = $("input[name=endDate]").val().replace(/-/g, '');
$.ajax({
url: url,
type: "POST",
data: {
cmd: "LIST",
startDate: startDate,
endDate: endDate
},
success: function(response) {
updateSummary(response.summary);
initGrid(response.dailyStats);
},
error: function(xhr, status, error) {
console.error("Error fetching data:", error);
alert("데이터를 불러오는 중 오류가 발생했습니다.");
}
});
}
$("#btn_search").click(function (){
setActiveDateRangeButton();
loadData();
});
loadData(); // 초기 데이터 로드
});
</script>
</head>
<body>
<div class="right_box">
<div class="content_top">
<ul class="path">
<li><a href="#">${rmsMenuPath}</a></li>
</ul>
</div>
<div class="content_middle" id="content_middle">
<h2 class="mb-4">일자 별 APP 통계 목록</h2>
<div class="row mb-4">
<div class="col-md-3 mb-3">
<div class="card text-center h-100">
<div class="card-body">
<i class="bi bi-window-stack card-icon text-primary"></i>
<h5 class="card-title">총 앱 수</h5>
<p class="card-text">
<span id="totalApps">0</span> 개
</p>
</div>
</div>
</div>
<div class="col-md-5 mb-3">
<div class="card text-center h-100">
<div class="card-body">
<i class="bi bi-graph-up card-icon text-success"></i>
<h5 class="card-title">앱 사용량</h5>
<div class="row">
<div class="col-sm-4">
<p class="card-text"><span id="monthlyRequests">0</span></p>
<p class="text-muted">월간</p>
</div>
<div class="col-sm-4">
<p class="card-text"><span id="weeklyRequests">0</span></p>
<p class="text-muted">주간</p>
</div>
<div class="col-sm-4">
<p class="card-text"><span id="dailyRequests">0</span></p>
<p class="text-muted">일간</p>
</div>
</div>
</div>
</div>
</div>
<div class="col-md-4 mb-3">
<div class="card text-center h-100">
<div class="card-body">
<i class="bi bi-star card-icon text-warning"></i>
<h5 class="card-title">주 사용 앱</h5>
<p class="text-muted" id="topApps"></p>
</div>
</div>
</div>
</div>
<div class="search-panel mb-4">
<h5 class="mb-3">검색 조건</h5>
<div class="row g-3 align-items-center">
<div class="col-md-3">
<div class="input-group">
<span class="input-group-text"><i class="bi bi-calendar"></i></span>
<input type="text" name="startDate" class="form-control" data-required data-warning="시작 날짜를 입력하여 주십시오." placeholder="시작 날짜"/>
</div>
</div>
<div class="col-auto">
<span>~</span>
</div>
<div class="col-md-3">
<div class="input-group">
<span class="input-group-text"><i class="bi bi-calendar"></i></span>
<input type="text" name="endDate" class="form-control" data-required data-warning="종료 날짜를 입력하여 주십시오." placeholder="종료 날짜"/>
</div>
</div>
<div class="col-auto">
<button type="button" id="btn_month" class="btn btn-outline-secondary btn-date-range">
<i class="bi bi-calendar-month"></i> 한달
</button>
<button type="button" id="btn_week" class="btn btn-outline-secondary btn-date-range">
<i class="bi bi-calendar-week"></i> 한주
</button>
</div>
<div class="col-auto">
<button type="button" id="btn_search" class="btn btn-primary">
<i class="bi bi-search"></i> 조회
</button>
</div>
</div>
</div>
<div id="wrapper"></div>
</div>
</div>
</body>
</html>
@@ -0,0 +1,308 @@
<%@ page language="java" contentType="text/html; charset=utf-8"%>
<%@ page import="java.io.*"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib uri="http://www.springframework.org/tags" prefix="spring"%>
<%@ include file="/jsp/common/include/localemessage.jsp" %>
<%
response.setHeader("Pragma", "No-cache");
response.setHeader("Cache-Control", "no-cache");
response.setHeader("Expires", "0");
%>
<!DOCTYPE html>
<html>
<head>
<title>API 통계</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<jsp:include page="/jsp/common/include/css.jsp"/>
<style>
.chart-container {
display: flex;
justify-content: space-between;
}
.chart {
width: 48%;
height: 500px;
}
.filter-container {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20px;
}
.select-group {
display: flex;
gap: 10px;
}
.date-group {
display: flex;
gap: 10px;
}
.date-picker {
width: 120px;
}
</style>
</head>
<body>
<div class="right_box">
<div class="content_top">
<ul class="path">
<li><a href="#">${rmsMenuPath}</a></li>
</ul>
</div>
<div class="content_middle" id="content_middle">
<div class="title">API 통계</div>
<%--<div class="filter-container">
<div class="select-group">
<div class="select-style">
<select name="searchOrgId">
<option value="">기관 선택</option>
<!-- 동적으로 옵션이 추가 -->
</select>
</div>
<div class="select-style">
<select name="searchAppId">
<option value="">APP 선택</option>
<option value="app1">앱1</option>
<option value="app2">앱2</option>
<option value="app3">앱3</option>
</select>
</div>
<div class="select-style">
<select name="searchApiId">
<option value="">API 선택</option>
<option value="api1">API1</option>
<option value="api2">API2</option>
<option value="api3">API3</option>
</select>
</div>
<div class="select-style">
<select name="searchTimeUnit">
<option value="">시간 단위</option>
<option value="hour">시간별</option>
<option value="day">일별</option>
<option value="month">월별</option>
</select>
</div>
</div>
<div class="date-group">
<input type="text" name="searchStartYYYYMMDD" id="startDatepicker" readonly="readonly" class="date-picker" placeholder="시작일">
<input type="text" name="searchEndYYYYMMDD" id="endDatepicker" readonly="readonly" class="date-picker" placeholder="종료일">
<button type="button" class="cssbtn" id="btn_search" level="R">
<i class="material-icons">search</i> <%= localeMessage.getString("button.search") %>
</button>
</div>
</div>--%>
<div class="chart-container">
<div id="normalChart" class="chart"></div>
<div id="errorChart" class="chart"></div>
</div>
</div>
</div>
<jsp:include page="/jsp/common/include/script.jsp"/>
<script src="<c:url value="/addon/echarts/echarts.min.js"/>"></script>
<script type="text/javascript">
var url = '<c:url value="/onl/apim/portalstatistics/portalStatisticsDailyMan.json" />';
var normalChart, errorChart;
var hours = ['00', '01', '02', '03', '04', '05', '06', '07', '08', '09', '10', '11',
'12', '13', '14', '15', '16', '17', '18', '19', '20', '21', '22', '23'];
var todayNormal = new Array(24).fill(0);
var todayError = new Array(24).fill(0);
var yesterdayNormal = new Array(24).fill(0);
var yesterdayError = new Array(24).fill(0);
function initializeCharts() {
normalChart = echarts.init(document.getElementById('normalChart'));
errorChart = echarts.init(document.getElementById('errorChart'));
var normalOption = {
title: { text: '정상 호출 통계' },
tooltip: {
trigger: 'axis',
axisPointer: { type: 'cross', label: { backgroundColor: '#6a7985' } }
},
legend: { data: ['금일 정상', '전일 정상'] },
toolbox: { feature: { saveAsImage: {} } },
grid: { left: '3%', right: '4%', bottom: '3%', containLabel: true },
xAxis: [{ type: 'category', boundaryGap: false, data: hours }],
yAxis: [{ ype: 'value', minInterval: 1 }],// 최소 간격을 1로 설정
series: [
{
name: '전일 정상',
type: 'line',
showSymbol: false,
itemStyle: { color: '#b9bcc4' },
lineStyle: { width: 2 },
areaStyle: { color: '#b9bcc4', opacity: 0.08 },
data: yesterdayNormal
},
{
name: '금일 정상',
type: 'line',
showSymbol: false,
itemStyle: { color: '#5470C6' },
lineStyle: { width: 3 },
areaStyle: { color: '#5470C6', opacity: 0.5 },
data: todayNormal
}
]
};
var errorOption = {
title: { text: '오류 호출 통계' },
tooltip: {
trigger: 'axis',
axisPointer: { type: 'cross', label: { backgroundColor: '#6a7985' } }
},
legend: { data: ['금일 오류', '전일 오류'] },
toolbox: { feature: { saveAsImage: {} } },
grid: { left: '3%', right: '4%', bottom: '3%', containLabel: true },
xAxis: [{ type: 'category', boundaryGap: false, data: hours }],
yAxis: [{ type: 'value', minInterval: 1 }],
series: [
{
name: '전일 오류',
type: 'line',
showSymbol: false,
itemStyle: { color: '#b9bcc4' },
lineStyle: { width: 2 },
areaStyle: { color: '#b9bcc4', opacity: 0.08 },
data: yesterdayError
},
{
name: '금일 오류',
type: 'line',
showSymbol: false,
itemStyle: { color: '#EE6666' },
lineStyle: { width: 3 },
areaStyle: { color: '#EE6666', opacity: 0.5 },
data: todayError
}
]
};
normalChart.setOption(normalOption);
errorChart.setOption(errorOption);
}
function updateCharts() {
normalChart.setOption({
series: [
{ data: yesterdayNormal },
{ data: todayNormal }
]
});
errorChart.setOption({
series: [
{ data: yesterdayError },
{ data: todayError }
]
});
}
function fetchData(startDate, endDate) {
$.ajax({
url: url,
type: 'POST',
data: {
cmd: 'LIST',
startDate: startDate,
endDate: endDate,
serviceType: 'APIGW'
},
success: function(response) {
console.log(response);
// 데이터 초기화
todayNormal = new Array(24).fill(0);
todayError = new Array(24).fill(0);
yesterdayNormal = new Array(24).fill(0);
yesterdayError = new Array(24).fill(0);
// 응답 데이터 처리
if (response.today) {
response.today.forEach(function(item) {
var hour = parseInt(item.statisticsTime.substring(8, 10));
todayNormal[hour] = item.requestCount;
todayError[hour] = item.failureCount;
});
}
if (response.yesterday) {
response.yesterday.forEach(function(item) {
var hour = parseInt(item.statisticsTime.substring(8, 10));
yesterdayNormal[hour] = item.requestCount;
yesterdayError[hour] = item.failureCount;
});
}
updateCharts();
},
error: function(xhr, status, error) {
console.error('Error fetching data:', error);
}
});
}
function getPreviousDay(date) {
var d = new Date(date.substring(0, 4) + "-" + date.substring(4, 6) + "-" + date.substring(6, 8));
d.setDate(d.getDate() - 1);
return d.toISOString().split('T')[0].replace(/-/g, "");
}
function initCombo() {
$.ajax({
url: url,
type: 'POST',
data: {
cmd: 'LIST_INIT_COMBO'
},
success: function(response) {
var orgList = response.orgList;
var selectOrg = $("select[name=searchOrgId]");
selectOrg.empty().append($('<option>').val('').text('기관 선택'));
$.each(orgList, function(i, item) {
selectOrg.append($('<option>').val(item.CODE).text(item.NAME));
});
},
error: function(xhr, status, error) {
console.error('Error initializing combo boxes:', error);
}
});
}
$(document).ready(function() {
$("input[name=searchStartYYYYMMDD],input[name=searchEndYYYYMMDD]").inputmask("yyyy-mm-dd",{'autoUnmask':true});
initializeCharts();
initCombo();
$("#startDatepicker").datepicker({
dateFormat: 'yy-mm-dd'
});
$("#endDatepicker").datepicker({
dateFormat: 'yy-mm-dd'
});
$("#btn_search").click(function(){
var start = $("input[name=searchStartYYYYMMDD]").val().replace(/-/g, "");
var end = $("input[name=searchEndYYYYMMDD]").val().replace(/-/g, "");
if(start > end){
alert("조회기간을 확인해주세요.");
return false;
}
fetchData(start, end);
});
var today = new Date().toISOString().split('T')[0].replace(/-/g, "");
$('#startDatepicker').val(today);
$('#endDatepicker').val(today);
fetchData(today, today);
});
</script>
</body>
</html>
@@ -0,0 +1,263 @@
<%@ page language="java" contentType="text/html; charset=utf-8"%>
<%@ page import="java.io.*"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib uri="http://www.springframework.org/tags" prefix="spring"%>
<%@ include file="/jsp/common/include/localemessage.jsp" %>
<%
response.setHeader("Pragma", "No-cache");
response.setHeader("Cache-Control", "no-cache");
response.setHeader("Expires", "0");
%>
<!DOCTYPE html>
<html>
<head>
<title>일별 기관 통계 목록</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<jsp:include page="/jsp/common/include/css.jsp"/>
<jsp:include page="/jsp/common/include/script.jsp"/>
<jsp:include page="/jsp/common/include/portal.jsp"/>
<script language="javascript">
var url = '<c:url value="/onl/apim/portalstatistics/portalStatisticsDailyOrgTableMan.json" />';
var grid;
$(document).ready(function() {
// Datepicker 초기화
$("input[name=startDate], input[name=endDate]").datepicker({
format: "yyyy-mm-dd",
autoclose: true,
todayHighlight: true,
language: "ko"
});
function setActiveDateRangeButton() {
var startDate = $("input[name=startDate]").datepicker('getDate');
var endDate = $("input[name=endDate]").datepicker('getDate');
var diffDays = Math.floor((endDate - startDate) / (1000 * 60 * 60 * 24));
$('.btn-date-range').removeClass('active');
if (diffDays === 30) {
$('#btn_month').addClass('active');
} else if (diffDays === 7) {
$('#btn_week').addClass('active');
}
}
function setDateRange(days) {
var now = new Date();
var endDate = now;
var startDate = new Date(now.getFullYear(), now.getMonth(), now.getDate() - days);
$("input[name=startDate]").datepicker('setDate', startDate);
$("input[name=endDate]").datepicker('setDate', endDate);
setActiveDateRangeButton();
}
$("#btn_month").click(function() {
setDateRange(30);
loadData();
});
$("#btn_week").click(function() {
setDateRange(7);
loadData();
});
$("#btn_today").click(function() {
setDateRange(0);
loadData();
});
setDateRange(30);
function initGrid(data) {
if (grid) {
grid.destroy();
}
var columns = [
{ id: 'orgName', name: '법인명', sort: true,
formatter: (cell) => gridjs.html('<b>'+cell+'</b>'),
width: '150px'
}
];
var dates = Object.keys(data[0]).filter(key => key !== 'orgName');
dates.forEach(date => {
columns.push({
id: date,
name: date,
sort: true,
formatter: (cell) => {
if (cell === undefined || cell === null) {
return '0';
}
return gridjs.html('<span style="color: #0a53be;">'+cell.toLocaleString()+'</span>');
},
width: '100px' // Set a fixed minimum width
});
});
grid = new gridjs.Grid({
columns: columns,
data: data,
sort: true,
pagination: {
limit: 10
},
search: true,
style: {
table: {
border: '3px solid #ccc'
},
th: {
'background-color': 'rgba(0, 0, 0, 0.1)',
color: '#000',
'border-bottom': '3px solid #ccc',
'text-align': 'center'
},
td: {
'text-align': 'center'
}
}
}).render(document.getElementById('wrapper'));
addExportButton(grid);
}
function updateSummary(summary) {
$("#totalOrgs").text(summary.totalOrgs);
$("#monthlyRequests").text(summary.monthlyRequests.toLocaleString());
$("#weeklyRequests").text(summary.weeklyRequests.toLocaleString());
$("#dailyRequests").text(summary.dailyRequests.toLocaleString());
$("#topOrgs").html(summary.topOrgs.join("<br>"));
}
function loadData() {
var startDate = $("input[name=startDate]").val().replace(/-/g, '');
var endDate = $("input[name=endDate]").val().replace(/-/g, '');
$.ajax({
url: url,
type: "POST",
data: {
cmd: "LIST",
startDate: startDate,
endDate: endDate
},
success: function(response) {
updateSummary(response.summary);
initGrid(response.dailyStats);
},
error: function(xhr, status, error) {
console.error("Error fetching data:", error);
alert("데이터를 불러오는 중 오류가 발생했습니다.");
}
});
}
$("#btn_search").click(function (){
setActiveDateRangeButton();
loadData();
});
loadData(); // 초기 데이터 로드
});
</script>
</head>
<body>
<div class="right_box">
<div class="content_top">
<ul class="path">
<li><a href="#">${rmsMenuPath}</a></li>
</ul>
</div>
<div class="content_middle" id="content_middle">
<h2 class="mb-4">일자별 법인 통계 목록</h2>
<div class="row mb-4">
<div class="col-md-3 mb-3">
<div class="card text-center h-100">
<div class="card-body">
<i class="bi bi-building card-icon text-primary"></i>
<h5 class="card-title">총 법인 수</h5>
<p class="card-text">
<span id="totalOrgs">0</span> 개
</p>
</div>
</div>
</div>
<div class="col-md-5 mb-3">
<div class="card text-center h-100">
<div class="card-body">
<i class="bi bi-graph-up card-icon text-success"></i>
<h5 class="card-title">법인 사용량</h5>
<div class="row">
<div class="col-sm-4">
<p class="card-text"><span id="monthlyRequests">0</span></p>
<p class="text-muted">월간</p>
</div>
<div class="col-sm-4">
<p class="card-text"><span id="weeklyRequests">0</span></p>
<p class="text-muted">주간</p>
</div>
<div class="col-sm-4">
<p class="card-text"><span id="dailyRequests">0</span></p>
<p class="text-muted">일간</p>
</div>
</div>
</div>
</div>
</div>
<div class="col-md-4 mb-3">
<div class="card text-center h-100">
<div class="card-body">
<i class="bi bi-star card-icon text-warning"></i>
<h5 class="card-title">주 사용 법인</h5>
<p class="text-muted" id="topOrgs"></p>
</div>
</div>
</div>
</div>
<div class="search-panel mb-4">
<h5 class="mb-3">검색 조건</h5>
<div class="row g-3 align-items-center">
<div class="col-md-3">
<div class="input-group">
<span class="input-group-text"><i class="bi bi-calendar"></i></span>
<input type="text" name="startDate" class="form-control" data-required data-warning="시작 날짜를 입력하여 주십시오." placeholder="시작 날짜"/>
</div>
</div>
<div class="col-auto">
<span>~</span>
</div>
<div class="col-md-3">
<div class="input-group">
<span class="input-group-text"><i class="bi bi-calendar"></i></span>
<input type="text" name="endDate" class="form-control" data-required data-warning="종료 날짜를 입력하여 주십시오." placeholder="종료 날짜"/>
</div>
</div>
<div class="col-auto">
<button type="button" id="btn_month" class="btn btn-outline-secondary btn-date-range">
<i class="bi bi-calendar-month"></i> 한달
</button>
<button type="button" id="btn_week" class="btn btn-outline-secondary btn-date-range">
<i class="bi bi-calendar-week"></i> 한주
</button>
</div>
<div class="col-auto">
<button type="button" id="btn_search" class="btn btn-primary">
<i class="bi bi-search"></i> 조회
</button>
</div>
</div>
</div>
<div id="wrapper"></div>
</div>
</div>
</body>
</html>
@@ -0,0 +1,170 @@
<%@ page language="java" contentType="text/html; charset=utf-8"%>
<%@ page import="java.io.*"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib uri="http://www.springframework.org/tags" prefix="spring"%>
<%@ include file="/jsp/common/include/localemessage.jsp" %>
<%
response.setHeader("Pragma", "No-cache");
response.setHeader("Cache-Control", "no-cache");
response.setHeader("Expires", "0");
%>
<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<jsp:include page="/jsp/common/include/css.jsp"/>
<jsp:include page="/jsp/common/include/script.jsp"/>
<script language="javascript">
var url = '<c:url value="/onl/apim/portalstatistics/portalStatisticsMan.json" />';
var url_view = '<c:url value="/onl/apim/portalstatistics/portalStatisticsMan.view" />';
$(document).ready(function() {
$("input[name=startDate], input[name=endDate]").inputmask("9999-99-99 99:99", {'autoUnmask': true});
var typingTimer;
var doneTypingInterval = 500; // 1초
$("input[name=startDate]").on('input', function() {
clearTimeout(typingTimer);
typingTimer = setTimeout(function() {
updateEndTime();
}, doneTypingInterval);
});
function updateEndTime() {
var startDateStr = $("input[name=startDate]").val();
if (isValidDateTimeFormat(startDateStr)) {
var startDate = parseDate(startDateStr);
var endDate = new Date(startDate.getTime() + 10 * 60000); // 10분 추가
var endDateStr = formatDate(endDate);
$("input[name=endDate]").val(endDateStr);
}
}
function isValidDateTimeFormat(dateStr) {
return /^\d{12}$/.test(dateStr);
}
function parseDate(dateStr) {
var year = parseInt(dateStr.substr(0, 4));
var month = parseInt(dateStr.substr(4, 2)) - 1; // JavaScript의 월은 0-11
var day = parseInt(dateStr.substr(6, 2));
var hour = parseInt(dateStr.substr(8, 2));
var minute = parseInt(dateStr.substr(10, 2));
return new Date(year, month, day, hour, minute);
}
function formatDate(date) {
return date.getFullYear() +
String(date.getMonth() + 1).padStart(2, '0') +
String(date.getDate()).padStart(2, '0') +
String(date.getHours()).padStart(2, '0') +
String(date.getMinutes()).padStart(2, '0');
}
function setCurrentTime() {
var now = new Date();
var year = now.getFullYear();
var month = String(now.getMonth() + 1).padStart(2, '0');
var day = String(now.getDate()).padStart(2, '0');
var hour = String(now.getHours()).padStart(2, '0');
var minute = String(Math.floor(now.getMinutes() / 10) * 10).padStart(2, '0');
var startDate = year + '-' + month + '-' + day + ' ' + hour + ':' + minute;
$("input[name=startDate]").val(startDate);
// 시작 시간을 Date 객체로 변환
var startDateTime = new Date(year, month - 1, day, hour, minute);
// 10분을 추가
var endDateTime = new Date(startDateTime.getTime() + 10 * 60000);
var endYear = endDateTime.getFullYear();
var endMonth = String(endDateTime.getMonth() + 1).padStart(2, '0');
var endDay = String(endDateTime.getDate()).padStart(2, '0');
var endHour = String(endDateTime.getHours()).padStart(2, '0');
var endMinute = String(endDateTime.getMinutes()).padStart(2, '0');
var endDateStr = endYear + '-' + endMonth + '-' + endDay + ' ' + endHour + ':' + endMinute;
$("input[name=endDate]").val(endDateStr);
}
$("#btn_current").click(function() {
setCurrentTime();
});
setCurrentTime(); // 초기 로드 시 현재 시간 설정
$("#btn_new").click(function(){
var startDate = $("input[name=startDate]").val().replace(/[^0-9]/g, '').slice(0, 12);
var postData = {
cmd: "INSERT",
startDate: startDate
};
$.ajax({
type: "POST",
url: url,
data: postData,
success: function(response) {
if (response.success) {
if (response.dataExists) {
alert(response.message + " 저장된 데이터 수: " + response.count);
} else {
alert(response.message);
}
} else {
alert("처리 중 오류가 발생했습니다: " + response.message);
}
},
error: function(e){
alert("서버 통신 오류: " + e.responseText);
}
});
});
$("input[name^=search]").keydown(function(key){
if (key.keyCode == 13){
$("#btn_new").click();
}
});
buttonControl();
});
</script>
</head>
<body>
<div class="right_box">
<div class="content_top">
<ul class="path">
<li><a href="#">${rmsMenuPath}</a></li>
</ul>
</div><!-- end content_top -->
<div class="content_middle" id="content_middle">
<div class="search_wrap">
<button type="button" class="cssbtn" id="btn_new" level="W"><i class="material-icons">add</i> 등록</button>
</div>
<div class="title">로그 통계조회</div>
<table class="search_condition" cellspacing=0;>
<tbody>
<tr>
<th style="width:10%; min-width:90px;">10분 통계</th>
<td>
<input type="text" name="startDate" data-required data-warning="시작 날짜와 시간을 입력하여 주십시오." style="width:150px;"/>
~
<input type="text" name="endDate" data-required data-warning="종료 날짜와 시간을 입력하여 주십시오." style="width:150px;" disabled="disabled" />
<button type="button" id="btn_current" class="cssbtn">현재</button>
</td>
</tr>
</tbody>
</table>
<table id="grid"></table>
</div><!-- end content_middle -->
</div><!-- end right_box -->
</body>
</html>
@@ -0,0 +1,262 @@
<%@ page language="java" contentType="text/html; charset=utf-8"%>
<%@ page import="java.io.*"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib uri="http://www.springframework.org/tags" prefix="spring"%>
<%@ include file="/jsp/common/include/localemessage.jsp" %>
<%
response.setHeader("Pragma", "No-cache");
response.setHeader("Cache-Control", "no-cache");
response.setHeader("Expires", "0");
%>
<!DOCTYPE html>
<html>
<head>
<title>법인별 통계 목록</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<jsp:include page="/jsp/common/include/css.jsp"/>
<jsp:include page="/jsp/common/include/script.jsp"/>
<jsp:include page="/jsp/common/include/portal.jsp"/>
<script language="javascript">
var url = '<c:url value="/onl/apim/portalstatistics/portalStatisticsOrgTableMan.json" />';
var grid;
$(document).ready(function() {
// Datepicker 초기화
$("input[name=startDate], input[name=endDate]").datepicker({
format: "yyyy-mm-dd",
autoclose: true,
todayHighlight: true,
language: "ko"
});
function setActiveDateRangeButton() {
var startDate = $("input[name=startDate]").datepicker('getDate');
var endDate = $("input[name=endDate]").datepicker('getDate');
var diffDays = Math.floor((endDate - startDate) / (1000 * 60 * 60 * 24));
$('.btn-date-range').removeClass('active');
if (diffDays === 30) {
$('#btn_month').addClass('active');
} else if (diffDays === 7) {
$('#btn_week').addClass('active');
} else if (diffDays === 0) {
$('#btn_today').addClass('active');
}
}
function setDateRange(days) {
var now = new Date();
var endDate = now;
var startDate = new Date(now.getFullYear(), now.getMonth(), now.getDate() - days);
$("input[name=startDate]").datepicker('setDate', startDate);
$("input[name=endDate]").datepicker('setDate', endDate);
setActiveDateRangeButton();
}
$("#btn_month").click(function() {
setDateRange(30);
loadData();
});
$("#btn_week").click(function() {
setDateRange(7);
loadData();
});
$("#btn_today").click(function() {
setDateRange(0);
loadData();
});
setDateRange(0);
function initGrid(data) {
if (grid) {
grid.destroy();
}
var columns = [
{ id: 'orgName', name: '법인명', sort: true,
formatter: (cell) => gridjs.html('<b>'+cell+'</b>')
},
{ id: 'totalRequests', name: '총 요청 수', sort: true,
formatter: (cell) => gridjs.html('<span style="color: #0a53be;">'+cell+'</span>')
},
{ id: 'totalFailures', name: '오류 건수', sort: true,
formatter: (cell) => gridjs.html('<span style="color: #dc3545;">'+cell+'</span>')
},
{ id: 'successRate', name: '성공 률 (%)', sort: true,
formatter: (cell) => gridjs.html('<span style="color: #198754;">'+cell+'%</span>')
}
];
grid = new gridjs.Grid({
columns: columns,
data: data,
sort: true,
pagination: {
limit: 10
},
search: true,
style: {
table: {
border: '3px solid #ccc'
},
th: {
'background-color': 'rgba(0, 0, 0, 0.1)',
color: '#000',
'border-bottom': '3px solid #ccc',
'text-align': 'center'
},
td: {
'text-align': 'center'
}
}
}).render(document.getElementById('wrapper'));
addExportButton(grid);
}
function updateSummary(summary) {
$("#totalOrgs").text(summary.totalOrgs);
$("#totalRequests").text(summary.totalRequests.toLocaleString());
$("#totalFailures").text(summary.totalFailures.toLocaleString());
$("#overallSuccessRate").text(summary.overallSuccessRate.toFixed(2));
}
function loadData() {
var startDate = $("input[name=startDate]").val().replace(/-/g, '');
var endDate = $("input[name=endDate]").val().replace(/-/g, '');
$.ajax({
url: url,
type: "POST",
data: {
cmd: "LIST",
startDate: startDate,
endDate: endDate
},
success: function(response) {
updateSummary(response.summary);
initGrid(response.orgStats);
},
error: function(xhr, status, error) {
console.error("Error fetching data:", error);
alert("데이터를 불러오는 중 오류가 발생했습니다.");
}
});
}
$("#btn_search").click(function (){
setActiveDateRangeButton();
loadData();
});
loadData(); // 초기 데이터 로드
});
</script>
</head>
<body>
<div class="right_box">
<div class="content_top">
<ul class="path">
<li><a href="#">${rmsMenuPath}</a></li>
</ul>
</div>
<div class="content_middle" id="content_middle">
<h2 class="mb-4">법인별 통계 목록</h2>
<div class="row mb-4">
<div class="col-md-3 mb-3">
<div class="card text-center h-100">
<div class="card-body">
<i class="bi bi-building card-icon text-primary"></i>
<h5 class="card-title">총 법인 수</h5>
<p class="card-text">
<span id="totalOrgs">0</span> 개
</p>
</div>
</div>
</div>
<div class="col-md-3 mb-3">
<div class="card text-center h-100">
<div class="card-body">
<i class="bi bi-arrow-repeat card-icon text-success"></i>
<h5 class="card-title">총 요청 수</h5>
<p class="card-text">
<span id="totalRequests">0</span>
</p>
</div>
</div>
</div>
<div class="col-md-3 mb-3">
<div class="card text-center h-100">
<div class="card-body">
<i class="bi bi-exclamation-triangle card-icon text-danger"></i>
<h5 class="card-title">총 실패 수</h5>
<p class="card-text">
<span id="totalFailures">0</span>
</p>
</div>
</div>
</div>
<div class="col-md-3 mb-3">
<div class="card text-center h-100">
<div class="card-body">
<i class="bi bi-graph-up card-icon text-info"></i>
<h5 class="card-title">전체 성공률</h5>
<p class="card-text">
<span id="overallSuccessRate">0</span>%
</p>
</div>
</div>
</div>
</div>
<div class="search-panel mb-4">
<h5 class="mb-3">검색 조건</h5>
<div class="row g-3 align-items-center">
<div class="col-md-3">
<div class="input-group">
<span class="input-group-text"><i class="bi bi-calendar"></i></span>
<input type="text" name="startDate" class="form-control" data-required data-warning="시작 날짜를 입력하여 주십시오." placeholder="시작 날짜"/>
</div>
</div>
<div class="col-auto">
<span>~</span>
</div>
<div class="col-md-3">
<div class="input-group">
<span class="input-group-text"><i class="bi bi-calendar"></i></span>
<input type="text" name="endDate" class="form-control" data-required data-warning="종료 날짜를 입력하여 주십시오." placeholder="종료 날짜"/>
</div>
</div>
<div class="col-auto">
<button type="button" id="btn_month" class="btn btn-outline-secondary btn-date-range">
<i class="bi bi-calendar-month"></i> 한달
</button>
<button type="button" id="btn_week" class="btn btn-outline-secondary btn-date-range">
<i class="bi bi-calendar-week"></i> 한주
</button>
<button type="button" id="btn_today" class="btn btn-outline-secondary btn-date-range">
<i class="bi bi-calendar-day"></i> 금일
</button>
</div>
<div class="col-auto">
<button type="button" id="btn_search" class="btn btn-primary">
<i class="bi bi-search"></i> 조회
</button>
</div>
</div>
</div>
<div id="wrapper"></div>
</div>
</div>
</body>
</html>
@@ -0,0 +1,172 @@
<%@ page language="java" contentType="text/html; charset=utf-8"%>
<%@ page import="java.io.*"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib uri="http://www.springframework.org/tags" prefix="spring"%>
<%@ include file="/jsp/common/include/localemessage.jsp" %>
<%
response.setHeader("Pragma", "No-cache");
response.setHeader("Cache-Control", "no-cache");
response.setHeader("Expires", "0");
%>
<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<jsp:include page="/jsp/common/include/css.jsp"/>
<jsp:include page="/jsp/common/include/script.jsp"/>
<script language="javascript" >
var url = '<c:url value="/onl/apim/portalterms/portalTermsMan.json" />';
var url_view = '<c:url value="/onl/apim/portalterms/portalTermsMan.view" />';
function init() {
$.ajax({
type: "POST",
url: url,
dataType: "json",
data: {cmd: 'LIST_INIT_COMBO'},
success: function(json) {
const comboConfigs = [
{name: 'searchAgreementsType', data: json.termsTypeRows}
];
comboConfigs.forEach(function(config) {
new makeOptions("CODE", "NAME")
.setObj($("select[name=" + config.name + "]"))
.setNoValueInclude(true)
.setNoValue("", "<%=localeMessage.getString("combo.all")%>")
.setData(config.data)
.setFormat(nameOptionFormat)
.rendering();
});
select_termsType = getGridSelectText("CODE", "NAME", json.termsTypeRows);
}
});
}
$(document).ready(function() {
init();
$('#grid').jqGrid({
datatype:"json",
mtype: 'POST',
url: url,
postData : { cmd : 'LIST',
searchAgreementsType: $('select[name=searchAgreementsType]').val()},
colNames:['No.', '약관타입', '종류', '버전', '약관시행일', '등록일', '등록자', '약관 수정일', '수정 등록자'],
colModel:[
{ name : 'rowNum' , align:'center', width:40 , sortable:false},
{ name : 'agreementsType' , align:'center', hidden:true},
{ name : 'name' , align:'center', width:150 },
{ name : 'revision' , align:'center', width:40 },
{ name : 'publishedOn' , align:'center', width:100, formatter: gridDateFormat },
{ name : 'createdDate' , align:'center', width:120, formatter: timeStampFormat },
{ name : 'createdByName' , align:'center', width:80 },
{ name : 'lastModifiedDate' , align:'center', width:120, formatter: timeStampFormat },
{ name : 'lastModifiedByName' , align:'center', width:80 }
],
jsonReader: {
repeatitems:false
},
pager : $('#pager'),
page : '${param.page}',
rowNum : '${rmsDefaultRowNum}',
autoheight: true,
height: $("#container").height(),
autowidth: true,
viewrecords: true,
rowList : eval('[${rmsDefaultRowList}]'),
rowId: function(obj) {
return obj.agreementsType + "_" + obj.revision;
},
loadComplete: function() {
var records = $(this).getGridParam('records');
var page = $(this).getGridParam('page');
var rowNum = $(this).getGridParam('rowNum');
var rows = $(this).getDataIDs();
var colModel = $(this).getGridParam("colModel");
for (var i = 0; i < rows.length; i++) {
var number = ((page - 1) * rowNum + i) + 1;
// var reverseNumber = records - ((page - 1) * rowNum + i);
$(this).setCell(rows[i], 'rowNum', number);
}
for(var i = 0 ; i< colModel.length; i++){
$(this).setColProp(colModel[i].name, {sortable : false});
}
},
ondblClickRow: function(rowId) {
var rowData = $(this).getRowData(rowId);
var agreementsType = rowData.agreementsType;
var revision = rowData.revision;
var url2 = url_view;
url2 += '?cmd=DETAIL';
url2 += '&page='+$(this).getGridParam("page");
url2 += '&returnUrl=' + getReturnUrl();
url2 += '&menuId='+'${param.menuId}';
url2 += '&agreementsType='+ agreementsType;
url2 += '&revision='+ revision;
goNav(url2);
},
loadError: function (jqXHR, textStatus, errorThrown) {
var location ='<%=request.getContextPath()%>/';
comloadError(jqXHR, textStatus, errorThrown ,location);
}
});
resizeJqGridWidth('grid','content_middle','1000');
// $("#btn_search").click(function(){
// var postData = getSearchForJqgrid("cmd","LIST");
// $("#grid").setGridParam({ url:url,postData: postData ,page:1 }).trigger("reloadGrid");
// });
$("select[name=searchAgreementsType]").change(function(){
var postData = getSearchForJqgrid("cmd","LIST");
$("#grid").setGridParam({ url:url, postData: postData, page:1 }).trigger("reloadGrid");
});
$("#btn_new").click(function(){
var url2 = url_view;
url2 += '?cmd=DETAIL';
url2 += '&page='+$("#grid").getGridParam("page");
url2 += '&returnUrl='+getReturnUrl();
url2 += '&menuId='+'${param.menuId}';
goNav(url2);
});
$("select[name=searchAgreementsType], input[name^=search]").keydown(function(key){
if (key.keyCode == 13){
$("#btn_search").click();
}
});
buttonControl();
});
</script>
</head>
<body>
<div class="right_box">
<div class="content_top">
<ul class="path">
<li><a href="#">${rmsMenuPath}</a></li>
</ul>
</div><!-- end content_top -->
<div class="content_middle" id="content_middle">
<div class="search_wrap">
<button type="button" class="cssbtn" id="btn_new" level="W"><i class="material-icons">add</i> <%= localeMessage.getString("button.new") %></button>
<%-- <button type="button" class="cssbtn" id="btn_search" level="R"><i class="material-icons">search</i> <%= localeMessage.getString("button.search") %></button>--%>
</div>
<div class="title">약관 목록</div>
<form id="ajaxForm" onsubmit="return false;">
<div class="select-style " style="align-items: center; margin-bottom: 20px;">
<select name="searchAgreementsType"></select>
</div>
</form>
<table id="grid" ></table>
<div id="pager"></div>
</div><!-- end content_middle -->
</div><!-- end right_box -->
</body>
</html>
@@ -0,0 +1,281 @@
<%@ page language="java" contentType="text/html; charset=utf-8"%>
<%@ page import="java.io.*"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib uri="http://www.springframework.org/tags" prefix="spring"%>
<%@ include file="/jsp/common/include/localemessage.jsp" %>
<%
response.setHeader("Pragma", "No-cache");
response.setHeader("Cache-Control", "no-cache");
response.setHeader("Expires", "0");
%>
<%!
public String getRequiredLabel(String label) {
return label + " <span class=\"required-mark\">*</span>";
}
%>
<html>
<head>
<title>이용약관 상세</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<jsp:include page="/jsp/common/include/css.jsp"/>
<jsp:include page="/jsp/common/include/script.jsp"/>
<jsp:include page="/jsp/common/include/portal.jsp"/>
<script language="javascript">
var url = '<c:url value="/onl/apim/portalterms/portalTermsMan.json" />';
var url_view = '<c:url value="/onl/apim/portalterms/portalTermsMan.view" />';
var isDetail = false;
function decodeHTMLEntities(text) {
var textArea = document.createElement('textarea');
textArea.innerHTML = text;
return textArea.value;
}
function init() {
$.ajax({
type: "POST",
url: url,
dataType: "json",
data: {cmd: 'LIST_INIT_COMBO'},
success: function(json) {
new makeOptions("CODE", "NAME")
.setObj($("select[name=agreementsType]"))
.setData(json.termsTypeRows)
.setFormat(nameOptionFormat)
.rendering();
if (isDetail && "${param.agreementsType}" && "${param.revision}") {
detail("${param.agreementsType}", "${param.revision}");
}
},
error: function(e) {
alert(e.responseText);
}
});
}
function detail(agreementsType, revision) {
if (!isDetail) {
$('#revisionHidden').val("0");
return;
}
$.ajax({
type: "POST",
url: url,
dataType: "json",
data: {cmd: 'DETAIL', agreementsType: agreementsType, revision: revision},
success: function (data) {
$("#agreementsType").val(data.agreementsType);
$("#revision").text(data.revision);
$("#revisionHidden").val(data.revision);
$("#name").val(data.name);
$("#status").val(data.status);
var decodedContent = decodeHTMLEntities(data.contents);
$('#contents').summernote('code', decodedContent);
if (data.publishedOn) {
$("#publishedOnDisplay").val(gridDateFormat(data.publishedOn));
$("#publishedOn").val(data.publishedOn);
}
if (data.status !== 'DRAFT') {
$("#publishedOnDisplay").prop('disabled', true);
}
$("#createdByName").text(data.createdByName);
$("#createdDate").text(timeStampFormat(data.createdDate));
$("#lastModifiedDate").text(timeStampFormat(data.lastModifiedDate));
$("#lastModifiedByName").text(data.lastModifiedByName);
},
error: function (e) {
alert(e.responseText);
}
});
}
$(document).ready(function() {
var returnUrl = getReturnUrlForReturn();
var agreementsType = "${param.agreementsType}";
var revision = "${param.revision}";
isDetail = agreementsType != "" && agreementsType != "null" && revision != "" && revision != "null";
if (isDetail) {
$("#title").append(" 수정");
$("#agreementsType").prop('disabled', true);
buttonControl(true);
} else {
$("#title").append(" 등록");
$("#revisionHidden").val("0");
$("#btn_modify").html('<i class="material-icons">save</i> <%= localeMessage.getString("button.register") %>');
buttonControl(false);
}
init();
$("#publishedOnDisplay").datepicker({
format: 'yyyy-mm-dd',
language: 'ko',
autoclose: true,
minDate: 0,
}).on('changeDate', function(e) {
var formattedDate = e.format('yyyymmdd') + '000000';
$("#publishedOn").val(formattedDate); // 변경된 날짜만 설정
}).on('hide', function(e) {
if (!$("#publishedOnDisplay").val()) {
$("#publishedOnDisplay").val(gridDateFormat($("#publishedOn").val()));
}
});
$('#contents').summernote({
placeholder: '여기에 답변을 입력하세요.',
height: 300,
toolbar: [
['style', ['style']],
['font', ['bold', 'underline', 'clear']],
['color', ['color']],
['para', ['ul', 'ol', 'paragraph']],
['table', ['table']],
['insert', ['link']],
['view', ['fullscreen', 'codeview', 'help']]
],
callbacks: {
onInit: function() {
$('.note-editable').on('keydown', function(e) {
if (e.keyCode === 8) {
e.stopPropagation();
}
});
}
}
});
if (agreementsType && revision) {
detail(agreementsType, revision);
}
$("#btn_modify").click(function() {
if (!checkRequired("ajaxForm")) return;
// Summernote 에디터 내용 검증
var contents = $('#contents').summernote('code');
if (contents === "" || contents === "<p><br></p>" || contents === "<p></p>") {
alert("약관 내용을 입력하여 주십시오.");
$('#contents').summernote('focus');
return;
}
if (confirm("<%= localeMessage.getString("common.checkSave")%>") != true)
return;
$("#agreementsType").prop('disabled', false);
var postData = $('#ajaxForm').serializeArray();
if (isDetail) {
postData.push({ name: "cmd", value: "UPDATE" });
} else {
postData.push({ name: "cmd", value: "INSERT" });
}
$.ajax({
type: "POST",
url: url,
data: postData,
success: function (json) {
alert("<%= localeMessage.getString("common.saveMsg") %>");
goNav(returnUrl);
},
error: function (e) {
alert(e.responseText);
}
});
});
$("#btn_delete").click(function () {
if (confirm("<%= localeMessage.getString("common.confirmMsg")%>")) {
var deleteData = {
cmd: "DELETE",
agreementsType: $("#agreementsType").val(),
revision: $("#revisionHidden").val()
};
$.ajax({
type: "POST",
url: url,
data: deleteData,
success: function (args) {
alert("<%= localeMessage.getString("common.deleteMsg") %>");
goNav(returnUrl);
},
error: function (e) {
alert(e.responseText);
}
});
}
});
$("#btn_previous").click(function() {
goNav(returnUrl);
});
});
</script>
</head>
<body>
<div class="right_box">
<div class="content_top">
<ul class="path">
<li><a href="#">${rmsMenuPath}</a></li>
</ul>
</div><!-- end content_top -->
<div class="content_middle">
<div class="search_wrap">
<button type="button" class="cssbtn" id="btn_modify" level="W" status="DETAIL,NEW"><i class="material-icons">save</i> <%= localeMessage.getString("button.modify") %></button>
<button type="button" class="cssbtn" id="btn_delete" level="W" status="DETAIL"><i class="material-icons">delete</i> <%= localeMessage.getString("button.delete") %></button>
<button type="button" class="cssbtn" id="btn_previous" level="R" status="DETAIL,NEW"><i class="material-icons">arrow_back</i> <%= localeMessage.getString("button.previous") %></button>
</div>
<div class="title" id="title">약관</div>
<form id="ajaxForm">
<input type="hidden" name="revision" id="revisionHidden">
<table class="table_row" cellspacing="0">
<tr>
<th style="width:10%;"><%= getRequiredLabel("약관명") %></th>
<td style="width:40%;" colspan="1">
<div class="select-style" >
<select type="text" id="agreementsType" name="agreementsType" style="width:100%"
data-required data-warning="약관명을 선택하여 주십시오."></select>
</div>
</td>
<th style="width:10%;">버전</th>
<td style="width:40%;" colspan="1" id="revision"></td>
</tr>
<tr>
<th>등록자</th>
<td id="createdByName"></td>
<th style="width:10%;">수정자</th>
<td id="lastModifiedByName"></td>
</tr>
<tr>
<th>등록일</th>
<td id="createdDate"></td>
<th>수정일</th>
<td id="lastModifiedDate"></td>
</tr>
<tr>
<th><%= getRequiredLabel("약관 시행일") %></th>
<td colspan="3" >
<!-- 표시용 날짜 필드 -->
<input type="text" id="publishedOnDisplay" style="width:200px;" data-required data-warning="약관시행일을 입력하여 주십시오."/>
<input type="hidden" id="publishedOn" name="publishedOn"/>
</td>
</tr>
<tr>
<th><%= getRequiredLabel("약관 내용") %></th>
<td colspan="3">
<textarea id="contents" name="contents" style="width:100%;height:300px" data-required data-warning="약관내용을 입력하여 주십시오."></textarea>
</td>
</tr>
</table>
</form>
</div>
</div>
</body>
</html>
@@ -0,0 +1,267 @@
<%@ page language="java" contentType="text/html; charset=utf-8" %>
<%@ page import="java.io.*" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib uri="http://www.springframework.org/tags" prefix="spring" %>
<%@ include file="/jsp/common/include/localemessage.jsp" %>
<%
response.setHeader("Pragma", "No-cache");
response.setHeader("Cache-Control", "no-cache");
response.setHeader("Expires", "0");
%>
<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<jsp:include page="/jsp/common/include/css.jsp"/>
<jsp:include page="/jsp/common/include/script.jsp"/>
<jsp:include page="/jsp/common/include/portal.jsp"/>
<script language="javascript">
var url = '<c:url value="/onl/apim/portaluser/portalUserMan.json" />';
var url_view = '<c:url value="/onl/apim/portaluser/portalUserMan.view" />';
var select_approvalStatus = "";
var select_userStatus = "";
function getGridSelectText(key, value, data) {
if (!Array.isArray(data) || data.length === 0) {
return "";
}
return data
.filter(item => item[key] !== undefined && item[value] !== undefined)
.map(item => String(item[key]) + ":" + String(item[value]))
.join(';');
}
function init() {
$.ajax({
type: "POST",
url: url,
dataType: "json",
data: {cmd: 'LIST_INIT_COMBO'},
success: function (json) {
const comboConfigs = [
{name: 'searchUserStatus', data: json.userStatusRows},
{name: 'searchApprovalStatus', data: json.approvalStatusRows},
{name: 'searchOrgId', data: json.orgRows},
{name: 'searchRoleCode', data: json.roleCodeRows}
];
comboConfigs.forEach(function (config) {
new makeOptions("CODE", "NAME")
.setObj($("select[name=" + config.name + "]"))
.setNoValueInclude(true)
.setNoValue("", "<%=localeMessage.getString("combo.all")%>")
.setData(config.data)
.setFormat(nameOptionFormat).rendering();
});
putSelectFromParam();
select_approvalStatus = ": ;" + getGridSelectText("CODE", "NAME", json.approvalStatusRows);
select_userStatus = ": ;" + getGridSelectText("CODE", "NAME", json.userStatusRows);
$('#grid').jqGrid('setColProp', 'approvalStatus', {editoptions: {value: select_approvalStatus}});
$('#grid').jqGrid('setColProp', 'userStatus', {editoptions: {value: select_userStatus}});
$('#grid').trigger('reloadGrid');
},
error: function (e) {
alert(e.responseText);
}
});
}
$(document).ready(function () {
var gridPostData = getSearchForJqgrid("cmd", "LIST");
$('#grid').jqGrid({
datatype: "json",
mtype: 'POST',
url: url,
postData: gridPostData,
colNames: ['No.',
'<%= localeMessage.getString("portalUser.id") %>',
'<%= localeMessage.getString("portalUser.orgName") %>',
'<%= localeMessage.getString("portalUser.name") %>',
'<%= localeMessage.getString("portalUser.userId") %>',
'<%= localeMessage.getString("portalUser.mobile") %>',
'<%= localeMessage.getString("portalUser.roleName") %>',
'<%= localeMessage.getString("portalUser.userStatus") %>',
'<%= localeMessage.getString("portalUser.createOn") %>',
'<%= localeMessage.getString("portalUser.approvalStatus") %>'
],
colModel: [
{name: 'rowNum', align: 'center', width: '30', sortable: false},
{name: 'id', align: 'center', key: true, hidden: true},
{name: 'portalOrgUIs.orgName', align: 'center', width: "120"},
{name: 'userName', align: 'center', width: "80" },
{name: 'loginId', align: 'center', width: "150" },
{name: 'mobileNumber', align: 'center', width: "100" },
{name: 'roleCodeDescription', align: 'center', width: "80"},
{name: 'userStatusDescription', align: 'center', width: "50"},
{name: 'createdDate', align: 'center', width: "100", formatter: timeStampFormat},
{name: 'approvalStatusDescription', align: 'center', width: "50"}
],
jsonReader: {
repeatitems: false
},
pager: $('#pager'),
page: '${param.page}',
rowNum: '${rmsDefaultRowNum}',
autoheight: true,
height: $("#container").height(),
autowidth: true,
viewrecords: true,
rowList: eval('[${rmsDefaultRowList}]'),
loadComplete: function (d) {
var records = $(this).getGridParam('records');
var page = $(this).getGridParam('page');
var rowNum = $(this).getGridParam('rowNum');
var rows = $(this).getDataIDs();
var colModel = $(this).getGridParam("colModel");
for (var i = 0; i < rows.length; i++) {
var number = ((page - 1) * rowNum + i) + 1;
// var reverseNumber = records - ((page - 1) * rowNum + i);
$(this).setCell(rows[i], 'rowNum', number);
}
for (var i = 0; i < colModel.length; i++) {
$(this).setColProp(colModel[i].name, {sortable: false});
}
},
ondblClickRow: function (rowId) {
var rowData = $(this).getRowData(rowId);
var key = rowData['id'];
var url2 = url_view;
url2 += '?cmd=DETAIL';
url2 += '&page=' + $(this).getGridParam("page");
url2 += '&returnUrl=' + getReturnUrl();
url2 += '&menuId=' + '${param.menuId}';
url2 += '&id=' + key;
goNav(url2);
}, loadError: function (jqXHR, textStatus, errorThrown) {
if (jqXHR.status == 401) {
var location = '<%=request.getContextPath()%>/';
comloadError(jqXHR, textStatus, errorThrown, location);
}
}
});
init();
$("#btn_search").click(function () {
//var searchMobileNumber = $("#searchMobileNumber").val().trim();
var postData = getSearchForJqgrid("cmd", "LIST");
$("#grid").setGridParam({url: url, postData: postData, page: 1}).trigger("reloadGrid");
});
$("#btn_new").click(function () {
var url2 = url_view;
url2 += '?cmd=DETAIL';
url2 += '&page=' + $("#grid").getGridParam("page");
url2 += '&returnUrl=' + getReturnUrl();
url2 += '&menuId=' + '${param.menuId}';
goNav(url2);
});
$("input[name^=search]").keydown(function (key) {
if (key.keyCode == 13) {
$("#btn_search").click();
}
});
$("#startDatepicker").datepicker();
$("#endDatepicker").datepicker();
buttonControl();
});
</script>
</head>
<body>
<div class="right_box">
<div class="content_top">
<ul class="path">
<li><a href="#">${rmsMenuPath}</a></li>
</ul>
</div><!-- end content_top -->
<div class="content_middle" id="content_middle">
<div class="search_wrap">
<button type="button" class="cssbtn" id="btn_new" level="W"><i
class="material-icons">add</i> <%= localeMessage.getString("button.new") %>
</button>
<button type="button" class="cssbtn" id="btn_search" level="R"><i
class="material-icons">search</i> <%= localeMessage.getString("button.search") %>
</button>
</div>
<div class="title"><%= localeMessage.getString("portalUser.title") %>
</div>
<table class="search_condition" cellspacing=0;>
<tbody>
<tr>
<th style="width:10%; min-width:100px;"><%= localeMessage.getString("portalUser.orgName") %>
</th>
<td>
<div class="select-style">
<select name="searchOrgId" value="${param.searchOrgId}"></select>
</div>
</td>
<th style="width:10%; min-width:100px;"><%= localeMessage.getString("portalUser.roleName") %>
</th>
<td>
<div class="select-style">
<select name="searchRoleCode" value="${param.searchRoleCode}"></select>
</div>
</td>
<th><%= localeMessage.getString("portalUser.userStatus") %>
</th>
<td>
<div class="select-style">
<select type="text" name="searchUserStatus" value="${param.searchUserStatus}"></select>
</div>
</td>
</tr>
<tr>
<th style="width:10%; min-width:100px;"><%= localeMessage.getString("portalUser.name") %>
</th>
<td><input type="text" name="searchUserName"></td>
<th style="width:10%; min-width:100px;"><%= localeMessage.getString("portalUser.userId") %>
</th>
<td><input type="text" name="searchUserId" value="${param.searchUserId}"></td>
<th style="width:10%; min-width:100px;"><%= localeMessage.getString("portalUser.mobileNumber") %>
</th>
<td><input type="text" name="searchMobileNumber" value="${param.searchMobileNumber}"></td>
</tr>
<%--<tr>
<th><%= localeMessage.getString("portalUser.approvalStatus") %></th>
<td>
<div class="select-style">
<select type="text" name="searchApprovalStatus" value="${param.searchApprovalStatus}"></select>
</div>
</td>
<th ><%= localeMessage.getString("portalUser.createOn")%></th>
<td>
<input type="text" name="searchStartYYYYMMDD" id="startDatepicker" readonly="readonly" value="" size="10" style="width:160px;">
~ <input type="text" name="searchEndYYYYMMDD" value="" id="endDatepicker" size="10" readonly="readonly" style="width:160px;">
<input type="hidden" name="searchStartDate" value="" style="width:0px;">
<input type="hidden" name="searchEndDate" value="" style="width:0px;">
</td>
</tr> --%>
</tbody>
</table>
<table id="grid"></table>
<div id="pager"></div>
</div><!-- end content_middle -->
</div><!-- end right_box -->
</body>
</html>
@@ -0,0 +1,704 @@
<%@ page language="java" contentType="text/html; charset=utf-8" %>
<%@ page import="java.io.*" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib uri="http://www.springframework.org/tags" prefix="spring" %>
<%@ include file="/jsp/common/include/localemessage.jsp" %>
<%
response.setHeader("Pragma", "No-cache");
response.setHeader("Cache-Control", "no-cache");
response.setHeader("Expires", "0");
%>
<%!
public String getRequiredLabel(String label) {
return label + " <span class=\"required-mark\">*</span>";
}
%>
<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<jsp:include page="/jsp/common/include/css.jsp"/>
<jsp:include page="/jsp/common/include/script.jsp"/>
<jsp:include page="/jsp/common/include/portal.jsp"/>
<script language="javascript">
const url = '<c:url value="/onl/apim/portaluser/portalUserMan.json" />';
const url_view = '<c:url value="/onl/apim/portaluser/portalUserMan.view" />';
const file_download = '<c:url value="/file/download.do" />';
let isDetail = false;
let originalUserStatus = '';
const STATUS = { REMOVED: 'REMOVED', READY: 'READY'};
const ROLE = { USER: 'ROLE_USER' };
/* 버튼제어 */
function updateButtonStates(status, isUnmasked = false) {
const isIdCheckCompleted = !$("#btn_check_id").is(":visible")
&& $("#loginId").prop('disabled')
&& ("#domain").prop('disabled');
// 공통적으로 권한에 따른 법인선택 제어
function updateOrgControl() {
if ($("#roleCode").val() === ROLE.USER) {
$("#orgId").prop('disabled', true);
}
}
if (!isDetail) {
// 신규 등록
$("#btn_unmask, #btn_delete").hide();
$("#orgId").prop('disabled', true);
if(isIdCheckCompleted) {
$("#btn_check_id").hide();
$("#btn_modify").show().prop('disabled', false);
$("#loginId").prop('disabled', true);
} else {
$("#btn_check_id").show();
$("#btn_modify").show().prop('disabled', true);
}
updateOrgControl();
return;
}
// 상세 조회 - 기본 버튼 상태
$("#btn_unmask").show().prop('disabled', isUnmasked);
$("#btn_check_id").hide();
$("#btn_delete").show();
// 현재 상태가 탈퇴인 경우
if (status === STATUS.REMOVED) {
$("#btn_modify").show().prop('disabled', true);
return;
}
// 일반 상태
$("#btn_modify").show().prop('disabled', !isUnmasked);
if (isUnmasked) {
$("input, select").prop('disabled', false);
updateOrgControl();
}
}
function init() {
$.ajax({
type: "POST",
url: url,
dataType: "json",
data: {cmd: 'LIST_INIT_COMBO'},
success: function (json) {
var orgRows = [{CODE: "", NAME: "없음"}].concat(json.orgRows);
new makeOptions("CODE", "NAME")
.setObj($("select[name=orgId]"))
.setData(orgRows).setFormat(nameOptionFormat).rendering();
// 권한
new makeOptions("CODE", "NAME")
.setObj($("select[name=roleCode]"))
.setData(json.roleCodeRows).setFormat(nameOptionFormat).rendering();
// 사용자 상태
var disabledUserStatus = ['PW_FAIL', 'DORMANT', 'ADMINBLOCK'];
new makeOptions("CODE", "NAME")
.setObj($("select[name=userStatus]"))
.setData(json.userStatusRows).setFormat(nameOptionFormat).rendering();
$("#userStatus option").each(function () {
if (disabledUserStatus.includes($(this).val())) {
$(this).prop('disabled', true);
}
});
// 승인 상태
new makeOptions("CODE", "NAME")
.setObj($("select[name=approvalStatus]"))
.setData(json.approvalStatusRows).setFormat(nameOptionFormat).rendering();
let key = "${param.id}";
if (key != "" && key !== "null") {
detail(key);
}
},
error: function (e) {
alert(e.responseText);
}
});
}
function detail(key) {
if (!isDetail) return;
$.ajax({
type: "POST",
url: url,
dataType: "json",
data: {cmd: 'DETAIL', id: key},
success: function (data) {
$("#id").val(data.id);
$("#userName").val(data.userName);
$("#orgId").val(data.orgId);
$("#loginId").val(data.loginId.split('@')[0]).attr('readonly', true);
$("#domain").val(data.loginId.split('@')[1]).attr('readonly', true);
// hidden input에는 원본 값 저장
$("input[name=loginId]").val(data.loginId);
$("#btn_check_id").hide();
// 상태 설정
originalUserStatus = data.userStatus; // 원래 상태값 저장
$("#userStatus").val(data.userStatus);
$("#roleCode").val(data.roleCode).trigger('change');
$("#approvalStatus").val(data.approvalStatus);
// 탈퇴 상태 처리
if (originalUserStatus === STATUS.REMOVED) {
$("#btn_modify, #btn_delete").hide();
$("input, select").prop('disabled', true);
} else {
$("#roleCode").trigger('change');
updateButtonStates(data.userStatus, false);
}
// 휴대폰 번호 표시
if (data.mobileNumber) {
const parts = data.mobileNumber.split('-');
if (parts.length === 3) {
$("#mobilePrefix").val(parts[0]);
$("#mobileMiddle").val(parts[1]);
$("#mobileLast").val(parts[2]);
}
// hidden input에 원본 값 저장
$("input[name=mobileNumber]").val(data.mobileNumber);
}
// 기관 정보 및 파일 정보 처리
const portalOrgData = data.portalOrgUIs;
if (data.roleCode !== 'ROLE_USER') {
$('#orgInfoSection').show();
if (portalOrgData) {
setOrgInfo(portalOrgData);
setFileInfo(portalOrgData);
}
} else {
$('#orgInfoSection').hide();
}
},
error: function (e) {
alert(e.responseText);
}
});
}
/*법인정보 표시*/
function setOrgInfo(portalOrgData) {
$('#orgNameInfo').text(portalOrgData.orgName);
$('#orgCodeInfo').text(portalOrgData.orgCode);
$('#ceoNameInfo').text(portalOrgData.ceoName);
$('#compRegNoInfo').text(formatCompanyRegNo(portalOrgData.compRegNo));
$('#orgAddrInfo').text(portalOrgData.orgAddr);
$('#corpRegNoInfo').text(formatCorpRegNo(portalOrgData.corpRegNo));
$('#orgSectorsInfo').text(portalOrgData.orgSectors);
$('#orgStatusDescription').text(portalOrgData.orgStatusDescription);
$('#orgIndustryTypeInfo').text(portalOrgData.orgIndustryType);
$('#orgPhoneNumberInfo').text(formatPhoneDisplay(portalOrgData.orgPhoneNumber));
$('#serviceNameInfo').text(portalOrgData.serviceName);
$('#scPhoneNumberInfo').text(formatPhoneDisplay(portalOrgData.scPhoneNumber));
}
/*파일정보 표시*/
function setFileInfo(portalOrgData) {
if (!portalOrgData?.fileInfo?.fileDetails?.length) {
return clearFileInfo();
}
const fileDetail = portalOrgData.fileInfo.fileDetails[0];
if (!fileDetail.fileId || !fileDetail.originalFileName) {
return clearFileInfo();
}
const fileName = fileDetail.originalFileName + "." + fileDetail.fileExtension;
$("#fileName").text(fileName)
.off('click')
.on('click', () => downloadFile(fileDetail.fileId, fileDetail.fileSn))
.show();
}
function clearFileInfo() {
$("#fileName").parent('span').hide();
}
/*아이디 중복 체크*/
function checkDuplicateLoginId() {
const id = $("#loginId").val().trim();
const domain = $("#domain").val().trim();
if (!id) {
alert("<%= localeMessage.getString("portalUser.checkRequired1") %>");
$("#loginId").focus();
return;
}
if (!domain) {
alert("도메인을 입력하여 주십시오.");
$("#domain").focus();
return;
}
// 연속된 점(..), 하이픈(--) 제거 및 시작/끝 위치 검증
const cleanedDomain = domain
.replace(/\.{2,}/g, '.') // 연속된 점을 하나로
.replace(/-{2,}/g, '-') // 연속된 하이픈을 하나로
.replace(/^\.+|\.+$/g, '') // 시작/끝의 점 제거
.replace(/^-+|-+$/g, ''); // 시작/끝의 하이픈 제거
if (cleanedDomain !== domain) {
alert("도메인 형식이 잘못되었습니다. 올바른 형식으로 수정해 주십시오.");
$("#domain").val(cleanedDomain).focus();
return;
}
const fullLoginId = id + "@" + domain;
const emailPattern = /^[A-Za-z][A-Za-z0-9._-]*@[A-Za-z0-9][-A-Za-z0-9.]+\.[A-Za-z]{2,}$/;
if (!emailPattern.test(fullLoginId)) {
alert(fullLoginId + " 은 올바른 이메일 형식이 아닙니다.");
return;
}
$.ajax({
type: "POST",
url: url,
data: {cmd: 'CHECK_ID', loginId: fullLoginId},
success: function (json) {
if (json.result !== "success") {
alert("<%= localeMessage.getString("portalUser.checkUserMsg1")%>");
$("#loginId").focus();
} else {
alert(fullLoginId + "는 사용가능한 아이디 입니다.");
$("#btn_modify").prop('disabled', false); // 등록 버튼 활성화
$("input[name=loginId]").val(fullLoginId);
// ID 입력 필드 비활성화
$("#btn_check_id").hide();
$("#loginId").prop('disabled', true);
$("#domain").prop('disabled', true);
}
},
error: function (e) {
alert(e.responseText);
}
});
}
function validateEmailId(input) {
input.value = input.value.replace(/[^A-Za-z0-9._-]/g, '');
}
function validateDomainInput(input) {
input.value = input.value.replace(/[^A-Za-z0-9.-]/g, '');
// 연속된 점(..)또는 하이픈(--)을 하나로 변경
input.value = input.value.replace(/\.{2,}/g, '.');
input.value = input.value.replace(/-{2,}/g, '-');
}
/*휴대폰 번호 유효성 검사*/
function validateMobileNumber() {
const prefix = $("#mobilePrefix").val();
const middle = $("#mobileMiddle").val();
const last = $("#mobileLast").val();
if (!prefix || !middle || !last || middle.length < 3 || last.length < 4) {
alert("올바른 휴대폰 번호를 입력하여 주십시오.");
return false;
}
return true;
}
function updateOrAddField(array, name, value) {
let field = array.find(item => item.name === name);
if (field) {
field.value = value;
} else {
array.push({name: name, value: value});
}
}
function downloadFile(fileId, fileSn) {
window.location.href = file_download + '?fileId=' + fileId + '&fileSn=' + fileSn;
}
function formatPhoneDisplay(phoneNumber) {
if (!phoneNumber) return '';
const parts = phoneNumber.split('-');
if (parts[0] === '없음') {
return parts.slice(1).join('-');
}
return phoneNumber;
}
$(document).ready(function () {
const returnUrl = getReturnUrlForReturn();
let key = "${param.id}";
isDetail = key !== "" && key !== "null";
if (isDetail) {
$("#title").append(" 수정")
$("#btn_modify").html('<i class="material-icons">save</i> <%= localeMessage.getString("button.modify") %>');
updateButtonStates(STATUS.READY, false);
} else {
$("#title").append(" 등록")
$("#btn_modify").html('<i class="material-icons">save</i> <%= localeMessage.getString("button.register") %>');
$("#userStatus").val("READY");
$("#approvalStatus").val("PENDING");
$("#roleCode").val("ROLE_USER").trigger('change');
updateButtonStates(STATUS.READY, false);
}
init();
$("#mobileMiddle, #mobileLast").on({
'input': function () {
this.value = this.value.replace(/[^0-9]/g, ''); // 숫자 외 문자 제거
if (this.value.length === this.maxLength && this.id === 'mobileMiddle') {
$('#mobileLast').focus(); // 자동 포커스 이동
}
},
'paste': function (e) {
// 붙여넣기 시 숫자만 허용
e.preventDefault();
this.value = (e.originalEvent.clipboardData || window.clipboardData)
.getData('text')
.replace(/[^0-9]/g, '').slice(0, 4);
}
});
/* 권한에 따른 법인 선택 제어 */
$('#roleCode').change(function () {
if ($(this).val() === 'ROLE_USER') {
$('#orgId').val("").attr("disabled", true);
$('#orgNameLabel').html('<%= localeMessage.getString("portalUser.orgName") %>');
} else {
$("#orgId").attr("disabled", false);
$('#orgNameLabel').html('<%= getRequiredLabel(localeMessage.getString("portalUser.orgName")) %>');
}
const currentStatus = $("#userStatus").val();
const currentUnmaskState = $("#btn_unmask").prop('disabled');
updateButtonStates(currentStatus, currentUnmaskState)
});
$("#userStatus").change(function() {
const newStatus = $(this).val();
if (newStatus === STATUS.REMOVED) {
alert("삭제 상태로 변경되었습니다. '삭제' 버튼을 클릭해 주세요.");
}
const currentUnmaskState = $("#btn_unmask").prop('disabled');
updateButtonStates(newStatus, currentUnmaskState);
$('#roleCode').trigger('change');
});
$("#btn_check_id").click(checkDuplicateLoginId);
$("#btn_unmask").click(function() {
var reason = prompt("마스킹 해제 사유를 입력해 주세요");
if (reason != null && reason.trim() !== '') {
$.ajax({
type: "POST",
url: url,
dataType: "json",
data: {
cmd: 'UNMASK',
id: $("#id").val(),
reason: reason
},
success: function(data) {
// 마스킹 해제된 데이터로 화면 갱신
$("#userName").val(data.userName);
// 이메일(loginId) 갱신
const emailParts = data.loginId.split('@');
$("#loginId").val(emailParts[0]);
$("#domain").val(emailParts[1]);
$("input[name=loginId]").val(data.loginId);
// 휴대폰 번호 갱신
if (data.mobileNumber) {
const parts = data.mobileNumber.split('-');
if (parts.length === 3) {
$("#mobilePrefix").val(parts[0]);
$("#mobileMiddle").val(parts[1]);
$("#mobileLast").val(parts[2]);
}
$("input[name=mobileNumber]").val(data.mobileNumber);
}
// 버튼 상태 업데이트
updateButtonStates($("#userStatus").val(), true);
},
error: function(e) {
alert(e.responseText);
}
});
} else if (reason !== null) {
alert("마스킹 해제 사유를 입력해 주세요.");
}
});
$("#btn_modify").click(function () {
if ($("#roleCode").val() !== 'ROLE_USER' && $("#orgId").val() === "") {
alert("법인명을 선택해 주세요.")
return;
}
if (!checkRequired("ajaxForm")) return;
if (!validateMobileNumber()) return;
// form data 구성
const formData = $('#ajaxForm').serializeArray();
const mobileNumber = [
$("#mobilePrefix").val(),
$("#mobileMiddle").val(),
$("#mobileLast").val()
].join('-');
let mobileField = formData.find(item => item.name === 'mobileNumber');
if (mobileField) {
mobileField.value = mobileNumber;
} else {
formData.push({name: 'mobileNumber', value: mobileNumber});
}
formData.push({
name: 'cmd',
value: isDetail ? "UPDATE" : "INSERT"
});
if (!confirm("<%= localeMessage.getString("common.checkSave")%>")) return;
$.ajax({
type: "POST",
url: url,
data: formData,
success: function (json) {
if (json.status === "fail") {
alert(json.errorMsg || "저장에 실패했습니다.");
return;
}
alert("<%= localeMessage.getString("common.saveMsg") %>");
goNav(returnUrl);
},
error: function (e) {
alert(e.responseText);
}
});
});
$("#btn_previous").click(function () {
goNav(returnUrl);
});
$("#btn_delete").click(function () {
if (!confirm("<%= localeMessage.getString("common.confirmMsg")%>")) return;
$.ajax({
type: "POST",
url: url,
data: {
cmd: "DELETE",
id: $('input[name=id]').val()
},
success: function () {
alert("<%= localeMessage.getString("common.deleteMsg") %>");
goNav(returnUrl);
},
error: function (e) {
alert(e.responseText);
}
});
});
});
</script>
</head>
<body>
<div class="right_box">
<div class="content_top">
<ul class="path">
<li><a href="#">${rmsMenuPath}</a></li>
</ul>
</div>
<div class="content_middle">
<div class="search_wrap">
<button type="button" class="cssbtn" id="btn_unmask" level="W" status="DETAIL">
<i class="material-icons">lock_open</i> 마스킹해제
</button>
<button type="button" class="cssbtn" id="btn_modify" level="W" status="DETAIL,NEW">
<i class="material-icons">save</i> <%= localeMessage.getString("button.modify") %>
</button>
<button type="button" class="cssbtn" id="btn_delete" level="W" status="DETAIL">
<i class="material-icons">delete</i> <%= localeMessage.getString("button.delete") %>
</button>
<button type="button" class="cssbtn" id="btn_previous" level="R" status="DETAIL,NEW">
<i class="material-icons">arrow_back</i> <%= localeMessage.getString("button.previous") %>
</button>
</div>
<div class="title" id="title"><%= localeMessage.getString("portalUserDetail.title") %>
</div>
<form id="ajaxForm">
<input type="hidden" name="id" id="id">
<table class="table_row" cellspacing="0">
<tr>
<th style="width:15%;"><%= getRequiredLabel(localeMessage.getString("portalUser.userId")) %>
</th>
<td colspan="3">
<div class="input-group" style="width: 50%;">
<input type="text" id="loginId" style="width:10%; display: inline-block;" maxlength="30" onkeyup="validateEmailId(this)"/>
<span style="padding: 0 10px;">@</span>
<input type="text" id="domain" style="width:20%; display: inline-block;" maxlength="50" onkeyup="validateDomainInput(this)"/>
<input type="hidden" name="loginId"/>
<button type="button" class="smallBtn cssbtn" id="btn_check_id" level="R" status="NEW"
style="margin-left: 10px; display: inline-block;">
<i class="material-icons">check_circle</i> 중복체크
</button>
</div>
</td>
</tr>
<%-- roleCode 로 제어 --%>
<tr>
<th style="width:15%;"><%= getRequiredLabel(localeMessage.getString("portalUser.roleName")) %>
</th>
<td style="width:35%;">
<div class="select-style">
<select name="roleCode" id="roleCode"></select>
</div>
</td>
<th id="orgNameLabel"><%= localeMessage.getString("portalUser.orgName") %>
</th>
<td style="width:35%;">
<div class="select-style">
<select name="orgId" id="orgId"></select>
</div>
</td>
</tr>
<tr>
<th><%= getRequiredLabel(localeMessage.getString("portalUser.name")) %>
</th>
<td>
<input type="text" name="userName" id="userName" maxlength="10" data-required data-warning="사용자명을 입력하여 주십시요."/>
</td>
<th><%= getRequiredLabel(localeMessage.getString("portalUser.userStatus")) %>
</th>
<td>
<div class="select-style">
<select name="userStatus" id="userStatus"></select>
</div>
</td>
</tr>
<tr>
<th><%= getRequiredLabel(localeMessage.getString("portalUser.mobileNumber")) %>
</th>
<td>
<div class="input-group" style="width: 60%; display: flex;">
<div class="select-style" style="width: 25%; display: inline-block;">
<select id="mobilePrefix" style="padding-left: 10px;">
<option value="010">010</option>
<option value="011">011</option>
<option value="016">016</option>
<option value="017">017</option>
<option value="018">018</option>
</select>
</div>
<span class="mx-2">-</span>
<input type="text" id="mobileMiddle" maxlength="4" style="width: 20%; text-align: center;"/>
<span class="mx-2">-</span>
<input type="text" id="mobileLast" maxlength="4" style="width: 20%; text-align: center;"/>
<input type="hidden" name="mobileNumber"/>
</div>
</td>
<th><%= getRequiredLabel(localeMessage.getString("portalUser.approvalStatus")) %>
</th>
<td>
<div class="select-style">
<select name="approvalStatus" id="approvalStatus"></select>
</div>
</td>
</tr>
</table>
</form>
<div id="orgInfoSection" style="display: none; margin-top: 50px;">
<div class="title" style="margin-top: 10px">법인 기본정보</div>
<table class="table_row" cellspacing="0">
<tr>
<th style="width:15%;"><%= localeMessage.getString("portalOrg.orgName")%></th>
<td style="width:35%;" id="orgNameInfo"></td>
<%-- 제휴기관코드 --%>
<th style="width:15%;"><%= localeMessage.getString("portalOrg.orgCode")%></th>
<td style="width:35%;" id="orgCodeInfo"></td>
</tr>
<tr>
<%--사업자 등록번호--%>
<th><%= localeMessage.getString("portalOrg.compRegNo")%></th>
<td id="compRegNoInfo"></td>
<%--업태--%>
<th><%= localeMessage.getString("portalOrg.orgSectors")%></th>
<td id="orgSectorsInfo"></td>
</tr>
<tr>
<%--법인등록번호--%>
<th><%= localeMessage.getString("portalOrg.corpRegNo")%></th>
<td id="corpRegNoInfo"></td>
<%--업종--%>
<th><%= localeMessage.getString("portalOrg.orgIndustryType") %></th>
<td id="orgIndustryTypeInfo"></td>
</tr>
<tr>
<%-- 법인상태 --%>
<th><%= localeMessage.getString("portalOrg.orgStatus") %></th>
<td id="orgStatusDescription"></td>
<%-- 법인상태 ceo이름 --%>
<th style="width:15%;"><%= localeMessage.getString("portalOrg.ceoName")%></th>
<td style="width:35%;" id="ceoNameInfo"></td>
</tr>
<tr>
<%--고객센터 전화번호--%>
<th><%= localeMessage.getString("portalOrg.orgPhoneNumber") %></th>
<td id="orgPhoneNumberInfo"></td>
<%--사업장 소재지--%>
<th><%= localeMessage.getString("portalOrg.orgAddr")%></th>
<td id="orgAddrInfo"></td>
</tr>
<tr>
<th><%= localeMessage.getString("portalOrg.scPhoneNumber") %></th>
<td id="scPhoneNumberInfo"></td>
<%--서비스명 _ 필수값--%>
<th><%= localeMessage.getString("portalOrg.serviceName") %></th>
<td id="serviceNameInfo"></td>
</tr>
<tr>
<th><%= localeMessage.getString("portalOrg.compRegFile") %></th>
<td colspan="3">
<span style="cursor: pointer;">
<span id="fileName" style="text-decoration: underline;"></span>
<img src="${pageContext.request.contextPath}/images/icon_file.png"
style="vertical-align: middle; margin-left: 5px;" alt="">
</span>
<input type="hidden" name="compRegFile" id="compRegFile"/>
</td>
</tr>
<%-- <tr>--%>
<%-- &lt;%&ndash;ip 화이트리스트&ndash;%&gt;--%>
<%-- <th><%= localeMessage.getString("portalOrg.ipWhitelist") %></th>--%>
<%-- <td colspan="3" name="ipWhitelist" id="ipWhitelist"></td>--%>
<%-- </tr>--%>
</table>
</div>
</div>
</div>
</body>
</html>
@@ -0,0 +1,228 @@
<%@ page language="java" contentType="text/html; charset=utf-8" %>
<%@ page import="java.io.*" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib uri="http://www.springframework.org/tags" prefix="spring" %>
<%@ include file="/jsp/common/include/localemessage.jsp" %>
<%
response.setHeader("Pragma", "No-cache");
response.setHeader("Cache-Control", "no-cache");
response.setHeader("Expires", "0");
%>
<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<jsp:include page="/jsp/common/include/css.jsp"/>
<jsp:include page="/jsp/common/include/script.jsp"/>
<script language="javascript">
var url = '<c:url value="/onl/apim/portaluserterms/portalUserTermsMan.json" />';
var url_view = '<c:url value="/onl/apim/portaluserterms/portalUserTermsMan.view" />';
var isUnMasked = false;
var unmaskReason = '';
function init() {
$.ajax({
type: "POST",
url: url,
dataType: "json",
data: {cmd: 'LIST_INIT_COMBO'},
success: function (json) {
const comboConfigs = [{name: 'searchTermsType', data: json.termsTypeRows}];
comboConfigs.forEach(function (config) {
new makeOptions("CODE", "NAME")
.setObj($("select[name=" + config.name + "]"))
.setNoValueInclude(true)
.setNoValue("", "<%=localeMessage.getString("combo.all")%>")
.setData(config.data)
.setFormat(nameOptionFormat).rendering();
});
select_termsType = ": ;" + getGridSelectText("CODE", "NAME", json.termsTypeRows);
},
error: function (e) {
alert(e.responseText);
}
});
}
$(document).ready(function () {
init();
$('#grid').jqGrid({
datatype: "json",
mtype: 'POST',
url: url,
postData: {cmd: 'LIST'},
colNames: ['No.', 'id', '법인명', '동의자명', '약관동의자 이메일 아이디', '종류', '버전', '동의일시'],
colModel: [
{name: 'rowNum', align: 'center', width: 40, sortable: false},
{name: 'id', align: 'center', hidden: true, key: true},
{name: 'userOrgName', align: 'center', width: 100},
{name: 'createdByName', align: 'center', width: 80},
{name: 'createdByLoginId', align: 'center', width: 100},
{name: 'termsTypeName', align: 'center'},
{name: 'termsVersion', align: 'center', width: 40},
{name: 'agreementDate', align: 'center', width: 100, formatter: timeStampFormat}
],
jsonReader: {
repeatitems: false
},
pager: $('#pager'),
page: '${param.page}',
rowNum: '${rmsDefaultRowNum}',
autoheight: true,
height: $("#container").height(),
autowidth: true,
viewrecords: true,
rowList: eval('[${rmsDefaultRowList}]'),
rowId: function (obj) {
return obj.id;
},
loadComplete: function () {
var page = $(this).getGridParam('page');
var rowNum = $(this).getGridParam('rowNum');
var rows = $(this).getDataIDs();
var colModel = $(this).getGridParam("colModel");
for (var i = 0; i < rows.length; i++) {
var number = ((page - 1) * rowNum + i) + 1;
// var reverseNumber = records - ((page - 1) * rowNum + i);
$(this).setCell(rows[i], 'rowNum', number);
}
for (var i = 0; i < colModel.length; i++) {
$(this).setColProp(colModel[i].name, {sortable: false});
}
},
loadError: function (jqXHR, textStatus, errorThrown) {
var location = '<%=request.getContextPath()%>/';
comloadError(jqXHR, textStatus, errorThrown, location);
}
});
resizeJqGridWidth('grid', 'content_middle', '1000');
$("input[name=searchAgreementVersion]").on('keypress', function (e) {
if (e.which !== 8 && e.which !== 9 && (e.which < 48 || e.which > 57)) {
e.preventDefault();
return false;
}
})
.on('paste', function (e) {
e.preventDefault();
const pastedData = (e.originalEvent || e).clipboardData.getData('text/plain');
if (!/^\d*$/.test(pastedData)) {
return false;
}
$(this).val(pastedData.replace(/[^\d]/g, ''));
});
$("#btn_search").click(function () {
var postData = getSearchForJqgrid("cmd", isUnMasked ? "UNMASK" : "LIST");
if (isUnMasked) {
postData.reason = unmaskReason;
}
$("#grid").setGridParam({url: url, postData: postData, page: 1}).trigger("reloadGrid");
});
$("input[name^=search]").keydown(function (key) {
if (key.keyCode == 13) {
$("#btn_search").click();
}
});
$("#btn_unmask").click(function () {
var reason = prompt("마스킹 해제 사유를 입력해 주세요");
if (reason != null && reason.trim() !== '') {
const postData = getSearchForJqgrid("cmd", "UNMASK");
postData.reason = reason;
$.ajax({
type: "POST",
url: url,
dataType: "json",
data: postData,
success: function (response) {
isUnMasked = true;
unmaskReason = reason;
buttonControl();
$('#btn_unmask').prop('disabled', true);
const reloadData = getSearchForJqgrid("cmd", "UNMASK");
reloadData.reason = reason;
$("#grid").setGridParam({
postData: reloadData
}).trigger("reloadGrid");
},
error: function (e) {
alert("마스킹 해제 중 오류가 발생했습니다. " + e.responseText);
}
});
} else if (reason !== null) {
alert("마스킹 해제 사유를 입력해 주세요");
}
});
// select 박스 변경시 자동 검색
$("select[name=searchTermsType]").change(function () {
$("#btn_search").click(); // 검색 버튼 클릭 이벤트 재사용
});
buttonControl();
});
</script>
</head>
<body>
<div class="right_box">
<div class="content_top">
<ul class="path">
<li><a href="#">${rmsMenuPath}</a></li>
</ul>
</div><!-- end content_top -->
<div class="content_middle" id="content_middle">
<div class="search_wrap">
<button type="button" class="cssbtn" id="btn_unmask" level="W" status="DETAIL"><i class="material-icons">lock_open</i>
마스킹해제
</button>
<button type="button" class="cssbtn" id="btn_search" level="R"><i
class="material-icons">search</i> <%= localeMessage.getString("button.search") %>
</button>
</div>
<div class="title">약관동의 이력</div>
<form id="ajaxForm" onsubmit="return false;">
<table class="search_condition" cellspacing=0;>
<tbody>
<tr>
<th style="width:10%;">약관종류</th>
<td style="width:15%;">
<div class="select-style">
<select type="text" name="searchTermsType" value="${param.searchTermsType}"></select>
</div>
</td>
<th style="width:10%;">버전</th>
<td style="width:15%;">
<input type="text" name="searchAgreementVersion" style="width:200px;"/>
</td>
<th style="width:10%;">아이디</th>
<td style="width:15%;">
<input type="text" name="searchLoginId" style="width:200px;"/>
</td>
<th style="width:10%;">이름</th>
<td style="width:15%;">
<input type="text" name="searchUserName" style="width:200px;"/>
</td>
</tr>
</tbody>
</table>
</form>
<table id="grid"></table>
<div id="pager"></div>
</div><!-- end content_middle -->
</div><!-- end right_box -->
</body>
</html>
@@ -0,0 +1,193 @@
<%@ page language="java" contentType="text/html; charset=utf-8" %>
<%@ page import="java.io.*" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib uri="http://www.springframework.org/tags" prefix="spring" %>
<%@ include file="/jsp/common/include/localemessage.jsp" %>
<%
response.setHeader("Pragma", "No-cache");
response.setHeader("Cache-Control", "no-cache");
response.setHeader("Expires", "0");
%>
<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<jsp:include page="/jsp/common/include/css.jsp"/>
<jsp:include page="/jsp/common/include/script.jsp"/>
<script language="javascript">
var url = '<c:url value="/onl/apim/template/messageTemplateMan.json" />';
var url_view = '<c:url value="/onl/apim/template/messageTemplateMan.view" />';
function booleanFormatter(cellvalue) {
return cellvalue === 'Y'
? '<span style="color: red; font-size: 16px;">O</span>' // 활성화: 빨간 체크
: ''; // 비활성화: 공백
}
$(document).ready(function() {
var gridPostData = getSearchForJqgrid("cmd", "LIST");
$('#grid').jqGrid({
datatype: "json",
mtype: 'POST',
url: url,
postData: gridPostData,
colNames: [
'No.',
'<%= localeMessage.getString("messageTemplate.messageCode") %>',
'<%= localeMessage.getString("messageTemplate.messageName") %>',
'<%= localeMessage.getString("messageTemplate.enableSms") %>',
'<%= localeMessage.getString("messageTemplate.enableEmail") %>',
'<%= localeMessage.getString("messageTemplate.enableMessenger") %>'
],
colModel: [
{name: 'rowNum', align: 'center', width: '50', sortable: false},
{name: 'messageCode', width: '300', align: 'center'},
{name: 'messageName', width: '400', align: 'center'},
{name: 'enableSms', align: 'center', formatter: booleanFormatter},
{name: 'enableEmail', align: 'center', formatter: booleanFormatter},
{name: 'enableMessenger', align: 'center', formatter: booleanFormatter}
],
jsonReader: {
repeatitems: false
},
pager: $('#pager'),
page: '${param.page}',
rowNum: '${rmsDefaultRowNum}',
autoheight: true,
height: $("#container").height(),
autowidth: true,
viewrecords: true,
rowList: eval('[${rmsDefaultRowList}]'),
loadComplete: function(d) {
var records = $(this).getGridParam('records');
var page = $(this).getGridParam('page');
var rowNum = $(this).getGridParam('rowNum');
var rows = $(this).getDataIDs();
var colModel = $(this).getGridParam("colModel");
for (var i = 0; i < rows.length; i++) {
var number = ((page - 1) * rowNum + i) + 1;
// var reverseNumber = records - ((page - 1) * rowNum + i);
$(this).setCell(rows[i], 'rowNum', number);
}
colModel.forEach(col => {
$(this).setColProp(col.name, {sortable: false});
});
},
ondblClickRow: function(rowId) {
var rowData = $(this).getRowData(rowId);
console.log(rowData);
var key = rowData['messageCode'];
var args = {};
var url2 = url_view;
url2 = url2 + '?cmd=DETAIL&status=DETAIL';
url2 += '&menuId=' + '${param.menuId}';
url2 += '&id=' + key;
console.log('Generated URL: ' + url2);
showModal(url2, args, 950, 650, function() {
$("#grid").trigger("reloadGrid");
});
}, loadError: function(jqXHR, textStatus, errorThrown) {
if (jqXHR.status == 401) {
var location = '<%=request.getContextPath()%>/';
comloadError(jqXHR, textStatus, errorThrown, location);
}
}
});
resizeJqGridWidth('grid', 'content_middle', '1000');
$("#btn_search").click(function() {
var postData = getSearchForJqgrid("cmd", "LIST");
postData.searchEnableSms = $("input[name='searchEnableSms']").is(":checked") ? "Y" : null;
postData.searchEnableEmail = $("input[name='searchEnableEmail']").is(":checked") ? "Y" : null;
postData.searchEnableMessenger = $("input[name='searchEnableMessenger']").is(":checked") ? "Y" : null;
$("#grid").setGridParam({url: url, postData: postData, page: 1}).trigger("reloadGrid");
});
$("#btn_new").click(function() {
var args = {};
var url2 = url_view;
url2 = url2 + '?cmd=DETAIL&status=NEW';
var width = 950;
var height = 650;
var left = (screen.width - width) / 2;
var top = (screen.height - height) / 2;
var option = "left=" + left + ",top=" + top + ",scrollbars=yes";
showModal(url2, args, width, height, function() {
$("#grid").trigger("reloadGrid");
}, option);
});
$("input[name^=search]").keydown(function(key) {
if (key.keyCode == 13) {
$("#btn_search").click();
}
});
$("#startDatepicker").datepicker();
$("#endDatepicker").datepicker();
buttonControl();
});
</script>
</head>
<body>
<div class="right_box">
<div class="content_top">
<ul class="path">
<li><a href="#">${rmsMenuPath}</a></li>
</ul>
</div><!-- end content_top -->
<div class="content_middle" id="content_middle">
<div class="search_wrap">
<button type="button" class="cssbtn" id="btn_new" level="W"><i class="material-icons">add</i> <%= localeMessage.getString("button.new") %>
</button>
<button type="button" class="cssbtn" id="btn_search" level="R"><i class="material-icons">search</i> <%= localeMessage.getString("button.search") %>
</button>
</div>
<div class="title"><%= localeMessage.getString("messageTemplate.title") %> <span class="tooltip"><%= localeMessage.getString("messageTemplate.tooltip") %></span></div>
<table class="search_condition" cellspacing=0;>
<tbody>
<tr><!-- 제목 -->
<th style="width:10%; min-width:100px;"><%= localeMessage.getString("messageTemplate.messageName") %></th>
<td>
<input type="text" name="searchMessageSubject" value="${param.searchMessageSubject}">
</td>
<th style="width:10%; min-width:100px;"><%= localeMessage.getString("messageTemplate.messageCode") %></th>
<td><input type="text" name="searchMessageCode" value="${param.searchMessageCode}"></td>
<th style="width:10%; min-width:100px;">활성 검색</th>
<td>
<div>
<label><input type="checkbox" name="searchEnableSms" value=""> SMS 활성</label>
<label><input type="checkbox" name="searchEnableEmail" value=""> 이메일 활성</label>
<label><input type="checkbox" name="searchEnableMessenger" value=""> 메신저 활성</label>
</div>
</td>
</tr>
</tbody>
</table>
<table id="grid"></table>
<div id="pager"></div>
</div><!-- end content_middle -->
</div><!-- end right_box -->
</body>
</html>
@@ -0,0 +1,231 @@
<%@ page language="java" contentType="text/html; charset=utf-8"%>
<%@ page import="java.io.*"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib uri="http://www.springframework.org/tags" prefix="spring"%>
<%@ include file="/jsp/common/include/localemessage.jsp" %>
<%
response.setHeader("Pragma", "No-cache");
response.setHeader("Cache-Control", "no-cache");
response.setHeader("Expires", "0");
%>
<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<jsp:include page="/jsp/common/include/css.jsp"/>
<jsp:include page="/jsp/common/include/script.jsp"/>
<script language="javascript" >
var url = '<c:url value="/onl/apim/template/messageTemplateMan.json" />';
var url_view = '<c:url value="/onl/apim/template/messageTemplateMan.view" />';
var isDetail = false;
function detail(key){
if (!isDetail)return;
$.ajax({
type : "POST",
url:url,
dataType:"json",
data:{cmd: 'DETAIL', id : key},
success:function(json){
var data = json;
/* Checkbox checked */
$('.enableCheckbox').each(function(){
var name = $(this).attr('name');
$(this).prop('checked', data[name] === 'Y');
});
$("#ajaxForm input[type!=radio],#ajaxForm select,#ajaxForm textarea").each(function(){
var name = $(this).attr("name");
var tag = $(this).prop("tagName").toLowerCase();
$(tag+"[name="+name+"]").val(data[name]);
});
$('#emailTemplate').summernote('code', data.emailTemplate);
},
error:function(e){
alert(e.responseText);
}
});
}
$(document).ready(function() {
$('#emailTemplate').summernote({
placeholder: '여기에 내용을 입력하세요.',
height: 300,
toolbar: [
['style', ['style']],
['font', ['bold', 'underline', 'clear']],
['color', ['color']],
['para', ['ul', 'ol', 'paragraph']],
['table', ['table']],
['insert', ['link', 'picture', 'video']],
['view', ['codeview', 'help']]
],
callbacks: {
onInit: function() {
$('.note-editable').on('keydown', function(e) {
if (e.keyCode === 8) {
e.stopPropagation();
}
});
}
}
});
var key ="${param.id}";
isDetail = key != "" && key != "null";
if (isDetail){
isDetail = true;
$("#title").append(" 수정");
buttonControl(true);
} else {
$("#title").append(" 등록");
$("#btn_modify").html('<i class="material-icons">save</i> <%= localeMessage.getString("button.register") %></button>');
buttonControl(false);
}
detail(key)
$("#btn_modify").click(function(){
if (!checkRequired("ajaxForm")){
return;
}
if (confirm("<%= localeMessage.getString("common.checkSave")%>") != true)
return;
var postData = $('#ajaxForm').serializeArray();
postData.forEach(function(item) {
if ($('.enableCheckbox[name="' + item.name + '"]').length > 0) {
item.value = ($('.enableCheckbox[name="' + item.name + '"]').is(':checked')) ? 'Y' : 'N';
}
});
['enableSms', 'enableEmail', 'enableMessenger'].forEach(function(name) {
if (!postData.some(function(item) { return item.name === name; })) {
postData.push({ name: name, value: 'N' });
}
});
if (isDetail){
postData.push({ name: "cmd" , value:"UPDATE"});
}else{
postData.push({ name: "cmd" , value:"INSERT"});
}
$.ajax({
type : "POST",
url:url,
data:postData,
success:function(json){
alert("<%= localeMessage.getString("common.saveMsg") %>");
$("#btn_close").trigger("click");
},
error:function(e){
alert(e.responseText);
}
});
});
$("#btn_close").click(function(){
window.close();
});
$("#btn_delete").click(function(){
if(confirm("<%= localeMessage.getString("common.confirmMsg")%> \n템플릿을 삭제하면 해당 메세지 전송이 불가합니다.")){
var postData = $('#ajaxForm').serializeArray();
postData.push({ name: "cmd" , value:"DELETE"});
$.ajax({
type : "POST",
url:url,
data:postData,
success:function(args){
alert("<%= localeMessage.getString("common.deleteMsg") %>");
$("#btn_close").trigger("click");
},
error:function(e){
alert(e.responseText);
}
});
} else{
return false;
}
});
});
</script>
</head>
<body>
<div class="popup_box">
<div class="search_wrap">
<button type="button" class="cssbtn" id="btn_modify" level="W" status="DETAIL,NEW"><i class="material-icons">save</i> <%= localeMessage.getString("button.modify") %></button>
<button type="button" class="cssbtn" id="btn_delete" level="W" status="DETAIL"><i class="material-icons">delete</i> <%= localeMessage.getString("button.delete") %></button>
<button type="button" class="cssbtn" id="btn_close" level="R"><i class="material-icons">cancel</i> <%= localeMessage.getString("button.close") %></button>
</div>
<div class="title" id ="title"><%= localeMessage.getString("messageTemplate.titlePopup") %></div>
<form id="ajaxForm">
<input type="hidden" name="id">
<table class="table_row" cellspacing="0">
<tr>
<th><%= localeMessage.getString("messageTemplate.messageCode") %> <font color="red"> *</font></th>
<td><input type="text" name="messageCode" data-required data-warning="메세지 코드는 필수입니다"/></td>
</tr>
<tr>
<th><%= localeMessage.getString("messageTemplate.messageName") %> <font color="red"> *</font></th>
<td><input type="text" name="messageName" data-required data-warning="메세지 제목은 필수입니다"/></td>
</tr>
<tr>
<th><%= localeMessage.getString("messageTemplate.subjectTemplate") %></th>
<td><input type="text" name="subjectTemplate" id ="subjectTemplate" /></td>
</tr>
<tr>
<th><%= localeMessage.getString("messageTemplate.enableSms") %> </th>
<td>
<input type="checkbox" class="form-check-input enableCheckbox" name="enableSms"/>
</td>
</tr>
<tr>
<th><%= localeMessage.getString("messageTemplate.smsTemplate") %></th>
<td><textarea id="smsTemplate" name="smsTemplate" style="width:100%;height:100px" ></textarea></td>
</tr>
<tr>
<th><%= localeMessage.getString("messageTemplate.enableEmail") %> </th>
<td>
<input type="checkbox" class="form-check-input enableCheckbox" name="enableEmail"/>
</td>
</tr>
<tr>
<th><%= localeMessage.getString("messageTemplate.emailTemplate") %></th>
<td><textarea id="emailTemplate" name="emailTemplate" style="width:100%;height:100px" ></textarea></td>
</tr>
<tr>
<th><%= localeMessage.getString("messageTemplate.enableMessenger") %> </th>
<td>
<input type="checkbox" class="form-check-input enableCheckbox" name="enableMessenger"/>
</td>
</tr>
<tr>
<th><%= localeMessage.getString("messageTemplate.messengerTemplate") %></th>
<td><textarea id="messengerTemplate" name="messengerTemplate" style="width:100%;height:100px" ></textarea></td>
</tr>
</table>
</form>
</div><!-- end popup_box -->
</body>
</html>