diff --git a/egovframe-template-simple-react-contribution/src/css/component.css b/egovframe-template-simple-react-contribution/src/css/component.css index 150f740..dd27ca4 100644 --- a/egovframe-template-simple-react-contribution/src/css/component.css +++ b/egovframe-template-simple-react-contribution/src/css/component.css @@ -15,26 +15,26 @@ .btn.noscript {font-size: 0;} .btn > span {position: relative;} -.btn_blue_h46 {height: 46px; border-radius: 5px; color: #fff; font-size: 15px; line-height: 46px; text-align: center; background: #169bd5; padding: 0px;} -.btn_blue_h46:hover {height: 46px; border-radius: 5px; color: #169bd5; font-size: 15px; line-height: 46px; text-align: center; border: 1px solid #169bd5; padding: 0px;} -.btn_skyblue_h46 {height: 46px; border-radius: 5px; color: #005b82; font-size: 15px; line-height: 46px; text-align: center; background: #daedf5; padding: 0px;} -.btn_skyblue_h46:hover {height: 46px; border-radius: 5px; color: #005b82; font-size: 15px; line-height: 46px; text-align: center; border: 1px solid #daedf5; padding: 0px;} -.btn_red_h46 {height: 46px; border-radius: 5px; color: darkred; font-size: 15px; line-height: 46px; text-align: center; background: #ed898b; padding: 0px;} -.btn_red_h46:hover {height: 46px; border-radius: 5px; color: darkred; font-size: 15px; line-height: 46px; text-align: center; border: 1px solid #ed898b; padding: 0px;} +.btn_blue_h46 {height: 46px; border-radius: 5px; color: #fff; font-size: 15px; line-height: 46px; text-align: center; background: #169bd5; padding: 0 1rem 0 1rem !important;} +.btn_blue_h46:hover {height: 46px; border-radius: 5px; color: #169bd5; font-size: 15px; line-height: 46px; text-align: center; border: 1px solid #169bd5; padding: 0 1rem 0 1rem !important;} +.btn_skyblue_h46 {height: 46px; border-radius: 5px; color: #005b82; font-size: 15px; line-height: 46px; text-align: center; background: #daedf5; padding: 0 1rem 0 1rem !important;} +.btn_skyblue_h46:hover {height: 46px; border-radius: 5px; color: #005b82; font-size: 15px; line-height: 46px; text-align: center; border: 1px solid #daedf5; padding: 0 1rem 0 1rem !important;} +.btn_red_h46 {height: 46px; border-radius: 5px; color: darkred; font-size: 15px; line-height: 46px; text-align: center; background: #ed898b; padding: 0 1rem 0 1rem !important;} +.btn_red_h46:hover {height: 46px; border-radius: 5px; color: darkred; font-size: 15px; line-height: 46px; text-align: center; border: 1px solid #ed898b; padding: 0 1rem 0 1rem !important;} -.btn_blue_h32 {height: 32px; border-radius: 5px; color: #fff; font-size: 15px; line-height: 32px; text-align: center; background: #169bd5; padding: 0px;} -.btn_blue_h32:hover {height: 32px; border-radius: 5px; color: #169bd5; font-size: 15px; line-height: 32px; text-align: center; border: 1px solid #169bd5; padding: 0px;} -.btn_skyblue_h32 {height: 32px; border-radius: 5px; color: #005b82; font-size: 15px; line-height: 32px; text-align: center; background: #daedf5; padding: 0px;} -.btn_skyblue_h32:hover {height: 32px; border-radius: 5px; color: #005b82; font-size: 15px; line-height: 32px; text-align: center; border: 1px solid #daedf5; padding: 0px;} -.btn_red_h32 {height: 32px; border-radius: 5px; color: darkred; font-size: 15px; line-height: 32px; text-align: center; background: #ed898b; padding: 0px;} -.btn_red_h32:hover {height: 32px; border-radius: 5px; color: darkred; font-size: 15px; line-height: 32px; text-align: center; border: 1px solid #ed898b; padding: 0px;} +.btn_blue_h32 {height: 32px; border-radius: 5px; color: #fff; font-size: 15px; line-height: 32px; text-align: center; background: #169bd5; padding: 0 1rem 0 1rem !important;} +.btn_blue_h32:hover {height: 32px; border-radius: 5px; color: #169bd5; font-size: 15px; line-height: 32px; text-align: center; border: 1px solid #169bd5; padding: 0 1rem 0 1rem !important;} +.btn_skyblue_h32 {height: 32px; border-radius: 5px; color: #005b82; font-size: 15px; line-height: 32px; text-align: center; background: #daedf5; padding: 0 1rem 0 1rem !important;} +.btn_skyblue_h32:hover {height: 32px; border-radius: 5px; color: #005b82; font-size: 15px; line-height: 32px; text-align: center; border: 1px solid #daedf5; padding: 0 1rem 0 1rem !important;} +.btn_red_h32 {height: 32px; border-radius: 5px; color: darkred; font-size: 15px; line-height: 32px; text-align: center; background: #ed898b; padding: 0 1rem 0 1rem !important;} +.btn_red_h32:hover {height: 32px; border-radius: 5px; color: darkred; font-size: 15px; line-height: 32px; text-align: center; border: 1px solid #ed898b; padding: 0 1rem 0 1rem !important;} -.btn_blue_h31 {height: 31px; border-radius: 5px; color: #fff; font-size: 15px; line-height: 31px; text-align: center; background: #169bd5; padding: 0px;} -.btn_blue_h31:hover {height: 31px; border-radius: 5px; color: #169bd5; font-size: 15px; line-height: 31px; text-align: center; border: 1px solid #169bd5; padding: 0px;} -.btn_skyblue_h31 {height: 31px; border-radius: 5px; color: #005b82; font-size: 15px; line-height: 31px; text-align: center; background: #daedf5; padding: 0px;} -.btn_skyblue_h31:hover {height: 31px; border-radius: 5px; color: #005b82; font-size: 15px; line-height: 31px; text-align: center; border: 1px solid #daedf5; padding: 0px;} -.btn_red_h31 {height: 31px; border-radius: 5px; color: darkred; font-size: 15px; line-height: 31px; text-align: center; background: #ed898b; padding: 0px;} -.btn_red_h31:hover {height: 31px; border-radius: 5px; color: darkred; font-size: 15px; line-height: 31px; text-align: center; border: 1px solid #ed898b; padding: 0px;} +.btn_blue_h31 {height: 31px; border-radius: 5px; color: #fff; font-size: 15px; line-height: 31px; text-align: center; background: #169bd5; padding: 0 1rem 0 1rem !important;} +.btn_blue_h31:hover {height: 31px; border-radius: 5px; color: #169bd5; font-size: 15px; line-height: 31px; text-align: center; border: 1px solid #169bd5; padding: 0 1rem 0 1rem !important;} +.btn_skyblue_h31 {height: 31px; border-radius: 5px; color: #005b82; font-size: 15px; line-height: 31px; text-align: center; background: #daedf5; padding: 0 1rem 0 1rem !important;} +.btn_skyblue_h31:hover {height: 31px; border-radius: 5px; color: #005b82; font-size: 15px; line-height: 31px; text-align: center; border: 1px solid #daedf5; padding: 0 1rem 0 1rem !important;} +.btn_red_h31 {height: 31px; border-radius: 5px; color: darkred; font-size: 15px; line-height: 31px; text-align: center; background: #ed898b; padding: 0 1rem 0 1rem !important;} +.btn_red_h31:hover {height: 31px; border-radius: 5px; color: darkred; font-size: 15px; line-height: 31px; text-align: center; border: 1px solid #ed898b; padding: 0 1rem 0 1rem !important;} .btn_upload {position: relative; width: 180px; height: 46px; border-radius: 5px; color: #fff; font-size: 16px; line-height: 46px; text-align: center; background: #169bd5;} .btn_upload span {display: inline-block; height: 46px; line-height: 46px;} @@ -328,4 +328,8 @@ select::-ms-expand {display:none;} border-top: 1px solid #f5f5f5; font-weight: 700; margin: 0 +} + +.recharts-legend-item-text { + font-size: 11px; } \ No newline at end of file diff --git a/egovframe-template-simple-react-contribution/src/css/page.css b/egovframe-template-simple-react-contribution/src/css/page.css index 54ec026..7ff8bc2 100644 --- a/egovframe-template-simple-react-contribution/src/css/page.css +++ b/egovframe-template-simple-react-contribution/src/css/page.css @@ -295,6 +295,35 @@ .BRD010 .result .list_item > div:nth-child(1) {width: 60%; text-overflow: ellipsis; white-space: nowrap; overflow: hidden;} .BRD010 .result .list_item > div:nth-child(2) {width: 40%;} + + /* 로그현황 - 파일다운현황*/ + .BRD011 .head > span:nth-child(1) {width: 80px; font-size: 11px;} + .BRD011 .head > span:nth-child(2) {width: 60px; font-size: 10px;} + .BRD011 .head > span:nth-child(3) {width: 60px; font-size: 10px;} + .BRD011 .head > span:nth-child(4) {width: 60px; font-size: 10px;} + .BRD011 .head > span:nth-child(5) {width: 60px; font-size: 10px;} + .BRD011 .head > span:nth-child(6) {width: 60px; font-size: 10px;} + .BRD011 .head > span:nth-child(7) {width: 60px; font-size: 10px;} + .BRD011 .head > span:nth-child(8) {width: 60px; font-size: 10px;} + .BRD011 .head > span:nth-child(9) {width: 60px; font-size: 10px;} + .BRD011 .head > span:nth-child(10) {width: 60px; font-size: 10px;} + .BRD011 .head > span:nth-child(11) {width: 60px; font-size: 10px;} + .BRD011 .head > span:nth-child(12) {width: 60px; font-size: 10px;} + .BRD011 .head > span:nth-child(13) {width: 60px; font-size: 10px;} + .BRD011 .result .list_item > div:nth-child(1) {width: 80px;} + .BRD011 .result .list_item > div:nth-child(2) {width: 60px;} + .BRD011 .result .list_item > div:nth-child(3) {width: 60px;} + .BRD011 .result .list_item > div:nth-child(4) {width: 60px;} + .BRD011 .result .list_item > div:nth-child(5) {width: 60px;} + .BRD011 .result .list_item > div:nth-child(6) {width: 60px;} + .BRD011 .result .list_item > div:nth-child(7) {width: 60px;} + .BRD011 .result .list_item > div:nth-child(8) {width: 60px;} + .BRD011 .result .list_item > div:nth-child(9) {width: 60px;} + .BRD011 .result .list_item > div:nth-child(10) {width: 60px;} + .BRD011 .result .list_item > div:nth-child(11) {width: 60px;} + .BRD011 .result .list_item > div:nth-child(12) {width: 60px;} + .BRD011 .result .list_item > div:nth-child(13) {width: 60px;} + /* 게시판 사용관리 등록 */ .BOARD_USE_LIST .board_view2 dl dt {width: 185px;} .BOARD_USE_LIST .board_view2 dl:nth-child(2) dd .f_input2 {width: 490px; margin-left: 17px;} diff --git a/egovframe-template-simple-react-contribution/src/css/response.css b/egovframe-template-simple-react-contribution/src/css/response.css index a133244..a7f9f9e 100644 --- a/egovframe-template-simple-react-contribution/src/css/response.css +++ b/egovframe-template-simple-react-contribution/src/css/response.css @@ -101,17 +101,27 @@ .list_1 li::before {top: 8px;} - .btn_blue_h46 {height: 40px; font-size: 13px; line-height: 40px;} - .btn_skyblue_h46 {height: 40px; font-size: 13px; line-height: 40px;} - .btn_red_h46 {height: 40px; font-size: 13px; line-height: 40px;} + .btn_blue_h46 {height: 40px; font-size: 13px; line-height: 40px; padding: 0 1rem 0 1rem !important;} + .btn_skyblue_h46 {height: 40px; font-size: 13px; line-height: 40px; padding: 0 1rem 0 1rem !important;} + .btn_red_h46 {height: 40px; font-size: 13px; line-height: 40px; padding: 0 1rem 0 1rem !important;} + .btn_blue_h46:hover {height: 40px; font-size: 13px; line-height: 40px; padding: 0 1rem 0 1rem !important;} + .btn_skyblue_h46:hover {height: 40px; font-size: 13px; line-height: 40px; padding: 0 1rem 0 1rem !important;} + .btn_red_h46:hover {height: 40px; font-size: 13px; line-height: 40px; padding: 0 1rem 0 1rem !important;} - .btn_blue_h32 {height: 28px; font-size: 13px; line-height: 28px;} - .btn_skyblue_h32 {height: 28px; font-size: 13px; line-height: 28px;} - .btn_red_h32 {height: 28px; font-size: 13px; line-height: 28px;} + .btn_blue_h32 {height: 28px; font-size: 13px; line-height: 28px; padding: 0 1rem 0 1rem !important;} + .btn_skyblue_h32 {height: 28px; font-size: 13px; line-height: 28px; padding: 0 1rem 0 1rem !important;} + .btn_red_h32 {height: 28px; font-size: 13px; line-height: 28px; padding: 0 1rem 0 1rem !important;} + .btn_blue_h32:hover {height: 28px; font-size: 13px; line-height: 28px; padding: 0 1rem 0 1rem !important;} + .btn_skyblue_h32:hover {height: 28px; font-size: 13px; line-height: 28px; padding: 0 1rem 0 1rem !important;} + .btn_red_h32:hover {height: 28px; font-size: 13px; line-height: 28px; padding: 0 1rem 0 1rem !important;} + + .btn_blue_h31 {height: 28px; font-size: 13px; line-height: 28px; padding: 0 1rem 0 1rem !important;} + .btn_skyblue_h31 {height: 28px; font-size: 13px; line-height: 28px; padding: 0 1rem 0 1rem !important;} + .btn_red_h31 {height: 28px; font-size: 13px; line-height: 28px; padding: 0 1rem 0 1rem !important;} + .btn_blue_h31:hover {height: 28px; font-size: 13px; line-height: 28px; padding: 0 1rem 0 1rem !important;} + .btn_skyblue_h31:hover {height: 28px; font-size: 13px; line-height: 28px; padding: 0 1rem 0 1rem !important;} + .btn_red_h31:hover {height: 28px; font-size: 13px; line-height: 28px; padding: 0 1rem 0 1rem !important;} - .btn_blue_h31 {height: 28px; font-size: 13px; line-height: 28px;} - .btn_skyblue_h31 {height: 28px; font-size: 13px; line-height: 28px;} - .btn_red_h31 {height: 28px; font-size: 13px; line-height: 28px;} .btn_calendar {width: 40px; height: 40px; background-size: contain;} .btn_upload {height: 40px; font-size: 13px; line-height: 40px;} .btn_upload span {height: 40px; line-height: 40px;} @@ -454,6 +464,22 @@ .BRD010 .result .list_item > div:nth-child(1) {width: 60%;} .BRD010 .result .list_item > div:nth-child(2) {width: 40%; padding: 0 0 2px 0; font-weight: 700; text-align: left;} + /* 로그현황 - 파일다운현황 추후 수정 lim */ + .BRD011 .head {display: none;} + .BRD011 .result .list_item {padding: 16px 0; border-bottom: 1px solid #dde2e5;} + .BRD011 .result .list_item > div {border-bottom: 0; font-size: 14px;} + .BRD011 .result .list_item > div:nth-child(1) {display: none;} + .BRD011 .result .list_item > div:nth-child(2) {width: 100%; padding: 0 0 2px 0; font-weight: 700; text-align: left;} + .BRD011 .result .list_item > div:nth-child(3), + .BRD011 .result .list_item > div:nth-child(4), + .BRD011 .result .list_item > div:nth-child(5), + .BRD011 .result .list_item > div:nth-child(6) {width: auto; margin-right: 5px; padding: 0;} + .BRD011 .result .list_item > div:nth-child(3)::after, + .BRD011 .result .list_item > div:nth-child(4)::after, + .BRD011 .result .list_item > div:nth-child(5)::after, + .BRD011 .result .list_item > div:nth-child(6)::after {content: ""; display: inline-block; width: 1px; height: 11px; margin-left: 6px; background: #ccc; vertical-align: 0px;} + .BRD011 .result .list_item > div:nth-child(6)::after {content: none;} + .BOARD_USE_LIST .board_view2 dl dt {width: 95px;} .BOARD_USE_LIST .board_view2 dl:nth-child(2) dd .f_select {width: 100%;} .BOARD_USE_LIST .board_view2 dl:nth-child(2) dd .f_input2 {width: 100%; margin: 15px 0 0 0;} diff --git a/egovframe-template-simple-react-contribution/src/pages/admin/logs/FileDownloadStatus.jsx b/egovframe-template-simple-react-contribution/src/pages/admin/logs/FileDownloadStatus.jsx index 87eb686..6c272e0 100644 --- a/egovframe-template-simple-react-contribution/src/pages/admin/logs/FileDownloadStatus.jsx +++ b/egovframe-template-simple-react-contribution/src/pages/admin/logs/FileDownloadStatus.jsx @@ -1,13 +1,326 @@ -import React from 'react'; +import React, {useState, useEffect, useCallback, useRef, PureComponent} from 'react'; +import { Link, useLocation } from 'react-router-dom'; +import {LineChart, Line, XAxis, YAxis, CartesianGrid, Tooltip, Legend, ResponsiveContainer} from 'recharts'; -function FileDownloadStatus(props) { +import DatePicker from 'react-datepicker'; +import 'react-datepicker/dist/react-datepicker.css'; + +import { CSVLink } from "react-csv"; + +import {format, sub} from "date-fns"; +import { ko } from 'date-fns/locale'; + +import * as EgovNet from 'api/egovFetch'; +import URL from 'constants/url'; + +import { default as EgovLeftNav } from 'components/leftmenu/EgovLeftNavAdmin'; + +import { itemIdxByPage } from 'utils/calc'; + +function FileConnections(props) { + // console.group("EgovAdminPrivacyList"); + // console.log("[Start] EgovAdminPrivacyList ------------------------------"); + // console.log("EgovAdminPrivacyList [props] : ", props); + const nowDate = new Date(); + const oneMonthAgoDate = sub(nowDate, { months: 1 }); + const [start_date, setStartDate] = useState(oneMonthAgoDate); + const [end_date, setEndDate] = useState(nowDate); // new Date() + + const location = useLocation(); + // console.log("EgovAdminPrivacyList [location] : ", location); + + // eslint-disable-next-line no-unused-vars + const [searchCondition, setSearchCondition] = useState(location.state?.searchCondition || {start_date: format(start_date, "yyyy-MM-dd"), end_date: format(end_date, "yyyy-MM-dd")}); + const [chartData, setChartData] = useState([]); + const [excelData, setExcelData] = useState([]); + + const [listTag, setListTag] = useState([]); + + const excelHeaders = [ + { label: "일자", key: "logdt" }, + { label: "설계기준", key: "group10" }, + { label: "표준시방서", key: "group20" }, + { label: "서울특별시", key: "group40" }, + { label: "고속도로공사", key: "group50" }, + { label: "농업생산기반시설", key: "group60" }, + { label: "철도건설공사", key: "group70" }, + { label: "LH", key: "group80" }, + { label: "K-water", key: "group90" }, + { label: "(구)설계기준", key: "groupO2" }, + { label: "(구)표준시방서", key: "groupO3" }, + { label: "(구)전문시방서", key: "groupO4" }, + { label: "(구)훈령.예규.지침", key: "groupO567" } + ]; + + const retrieveList = useCallback((srchCnd) => { + // console.groupCollapsed("EgovAdminUsageList.retrieveList()"); + const retrieveListURL = '/admin/logs/file'; + + const requestOptions = { + method: "POST", + headers: { + 'Content-type': 'application/json', + }, + body: JSON.stringify(srchCnd) + } + + EgovNet.requestFetch( + retrieveListURL, + requestOptions, + (resp) => { + let mutListTag = []; + + const resultCnt = parseInt(resp.result.resultCnt); + const currentPageNo = 1; // resp.result.paginationInfo.currentPageNo; + const pageSize = resultCnt; // resp.result.paginationInfo.pageSize; + + // 리스트 항목 구성 + if (resultCnt === 0) { + mutListTag.push(

데이터가 없습니다.

); + } else { + resp.result.resultList.forEach(function (item, index) { + if (index === 0) mutListTag = []; // 목록 초기화 + const listIdx = itemIdxByPage(resultCnt, currentPageNo, pageSize, index); + + mutListTag.push( +
+
{item[0]}
+
{item[1].toLocaleString()}
+
{item[2].toLocaleString()}
+
{item[3].toLocaleString()}
+
{item[4].toLocaleString()}
+
{item[5].toLocaleString()}
+
{item[6].toLocaleString()}
+
{item[7].toLocaleString()}
+
{item[8].toLocaleString()}
+
{item[9].toLocaleString()}
+
{item[10].toLocaleString()}
+
{item[11].toLocaleString()}
+
{item[12].toLocaleString()}
+
+ ); + }); + } + setListTag(mutListTag); + + // chart values + let chartDataArray = resp.result.resultList.map((item, index) => ({ + logdt: item[0], // Assuming logdt is the x-axis data + "설계기준": item[1], // Assuming menuTitle is the y-axis data + "표준시방서": item[2], + "서울특별시": item[3], + "고속도로공사": item[4], + "농업생산기반시설": item[5], + "철도건설공사": item[6], + "LH": item[7], + "K-water": item[8], + "(구)설계기준": item[9], + "(구)표준시방서": item[10], + "(구)전문시방서": item[11], + "(구)훈령.예규.지침": item[12], + })); + setChartData(chartDataArray); + + // excel value + let filteredExcelData = resp.result.resultList.map((item) => ({ + logdt: item[0], + group10: item[1], + group20: item[2], + group40: item[3], + group50: item[4], + group60: item[5], + group70: item[6], + group80: item[7], + group90: item[8], + groupO2: item[9], + groupO3: item[10], + groupO4: item[11], + groupO567: item[12] + })); + setExcelData(filteredExcelData); + }, + function (resp) { + console.log("err response : ", resp); + } + ); + // console.groupEnd("EgovAdminPrivacyList.retrieveList()"); + },[listTag]); + + const CustomTooltip = ({ active, payload, label }) => { + if (active && payload && payload.length) { + return ( +
+

