이력관리 추가
parent
e72e31d4d5
commit
071b4106cb
@ -0,0 +1,119 @@
|
|||||||
|
package cokr.xit.fims.base;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.stream.IntStream;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Controller;
|
||||||
|
import org.springframework.web.servlet.ModelAndView;
|
||||||
|
|
||||||
|
import cokr.xit.base.docs.xls.CellDef;
|
||||||
|
import cokr.xit.base.docs.xls.XLSWriter;
|
||||||
|
import cokr.xit.base.syslog.LogQuery;
|
||||||
|
import cokr.xit.base.syslog.service.LoggingService;
|
||||||
|
import cokr.xit.fims.task.TaskRequestMappingHandlerMapping;
|
||||||
|
import cokr.xit.foundation.data.DataFormat;
|
||||||
|
import cokr.xit.foundation.data.DataObject;
|
||||||
|
import cokr.xit.foundation.web.RequestHandlerReader;
|
||||||
|
|
||||||
|
@Controller
|
||||||
|
public class LoggingController extends cokr.xit.base.syslog.web.LoggingController {
|
||||||
|
@Resource(name = "loggingService")
|
||||||
|
private LoggingService loggingService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private TaskRequestMappingHandlerMapping requestHandlers;
|
||||||
|
|
||||||
|
private RequestHandlerReader requestReader = new RequestHandlerReader();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ModelAndView getLogs(LogQuery req) {
|
||||||
|
boolean download = !isEmpty(req.getDownload());
|
||||||
|
if (!download)
|
||||||
|
setFetchSize(req);
|
||||||
|
else
|
||||||
|
req.setPageNum(0).setFetchSize(0);
|
||||||
|
|
||||||
|
String
|
||||||
|
toDate = req.getToDate(),
|
||||||
|
fromDate = req.getFromDate();
|
||||||
|
if (isEmpty(toDate)) {
|
||||||
|
Date date = new Date();
|
||||||
|
toDate = DataFormat.yyyy_mm_dd(date);
|
||||||
|
req.setToDate(toDate.replace("-", ""));
|
||||||
|
|
||||||
|
if (isEmpty(fromDate)) {
|
||||||
|
fromDate = DataFormat.yyyy_mm_dd(new Date(date.getTime() - 1000L * 60L * 60L * 24L * 30L));
|
||||||
|
req.setFromDate(fromDate.replace("-", ""));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
List<DataObject>
|
||||||
|
list = loggingService.getLogs(req),
|
||||||
|
web = list.stream()
|
||||||
|
.filter(row -> "web".equals(row.get("LOG_TYPE")))
|
||||||
|
.toList();
|
||||||
|
if (!list.isEmpty()) {
|
||||||
|
Map<String, DataObject> reqs = requestReader.asTree(requestHandlers).getIndex();
|
||||||
|
list.forEach(row -> {
|
||||||
|
Object obj = row.get("REG_DT");
|
||||||
|
row.set("REG_DT", DataFormat.yyyy_mm_dd_hh_mm_ss(obj));
|
||||||
|
|
||||||
|
obj = row.get("URL");
|
||||||
|
if (isEmpty(obj)) return;
|
||||||
|
|
||||||
|
DataObject reqInfo = reqs.get(obj);
|
||||||
|
row.set("DSCRP", reqInfo != null ? reqInfo.get("name") : "");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!download)
|
||||||
|
return setCollectionInfo(
|
||||||
|
new ModelAndView("jsonView")
|
||||||
|
.addObject("fromDate", fromDate)
|
||||||
|
.addObject("toDate", toDate),
|
||||||
|
list,
|
||||||
|
"syslog"
|
||||||
|
);
|
||||||
|
else
|
||||||
|
return download(list);
|
||||||
|
}
|
||||||
|
|
||||||
|
private ModelAndView download(List<DataObject> list) {
|
||||||
|
List<CellDef> cellDefs = List.of(
|
||||||
|
new CellDef().setLabel("계정").setField("USER_ACNT"),
|
||||||
|
new CellDef().setLabel("사용자이름").setField("USER_NM"),
|
||||||
|
new CellDef().setLabel("IP 주소").setField("IP_ADDR"),
|
||||||
|
new CellDef().setLabel("로그유형").setField("LOG_TYPE_NM"),
|
||||||
|
new CellDef().setLabel("접속일시").setField("REG_DT"),
|
||||||
|
new CellDef().setLabel("URL").setField("URL"),
|
||||||
|
new CellDef().setLabel("설명").setField("DSCRP"),
|
||||||
|
new CellDef().setLabel("파일이름").setField("FILE_NM"),
|
||||||
|
new CellDef().setLabel("민감정보").setField("PSNL_INFO")
|
||||||
|
);
|
||||||
|
XLSWriter xlsx = new XLSWriter()
|
||||||
|
.worksheet(0)
|
||||||
|
.trackWidth(IntStream.range(0, cellDefs.size()).toArray())
|
||||||
|
.cell(0, 0)
|
||||||
|
.value("시스템 로그 목록").merge(0, cellDefs.size() - 1)
|
||||||
|
.cell(2, 0)
|
||||||
|
.rowValues(CellDef.header(cellDefs, null))
|
||||||
|
.cell(3, 0)
|
||||||
|
.values(
|
||||||
|
list,
|
||||||
|
CellDef.values(cellDefs)
|
||||||
|
)
|
||||||
|
.autoWidth();
|
||||||
|
|
||||||
|
return new ModelAndView("downloadView")
|
||||||
|
.addObject("download",
|
||||||
|
xlsx.getDownloadable()
|
||||||
|
.setFilename("시스템 로그 목록.xlsx")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,155 @@
|
|||||||
|
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" isELIgnored="false" session="false"%>
|
||||||
|
<%@ include file="/WEB-INF/jsp/include/taglib.jsp"%>
|
||||||
|
<c:set var="prefixName" scope="request">시스템 로그</c:set>
|
||||||
|
<!-- Page Body -->
|
||||||
|
<div class="d-flex flex-column flex-grow-1">
|
||||||
|
<div class="dataTables_wrapper dt-bootstrap5 no-footer">
|
||||||
|
|
||||||
|
<div id="${infoPrefix}-query" class="d-flex flex-row justify-content-between p-3">
|
||||||
|
<div class="d-flex flex-row">
|
||||||
|
<div class="input-group">
|
||||||
|
<select id="logType" class="form-select">
|
||||||
|
<option value="">로그유형</option>
|
||||||
|
<option value="log-inout">로그인/아웃</option>
|
||||||
|
<option value="download">다운로드</option>
|
||||||
|
<option value="web">웹</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="input-group" style="margin: 0 1rem 0 1rem">
|
||||||
|
<select id="by" onchange="document.getElementById('term').focus();" class="form-select">
|
||||||
|
<option value="userName">사용자 이름</option>
|
||||||
|
<option value="userAccount">사용자 계정</option>
|
||||||
|
<option value="userID">사용자 아이디</option>
|
||||||
|
</select>
|
||||||
|
<input id="term" type="text" placeholder="조회 조건을 입력하십시오." class="form-control">
|
||||||
|
</div>
|
||||||
|
<div class="input-group">
|
||||||
|
<input id="fromDate" type="text" value="${fromDate}" required placeholder="시작일자" class="form-control">
|
||||||
|
<span style="margin: 0 .5rem 0 .5rem"> ~ </span>
|
||||||
|
<input id="toDate" type="text" value="${toDate}" required placeholder="종료일자" class="form-control">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<button onclick="search${infoPrefix}s();" class="btn btn-primary">찾기</button>
|
||||||
|
<button onclick="${infoPrefix}Control.download();" class="btn btn-primary not-empty">다운로드</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="table-responsive">
|
||||||
|
<table class="datatables-ajax table table-bordered dataTable no-footer" id="DataTables_Table_0" aria-describedby="DataTables_Table_0_info">
|
||||||
|
<thead>
|
||||||
|
<tr><th style="width: auto;">계정</th>
|
||||||
|
<th style="width: auto;">사용자이름</th>
|
||||||
|
<th style="width: auto;">IP 주소</th>
|
||||||
|
<th style="width: max-content;">로그유형</th>
|
||||||
|
<th style="width: max-content;">접속일시</th>
|
||||||
|
<th style="width: auto;">URL</th>
|
||||||
|
<th style="width: auto;">설명</th>
|
||||||
|
<th style="width: auto;">파일이름</th>
|
||||||
|
<th style="width: auto;">민감정보</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody id="${infoPrefix}List">
|
||||||
|
</tbody>
|
||||||
|
<template id="${infoPrefix}Row">
|
||||||
|
<tr data-key="{LOG_ID}" {onclick}>
|
||||||
|
<td>{USER_ACNT}</td>
|
||||||
|
<td>{USER_NM}</td>
|
||||||
|
<td>{IP_ADDR}</td>
|
||||||
|
<td>{LOG_TYPE_NM}</td>
|
||||||
|
<td>{REG_DT}</td>
|
||||||
|
<td>{URL}</td>
|
||||||
|
<td>{DSCRP}</td>
|
||||||
|
<td>{FILE_NM}</td>
|
||||||
|
<td>{PSNL_INFO}</td>
|
||||||
|
</tr>
|
||||||
|
</template>
|
||||||
|
<template id="${infoPrefix}NotFound">
|
||||||
|
<tr class="odd">
|
||||||
|
<td valign="top" colspan="8" class="dataTables_empty text-center">${prefixName} 정보를 찾지 못했습니다.</td>
|
||||||
|
</tr>
|
||||||
|
</template>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<div class="d-flex flex-row p-3 justify-content-between">
|
||||||
|
<label id="${infoPrefix}PagingInfo" class="dataTables_info" role="status" aria-live="polite"></label>
|
||||||
|
<ul id="${infoPrefix}Paging" class="pagination pagination-primary">
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!--/ Page Body -->
|
||||||
|
<script >
|
||||||
|
var ${infoPrefix}Control = new DatasetControl({
|
||||||
|
prefix: "${infoPrefix}",
|
||||||
|
prefixName: "${prefixName}",
|
||||||
|
keymapper: row => row.LOG_ID,
|
||||||
|
dataGetter: obj => obj.${infoPrefix}List,
|
||||||
|
query: {}
|
||||||
|
});
|
||||||
|
|
||||||
|
function search${infoPrefix}s() {
|
||||||
|
let logType = $("#logType").val(),
|
||||||
|
params = {
|
||||||
|
logTypes: logType ? [logType] : [],
|
||||||
|
fromDate: $("#fromDate").val().replace(/-/gi, ""),
|
||||||
|
toDate: $("#toDate").val().replace(/-/gi, "")
|
||||||
|
},
|
||||||
|
terms = $("#${infoPrefix}-query #term").val();
|
||||||
|
if (terms) {
|
||||||
|
switch ($("#${infoPrefix}-query #by").val()) {
|
||||||
|
case "userName": params.userName = terms; break;
|
||||||
|
case "userAccount": params.userAccounts = [terms]; break;
|
||||||
|
case "userID": params.userIDs = [terms]; break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
${infoPrefix}Control.query = params;
|
||||||
|
${infoPrefix}Control.load(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
${infoPrefix}Control.onDatasetChange = obj => {
|
||||||
|
let ${infoPrefix}List = ${infoPrefix}Control.dataset,
|
||||||
|
empty = ${infoPrefix}List.empty,
|
||||||
|
|
||||||
|
trs = empty ?
|
||||||
|
[document.getElementById("${infoPrefix}NotFound").innerHTML] : <%-- from template#${infoPrefix}NotFound --%>
|
||||||
|
${infoPrefix}List.inStrings(
|
||||||
|
document.getElementById("${infoPrefix}Row").innerHTML, <%-- from template#${infoPrefix}Row --%>
|
||||||
|
(str, dataItem) => str
|
||||||
|
.replace(/{onclick}=""/gi, 'onclick="syslogControl.setCurrent(\'' + dataItem.getValue("LOG_ID") + '\');"')
|
||||||
|
);
|
||||||
|
$("#${infoPrefix}List").html(trs.join());
|
||||||
|
$("#${infoPrefix}-query button.not-empty").prop("disabled", empty);
|
||||||
|
|
||||||
|
$("#${infoPrefix}Paging").setPaging({
|
||||||
|
list:${infoPrefix}Control.dataset,
|
||||||
|
prefix:${infoPrefix}Control.prefix,
|
||||||
|
start:obj.${infoPrefix}Start,
|
||||||
|
totalSize:obj.${infoPrefix}Total,
|
||||||
|
fetchSize:obj.${infoPrefix}Fetch,
|
||||||
|
func:"${infoPrefix}Control.load({index})"
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
${infoPrefix}Control.onCurrentChange = item => {
|
||||||
|
if (!item) return;
|
||||||
|
|
||||||
|
let key = item.data.LOG_ID;
|
||||||
|
$("#${infoPrefix}List").setCurrentRow(key);
|
||||||
|
};
|
||||||
|
|
||||||
|
$("#term").onEnterPress(search${infoPrefix}s);
|
||||||
|
|
||||||
|
$(function(){
|
||||||
|
${onload}
|
||||||
|
${infoPrefix}Control.setData({
|
||||||
|
${infoPrefix}List:${syslogList},
|
||||||
|
${infoPrefix}Start:${syslogStart},
|
||||||
|
${infoPrefix}Fetch:${syslogFetch},
|
||||||
|
${infoPrefix}Total:${syslogTotal}
|
||||||
|
});
|
||||||
|
$("#${infoPrefix}-query #fromDate, #${infoPrefix}-query #toDate").datePicker();
|
||||||
|
});
|
||||||
|
//# sourceURL=${infoPrefix}-main.jsp
|
||||||
|
</script>
|
Loading…
Reference in New Issue