일, 월 회원 로그인 통계 화면 및 기능 추가

This commit is contained in:
name 2023-08-24 11:27:54 +09:00
parent c287701e1a
commit 1d57ffaed1
8 changed files with 451 additions and 6 deletions

View File

@ -99,5 +99,7 @@ public interface EgovLoginLogService {
public List<LoginLog> selectDeviceLogList(LoginLog loginLog) throws Exception;
public List<LoginLog> SelectDauLoginLogList(LoginLog loginLog) throws Exception;
public List<LoginLog> SelectMauLoginLogList(LoginLog loginLog) throws Exception;
}

View File

@ -128,6 +128,7 @@ public class LoginLog extends ComDefaultVO implements Serializable {
private String conectId ;
/*관리자 메소드 부분 추가*/
private String methodNm; //메소드 이름
private String param; //파라미터
@ -153,6 +154,39 @@ public class LoginLog extends ComDefaultVO implements Serializable {
private int visitCnt; // 방문수
private String startDateType; // 시작날짜
private String regDate; // 일자
private String joinUserCnt; // 회원가입 회원수
private String loginUserCnt; // 로그인 회원수
private String userRatio; // 이용자 비율
public String getRegDate() {
return regDate;
}
public void setRegDate(String regDate) {
this.regDate = regDate;
}
public String getJoinUserCnt() {
return joinUserCnt;
}
public void setJoinUserCnt(String joinUserCnt) {
this.joinUserCnt = joinUserCnt;
}
public String getLoginUserCnt() {
return loginUserCnt;
}
public void setLoginUserCnt(String loginUserCnt) {
this.loginUserCnt = loginUserCnt;
}
public String getUserRatio() {
return userRatio;
}
public void setUserRatio(String userRatio) {
this.userRatio = userRatio;
}
public String getStartDateType() {
return startDateType;
}
@ -522,6 +556,4 @@ public class LoginLog extends ComDefaultVO implements Serializable {
public void setmCnt(String mCnt) {
this.mCnt = mCnt;
}
}

View File

@ -222,6 +222,16 @@ public class EgovLoginLogServiceImpl extends EgovAbstractServiceImpl implements
@Override
public List<LoginLog> selectDeviceLogList(LoginLog loginLog) throws Exception {
return loginLogDAO.selectDeviceLogList(loginLog);
}
@Override
public List<LoginLog> SelectDauLoginLogList(LoginLog loginLog) throws Exception {
return loginLogDAO.SelectDauLoginLogList(loginLog);
}
@Override
public List<LoginLog> SelectMauLoginLogList(LoginLog loginLog) throws Exception {
return loginLogDAO.SelectMauLoginLogList(loginLog);
}
}

View File

@ -198,4 +198,14 @@ public class LoginLogDAO extends EgovAbstractDAO {
return (List<LoginLog>)list("LoginLogDAO.selectDeviceLogList", loginLog);
}
@SuppressWarnings("unchecked")
public List<LoginLog> SelectDauLoginLogList(LoginLog loginLog) throws Exception {
return (List<LoginLog>)list("LoginLogDAO.SelectDauLoginLogList", loginLog);
}
@SuppressWarnings("unchecked")
public List<LoginLog> SelectMauLoginLogList(LoginLog loginLog) throws Exception {
return (List<LoginLog>)list("LoginLogDAO.SelectMauLoginLogList", loginLog);
}
}

View File