파일 다운 현황 [{`${label}`}]

+

설계기준 : {`${payload[0].value}`}회

+

표준시방서 : {`${payload[1].value}`}회

+

서울특별시 : {`${payload[2].value}`}회

+

고속도로공사 : {`${payload[3].value}`}회

+

농업생산기반시설 : {`${payload[4].value}`}회

+

철도건설공사 : {`${payload[5].value}`}회

+

LH : {`${payload[6].value}`}회

+

K-water : {`${payload[7].value}`}회

+

(구)설계기준 : {`${payload[8].value}`}회

+

(구)표준시방서 : {`${payload[9].value}`}회

+

(구)전문시방서 : {`${payload[10].value}`}회

+

(구)훈령.예규.지침 : {`${payload[11].value}`}회

+
+ ); + } + return null; + }; + + useEffect(() => { + retrieveList(searchCondition); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [start_date, end_date]); + + // console.log("------------------------------EgovAdminPrivacyList [End]"); + // console.groupEnd("EgovAdminPrivacyList"); return (
- FileDownloadStatus +
+ {/* */} +
+
    +
  • Home
  • +
  • 사이트관리
  • +
  • 로그현황
  • +
  • 파일 다운 현황
  • +
+
+ {/* */} + +
+ {/* */} + + {/* */} + +
+ {/* */} + +
+

파일 다운 현황

+
+ + {/* */} +
+
    +
  • + { + setStartDate(date); + setSearchCondition({ + start_date: format(date, "yyyy-MM-dd"), + end_date: format(end_date, "yyyy-MM-dd") + }); + }} + /> - +
  • +
  • + { + setEndDate(date); + setSearchCondition({ + start_date: format(start_date, "yyyy-MM-dd"), + end_date: format(date, "yyyy-MM-dd") + }); + }} + /> + {/* */} + CSV ⬇ +
  • +
+
+ {/* */} + + {/* */} +
+
+ 일자 + 설계기준 + 표준시방서 + 서울특별시 + 고속도로공사 + 농업생산기반시설 + 철도건설공사 + LH + K-water + (구)설계기준 + (구)표준시방서 + (구)전문시방서 + (구)훈령.예규.지침 +
+
+ {listTag} +
+
+
+ + + + + + } /> + + + + + + + + + + + + + + + +
+ {/* */} + + {/* */} +
+
+
); } -export default FileDownloadStatus; \ No newline at end of file +export default FileConnections; \ No newline at end of file diff --git a/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/logs/AdminLogsController.java b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/logs/AdminLogsController.java index 44b6f23..f867de6 100644 --- a/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/logs/AdminLogsController.java +++ b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/logs/AdminLogsController.java @@ -2,6 +2,7 @@ package com.dbnt.kcscbackend.admin.logs; import com.dbnt.kcscbackend.admin.logs.entity.TnDailyMenuLog; import com.dbnt.kcscbackend.admin.logs.entity.ThPrivacyLog; +import com.dbnt.kcscbackend.admin.logs.service.AdminFileService; import com.dbnt.kcscbackend.admin.logs.service.AdminMenuService; import com.dbnt.kcscbackend.admin.logs.service.AdminLogsService; import com.dbnt.kcscbackend.admin.logs.service.AdminUserService; @@ -35,6 +36,7 @@ public class AdminLogsController extends BaseController { private final AdminMenuService adminMenuService; private final AdminUserService adminUserService; private final AdminLogsService adminLogsService; + private final AdminFileService adminFileService; @Operation( summary = "로그현황 - 메뉴별 접속현황", @@ -93,6 +95,7 @@ public class AdminLogsController extends BaseController { return resultVO; } + @Operation( summary = "로그현황 - 개인정보 로그", description = "개인정보 로그현황", @@ -120,4 +123,32 @@ public class AdminLogsController extends BaseController { return resultVO; } + + @Operation( + summary = "로그현황 - 파일 다운 현황", + description = "파일 다운 현황", + tags = {"AdminLogsController"} + ) + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "조회 성공"), + @ApiResponse(responseCode = "403", description = "인가된 사용자가 아님") + }) + @RequestMapping(method = RequestMethod.POST, value = "/file", consumes = MediaType.APPLICATION_JSON_VALUE) + public ResultVO FileListCount(@RequestBody Map dateRange, + @AuthenticationPrincipal LoginVO user) + throws Exception { + + ResultVO resultVO = new ResultVO(); + Map resultMap = new HashMap<>(); + + String startDate = dateRange.get("start_date"); + String endDate = dateRange.get("end_date"); + + resultMap.put("resultCnt", adminFileService.selectFileCountCnt(startDate, endDate)); + resultMap.put("resultList", adminFileService.selectFileCount(startDate, endDate)); + resultVO.setResultCode(ResponseCode.SUCCESS.getCode()); + resultVO.setResultMessage(ResponseCode.SUCCESS.getMessage()); + resultVO.setResult(resultMap); + return resultVO; + } } diff --git a/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/logs/entity/ThAttachFileLog.java b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/logs/entity/ThAttachFileLog.java new file mode 100644 index 0000000..f71a4c6 --- /dev/null +++ b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/logs/entity/ThAttachFileLog.java @@ -0,0 +1,34 @@ +package com.dbnt.kcscbackend.admin.logs.entity; + +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.experimental.Accessors; +import org.hibernate.annotations.DynamicInsert; +import org.hibernate.annotations.DynamicUpdate; +import org.springframework.format.annotation.DateTimeFormat; + +import javax.persistence.*; +import java.time.LocalDate; +import java.awt.*; + +@Getter +@Setter +@Accessors(chain = true) +@Entity +@NoArgsConstructor +@DynamicInsert +@DynamicUpdate +@Table(name = "th_attach_file_log") +public class ThAttachFileLog { + @Id + @Column(name = "file_log_seq") + private Long fileLogSeq; + + @Column(name = "access_type") + private Long accessType; + + @Column(name = "access_dt") + @DateTimeFormat(pattern = "yyyy-MM-dd") + private LocalDate accessDt; +} diff --git a/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/logs/repository/FileLogsRepository.java b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/logs/repository/FileLogsRepository.java new file mode 100644 index 0000000..e8a1c93 --- /dev/null +++ b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/logs/repository/FileLogsRepository.java @@ -0,0 +1,37 @@ +package com.dbnt.kcscbackend.admin.logs.repository; + +import com.dbnt.kcscbackend.admin.logs.entity.ThAttachFileLog; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; + +import java.util.List; + +public interface FileLogsRepository extends JpaRepository { + + @Query(value = "SELECT COUNT(DISTINCT TO_CHAR(access_dt, 'YYYY-MM-DD')) " + + "FROM th_attach_file_log " + + "WHERE access_dt BETWEEN TO_DATE(:startDate, 'YYYY-MM-DD') AND TO_DATE(:endDate, 'YYYY-MM-DD')", nativeQuery = true) + long countDistinctFileIds(@Param("startDate") String startDate, @Param("endDate") String endDate); + + @Query(value = "SELECT TO_CHAR(access_dt, 'YYYY-MM-DD') as log_dt," + + " COUNT(CASE WHEN group_cur_cd = '10' THEN 1 ELSE NULL END) AS Code10Cnt," + + " COUNT(CASE WHEN group_cur_cd = '20' THEN 1 ELSE NULL END) AS Code20Cnt," + + " COUNT(CASE WHEN group_cur_cd = '40' THEN 1 ELSE NULL END) AS Code40Cnt," + + " COUNT(CASE WHEN group_cur_cd = '50' THEN 1 ELSE NULL END) AS Code50Cnt," + + " COUNT(CASE WHEN group_cur_cd = '60' THEN 1 ELSE NULL END) AS Code60Cnt," + + " COUNT(CASE WHEN group_cur_cd = '70' THEN 1 ELSE NULL END) AS Code70Cnt," + + " COUNT(CASE WHEN group_cur_cd = '80' THEN 1 ELSE NULL END) AS Code80Cnt," + + " COUNT(CASE WHEN group_cur_cd = '90' THEN 1 ELSE NULL END) AS Code90Cnt," + + " COUNT(CASE WHEN group_cur_cd = 'O2' THEN 1 ELSE NULL END) AS CodeO2Cnt," + + " COUNT(CASE WHEN group_cur_cd = 'O3' THEN 1 ELSE NULL END) AS CodeO3Cnt," + + " COUNT(CASE WHEN group_cur_cd = 'O4' THEN 1 ELSE NULL END) AS CodeO4Cnt," + + " COUNT(CASE WHEN group_cur_cd IN ('O5', 'O6', 'O7') THEN 1 ELSE NULL END) AS CodeO5Cnt " + + "FROM th_attach_file_log " + + "WHERE access_dt BETWEEN TO_DATE(:startDate, 'YYYY-MM-DD') AND TO_DATE(:endDate, 'YYYY-MM-DD') " + + "GROUP BY TO_CHAR(access_dt, 'YYYY-MM-DD') " + + "ORDER BY log_dt asc", nativeQuery = true) + List selectCountFile(@Param("startDate") String startDate, @Param("endDate") String endDate); + + +} diff --git a/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/logs/service/AdminFileService.java b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/logs/service/AdminFileService.java new file mode 100644 index 0000000..a3226a7 --- /dev/null +++ b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/logs/service/AdminFileService.java @@ -0,0 +1,25 @@ +package com.dbnt.kcscbackend.admin.logs.service; + +import com.dbnt.kcscbackend.admin.logs.repository.FileLogsRepository; +import lombok.RequiredArgsConstructor; +import org.egovframe.rte.fdl.cmmn.EgovAbstractServiceImpl; +import org.springframework.stereotype.Service; + +import java.util.List; + +@Service +@RequiredArgsConstructor +public class AdminFileService extends EgovAbstractServiceImpl { + private final FileLogsRepository fileLogsRepository; + + // 파일 다운 횟수 + public List selectFileCount(String startDate, String endDate) { + return fileLogsRepository.selectCountFile(startDate, endDate); + } + + // 전체 레코드 수 가져오기 + public long selectFileCountCnt(String startDate, String endDate) { + return fileLogsRepository.countDistinctFileIds(startDate, endDate); + } + +}