@ -37,6 +37,7 @@ import egovframework.rte.ptl.mvc.tags.ui.pagination.PaginationInfo;
import itn.com.cmm.EgovMessageSource;
import itn.com.cmm.LoginVO;
import itn.com.cmm.util.RedirectUrlMaker;
import itn.let.mjo.msg.service.MjonMsgVO;
import itn.let.sym.log.clg.service.EgovLoginLogService;
import itn.let.sym.log.clg.service.LoginLog;
import itn.let.sym.log.clg.service.MsgLog;
@ -425,7 +426,6 @@ public class EgovLoginLogController {
RedirectUrlMaker redirectUrlMaker = new RedirectUrlMaker("/sym/log/clg/SelectLogMethodList.do");
return redirectUrlMaker.getRedirectUrl();
}
/*관리자로그설정관리 수정/view*/
@RequestMapping(value="/sym/log/clg/ViewLogMethod.do")
@ -441,7 +441,6 @@ public class EgovLoginLogController {
return "sym/log/clg/ViewLogMethod";
}
/* 관리자로그설정관리 등록*/
@RequestMapping(value="/sym/log/clg/InsertLogMethod.do")
public String insertLogMethod(@RequestParam Map<?, ?> commandMap,
@ -951,4 +950,64 @@ public class EgovLoginLogController {
//model.addAttribute("paginationInfo", paginationInfo);
return "sym/log/clg/SelectMsgLogList";
}
/**
* @Method Name : SelectDauLoginLogList
* @작성일 : 2023. 8. 22.
* @작성자 : WYH
* @변경이력 :
* @Method 설명 : 이용자 통계
*/
@RequestMapping(value = "/sym/log/clg/SelectDauLoginLogList.do")
public String SelectDauLoginLogList(
@ModelAttribute("searchVO") LoginLog loginLog
, @RequestParam Map<String, Object> commandMap
, ModelMap model) throws Exception {
/** pageing */
PaginationInfo paginationInfo = new PaginationInfo();
paginationInfo.setCurrentPageNo(loginLog.getPageIndex());
paginationInfo.setRecordCountPerPage(loginLog.getPageUnit());
paginationInfo.setPageSize(loginLog.getPageSize());
loginLog.setFirstIndex(paginationInfo.getFirstRecordIndex());
loginLog.setLastIndex(paginationInfo.getLastRecordIndex());
loginLog.setRecordCountPerPage(paginationInfo.getRecordCountPerPage());
List<LoginLog> dauLoginLogList = loginLogService.SelectDauLoginLogList(loginLog);
model.addAttribute("dauLoginLogList", dauLoginLogList);
paginationInfo.setTotalRecordCount(dauLoginLogList.size() > 0 ? ((LoginLog)dauLoginLogList.get(0)).getTotCnt() : 0);
model.addAttribute("paginationInfo", paginationInfo);
return "sym/log/clg/SelectDauLoginLogList";
}
/**
* @Method Name : SelectMauLoginLogList
* @작성일 : 2023. 8. 22.
* @작성자 : WYH
* @변경이력 :
* @Method 설명 : 이용자 통계
*/
@RequestMapping(value = "/sym/log/clg/SelectMauLoginLogList.do")
public String SelectMauLoginLogList(
@ModelAttribute("searchVO") LoginLog loginLog
, @RequestParam Map<String, Object> commandMap
, ModelMap model) throws Exception {
if("".equals(loginLog.getSearchCnd()) || loginLog.getSearchCnd() == null){ //최초조회시 현재년도 조회
LocalDate now = LocalDate.now();
int year = now.getYear();
loginLog.setSearchCnd(Integer.toString(year));
}
List<LoginLog> mauLoginLogList = loginLogService.SelectMauLoginLogList(loginLog);
model.addAttribute("mauLoginLogList", mauLoginLogList);
return "sym/log/clg/SelectMauLoginLogList";
}
}

View File

@ -974,6 +974,64 @@
ON A.days = C.mday
ORDER BY days DESC
</select>
</select>
<select id="LoginLogDAO.SelectDauLoginLogList" parameterClass="loginLog" resultClass="loginLog">
SELECT
COUNT(0) OVER() AS totCnt
, M.REG_DATE AS regDate
, M.REG_STEP_SUM AS joinUserCnt
, D.TDAY_U_CNT AS loginUserCnt
, ROUND((D.TDAY_U_CNT / M.REG_STEP_SUM) * 100,2) AS userRatio
FROM
(SELECT
DATE_FORMAT(L.APPROVAL_PNTTM, '%Y-%m-%d') AS REG_DATE
, SUM(COUNT(0)) OVER(ORDER BY DATE_FORMAT(L.APPROVAL_PNTTM, '%Y-%m-%d') ASC) AS REG_STEP_SUM
FROM LETTNGNRLMBER L
WHERE 1=1
AND L.MBER_STTUS = 'Y'
<isNotEmpty prepend="AND" property="searchBgnDe">
<![CDATA[DATE_FORMAT(L.APPROVAL_PNTTM, '%Y-%m-%d') >= DATE_FORMAT(#searchBgnDe#, '%Y-%m-%d')]]>
</isNotEmpty>
<isNotEmpty prepend="AND" property="searchEndDe">
<![CDATA[DATE_FORMAT(L.APPROVAL_PNTTM, '%Y-%m-%d') <= DATE_FORMAT(#searchEndDe#, '%Y-%m-%d')]]>
</isNotEmpty>
GROUP BY DATE_FORMAT(L.APPROVAL_PNTTM, '%Y-%m-%d')
ORDER BY DATE_FORMAT(L.APPROVAL_PNTTM, '%Y-%m-%d') DESC
) M
INNER JOIN MJ_DASH_STAT D
ON D.STAT_DATE = M.REG_DATE
WHERE 1=1
ORDER BY M.REG_DATE DESC
LIMIT #recordCountPerPage# OFFSET #firstIndex#
</select>
<select id="LoginLogDAO.SelectMauLoginLogList" parameterClass="loginLog" resultClass="loginLog">
SELECT
COUNT(0) OVER() AS totCnt
, M.REG_DATE AS regDate
, M.REG_STEP_SUM AS joinUserCnt
, D.TDAY_U_CNT AS loginUserCnt
, ROUND((D.TDAY_U_CNT / M.REG_STEP_SUM) * 100,2) AS userRatio
FROM
(SELECT
DATE_FORMAT(L.APPROVAL_PNTTM, '%Y-%m') AS REG_DATE
, SUM(COUNT(0)) OVER(ORDER BY DATE_FORMAT(L.APPROVAL_PNTTM, '%Y-%m') ASC) AS REG_STEP_SUM
FROM
LETTNGNRLMBER L
WHERE 1=1
AND L.MBER_STTUS = 'Y'
GROUP BY DATE_FORMAT(L.APPROVAL_PNTTM, '%Y-%m')
ORDER BY DATE_FORMAT(L.APPROVAL_PNTTM, '%Y-%m') DESC
)M
INNER JOIN MJ_DASH_STAT D
ON DATE_FORMAT(D.STAT_DATE, '%Y-%m') = M.REG_DATE
WHERE 1=1
<isNotEmpty prepend="AND" property="searchCnd">
<![CDATA[ DATE_FORMAT(D.STAT_DATE, '%Y') IN (#searchCnd#) ]]>
</isNotEmpty>
GROUP BY DATE_FORMAT(D.STAT_DATE, '%Y-%m')
ORDER BY M.REG_DATE DESC
</select>
</sqlMap>

View File

@ -0,0 +1,188 @@
<%@ page contentType="text/html; charset=utf-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="ui" uri="http://egovframework.gov/ctl/ui"%>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions"%>
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>
<%@ taglib prefix="ec" uri="/WEB-INF/tld/ecnet_tld.tld"%>
<%
response.setHeader("Cache-Control","no-store");
response.setHeader("Pragma","no-cache");
response.setDateHeader("Expires",0);
if (request.getProtocol().equals("HTTP/1.1")) response.setHeader("Cache-Control", "no-cache");
%>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<script type="text/javascript" src="<c:url value='/js/EgovMultiFile.js'/>"></script>
<script type="text/javascript" src="<c:url value='/js/EgovCalPopup.js'/>"></script>
<script type="text/javaScript" language="javascript">
function fn_search(){
linkPage(1);
}
function linkPage(pageNo){
var listForm = document.listForm ;
listForm.pageIndex.value = pageNo ;
if( $('#searchBgnDeYYYMMDD').val() != '' && $('#searchEndDeYYYMMDD').val() != '' ){
var iChkBeginDe = Number($('#searchBgnDeYYYMMDD').val().replaceAll("-", ""));
var iChkEndDe = Number($('#searchEndDeYYYMMDD').val().replaceAll("-", ""));
if(iChkBeginDe > iChkEndDe || iChkEndDe < iChkBeginDe ){
alert("검색 시작 일자는 종료 일자 보다 클 수 없습니다.");
return;
}
}
$('#searchBgnDe').val($('#searchBgnDeYYYMMDD').val()) ;
$('#searchEndDe').val($('#searchEndDeYYYMMDD').val()) ;
listForm.submit();
}
/* 날짜 초기화 */
function init_date(){
$('#ntceBgndeYYYMMDD').val('');
$('#ntceEnddeYYYMMDD').val('');
$('#ntceBgnde').val('');
$('#ntceEndde').val('');
}
//기간선택 select
function fnSetCalMonth(val) {
if(val == 0) {
init_date();
return;
}
var form = document.listForm;
var today = new Date();
var year = today.getFullYear();
var month = ("0"+(today.getMonth()+1)).slice(-2);
var date = ("0"+today.getDate()).slice(-2);
var sDate = new Date(today.setMonth(today.getMonth() - val));
var sYear = sDate.getFullYear();
var sMonth = ("0"+(sDate.getMonth()+1)).slice(-2);
var sDate = ("0"+sDate.getDate()).slice(-2);
form.searchBgnDeYYYMMDD.value = sYear + "-" + sMonth + "-" + sDate;
form.searchEndDeYYYMMDD.value = year + "-" + month + "-" + date;
}
</script>
<style>
.calBtn {
border: none;
background-color: transparent !important;
background-image: url(/pb/img/common/calendarIcon.png);
background-repeat: no-repeat;
width: 25px;
height: 25px !important;
vertical-align: middle;
margin-left: -38px !important;
margin-top: -2px !important;
cursor: pointer;
}
</style>
<form name="listForm" action="<c:url value='/sym/log/clg/SelectDauLoginLogList.do'/>" method="post">
<input name="pageIndex" type="hidden" value="<c:out value='${searchVO.pageIndex}'/>"/>
<input type="hidden" name="searchSortCnd" value="<c:out value="${searchVO.searchSortCnd}" />" />
<input type="hidden" name="searchSortOrd" value="<c:out value="${searchVO.searchSortOrd}" />" />
<input type="hidden" name="searchBgnDe" id="searchBgnDe" value="<c:out value="${searchVO.searchBgnDe}" />">
<input type="hidden" name="searchEndDe" id="searchEndDe" value="<c:out value="${searchVO.searchEndDe}" />">
<div class="contWrap">
<div class="pageTitle">
<div class="pageIcon"><img src="/pb/img/pageTitIcon4.png" alt=""></div>
<h2 class="titType1 c_222222 fwBold">DAU(일 이용자 수)</h2>
<p class="tType6 c_999999">일 기준 순 이용자(1회라도 로그인 한 이용자, 중복제거)를 확인할 수 있습니다.</p>
</div>
<div class="pageCont">
<div class="listSerch">
<select name="setCalMonth" onchange="fnSetCalMonth(this.value)">
<option value="0">전체</option>
<option value="1">1개월</option>
<option value="3">3개월</option>
<option value="6">6개월</option>
</select>
<a href="#" onclick="javascript:fn_egov_NormalCalendar(document.forms.listForm, document.forms.listForm.searchBgnDeYYYMMDD);">
<input style="width:auto;min-width: 83px;" type="text" class="date_format" name="searchBgnDeYYYMMDD" id="searchBgnDeYYYMMDD" size="4" maxlength="4" readonly=""
value="<c:out value="${searchVO.searchBgnDe}" />" >
<input type="button" class="calBtn">
</a>
<span class="line">&nbsp;~</span>
<a href="#" onclick="javascript:fn_egov_NormalCalendar(document.forms.listForm, document.forms.listForm.searchEndDeYYYMMDD);">
<input style="width:auto;min-width: 83px;" type="text" class="date_format" name="searchEndDeYYYMMDD" id="searchEndDeYYYMMDD" size="4" maxlength="4" readonly=""
value="<c:out value="${searchVO.searchEndDe}" />" >
<input type="button" class="calBtn">
</a>
<a href="#" style="margin-left: 17px;" onclick="init_date(); return false;">
<img src="/pb/img/common/topTimeOut.png" alt="타임아웃 아이콘">
</a>
<input type="button" class="btnType1" style="margin-left:10px;" value="검색" onclick="fn_search(); return false;">
</div>
<div class="listTop">
<p class="tType5">
총 <span class="tType4 c_456ded fwBold"><fmt:formatNumber value="${paginationInfo.totalRecordCount}" pattern="#,###" /></span>건
</p>
<div class="rightWrap">
<!-- <input type="button" class="printBtn"> -->
<select name="pageUnit" id="pageUnit" class="select" title="검색조건선택" onchange="linkPage(1);">
<option value='10' <c:if test="${searchVO.pageUnit == '10' or searchVO.pageUnit == ''}">selected</c:if>>10줄</option>
<option value='20' <c:if test="${searchVO.pageUnit == '20'}">selected</c:if>>20줄</option>
<option value='30' <c:if test="${searchVO.pageUnit == '30'}">selected</c:if>>30줄</option>
</select>
</div>
</div>
<div class="tableWrap">
<table class="tbType1">
<colgroup>
<col style="width: auto;">
<col style="width: 25%">
<col style="width: 25%">
<col style="width: 25%">
</colgroup>
<thead>
<tr>
<th>일자</th>
<th>회원수</th>
<th>순 이용자</th>
<th>순 이용자 비율</th>
</tr>
</thead>
<tbody>
<c:forEach var="result" items="${dauLoginLogList}" varStatus="status">
<tr>
<td><c:out value="${result.regDate}"/></td>
<td><fmt:formatNumber value="${result.joinUserCnt}" pattern="#,###" /></td>
<td><fmt:formatNumber value="${result.loginUserCnt}" pattern="#,###" /></td>
<td><c:out value="${result.userRatio}"/>%</td>
</tr>
</c:forEach>
<c:if test="${empty dauLoginLogList}">
<tr><td colspan="4"><spring:message code="common.nodata.msg" /></td></tr>
</c:if>
</tbody>
</table>
</div>
<div class="btnWrap">
</div>
<!-- 페이지 네비게이션 시작 -->
<c:if test="${!empty dauLoginLogList}">
<div class="page">
<ul class="inline">
<ui:pagination paginationInfo = "${paginationInfo}" type="image" jsFunction="linkPage" />
</ul>
</div>
</c:if>
<!-- //페이지 네비게이션 끝 -->
</div>
</div>
</form>

View File

@ -0,0 +1,86 @@
<%@ page contentType="text/html; charset=utf-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="ui" uri="http://egovframework.gov/ctl/ui"%>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions"%>
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>
<%@ taglib prefix="ec" uri="/WEB-INF/tld/ecnet_tld.tld"%>
<%
response.setHeader("Cache-Control","no-store");
response.setHeader("Pragma","no-cache");
response.setDateHeader("Expires",0);
if (request.getProtocol().equals("HTTP/1.1")) response.setHeader("Cache-Control", "no-cache");
%>
<title>월별 회원가입건수 통계</title>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<script type="text/javascript" src="<c:url value='/js/EgovMultiFile.js'/>"></script>
<script type="text/javascript" src="<c:url value='/js/EgovCalPopup.js'/>"></script>
<script type="text/javaScript" language="javascript">
$(document).ready(function(){
var date = new Date();
var year = date.getFullYear();
var startY = Number(year);
var endY = 2021;
for(var y = startY; y>= endY; y-- ){
$('#searchYear').append("<option value='"+y+"'>" + y+"년"+"</option>")
}
$('#searchYear').find('option[value="${searchVO.searchCnd}"]').attr("selected",true);
});
function linkPage(){
var listForm = document.listForm ;
$('#searchCnd').val($('#searchYear option:selected').val());
listForm.submit();
}
</script>
<form name="listForm" action="<c:url value='/sym/log/clg/SelectMauLoginLogList.do'/>" method="post">
<input type="hidden" name="searchCnd" id="searchCnd" value="">
<div class="contWrap">
<div class="pageTitle">
<div class="pageIcon"><img src="/pb/img/pageTitIcon4.png" alt=""></div>
<h2 class="titType1 c_222222 fwBold">MAU(월 이용자 수)</h2>
<p class="tType6 c_999999">월 기준 순 이용자(1회라도 로그인 한 이용자, 중복제거)를 확인할 수 있습니다..</p>
</div>
<div class="pageCont">
<div class="listSerch">
<select id="searchYear" name="searchYear" onchange="linkPage();"></select>
</div>
<div class="tableWrap">
<table class="tbType1">
<colgroup>
<col style="width: 20%">
<col style="width: 20%">
<col style="width: 20%">
<col style="width: 20%">
</colgroup>
<thead>
<tr>
<th>일자</th>
<th>회원수</th>
<th>순 이용자</th>
<th>순 이용자 비율</th>
</tr>
</thead>
<tbody>
<c:forEach var="result" items="${mauLoginLogList}" varStatus="status">
<tr>
<td><c:out value="${result.regDate}"/></td>
<td><fmt:formatNumber value="${result.joinUserCnt}" pattern="#,###" /></td>
<td><fmt:formatNumber value="${result.loginUserCnt}" pattern="#,###" /></td>
<td><c:out value="${result.userRatio}"/>%</td>
</tr>
</c:forEach>
<c:if test="${empty mauLoginLogList}">
<tr><td colspan="4"><spring:message code="common.nodata.msg" /></td></tr>
</c:if>
</tbody>
</table>
</div>
</div>
</div>
</form>