chore: 중간저장

thkim
thkim 2024-01-16 17:59:27 +09:00
commit e865725999
47 changed files with 2615 additions and 344 deletions

File diff suppressed because it is too large Load Diff

View File

@ -19,7 +19,8 @@
"react-scripts": "5.0.1", "react-scripts": "5.0.1",
"recharts": "^2.10.3", "recharts": "^2.10.3",
"styled-components": "^6.0.9", "styled-components": "^6.0.9",
"web-vitals": "^2.1.4" "web-vitals": "^2.1.4",
"date-fns": "^3.2.0"
}, },
"devDependencies": { "devDependencies": {
"@testing-library/jest-dom": "^5.16.4", "@testing-library/jest-dom": "^5.16.4",

View File

@ -10,6 +10,16 @@ export function getQueryString(params){
return `?${Object.entries(params).map(e => e.join('=')).join('&') }` return `?${Object.entries(params).map(e => e.join('=')).join('&') }`
} }
export function convParams(params){
let str = "?"
for(let key in params){
if(params[key]){
str = str+key+"="+params[key]+"&";
}
}
return str;
}
export function requestFetch(url, requestOptions, handler, errorHandler) { export function requestFetch(url, requestOptions, handler, errorHandler) {
console.groupCollapsed("requestFetch"); console.groupCollapsed("requestFetch");
console.log("requestFetch [URL] : ", SERVER_URL + url); console.log("requestFetch [URL] : ", SERVER_URL + url);

View File

@ -0,0 +1,56 @@
import React, {useCallback, useEffect, useState} from "react";
import Form from "react-bootstrap/Form";
import * as EgovNet from "api/egovFetch";
function CheckBox({name, grpCd, selectedValue}){
const [checkBox, setCheckBox] = useState();
useEffect(() => {
getCodeItemList()
}, []);
useEffect(() => {
if(selectedValue){
const itemCdAry = selectedValue.split(',');
itemCdAry.forEach(function(itemCd){
document.querySelector(`#chkBox_${itemCd}`).checked = true;
})
}
}, [selectedValue]);
function getCodeItemList() {
EgovNet.requestFetch(
'/commonCode/code-item?grpCd='+grpCd,
{
method: "GET"
},
(resp) => {
let checkBoxTag = [];
resp.result.codeList.forEach(function (item, index) {
checkBoxTag.push(
<Form.Check inline
label={item.itemNm}
id={`chkBox_${item.itemCd}`}
key={`chkBox_${item.itemCd}_${index}`}
name={name}
value={item.itemCd}
/>
);
});
setCheckBox(checkBoxTag);
},
function (resp) {
console.log("err response : ", resp);
}
);
}
return (
<div id={`${grpCd}_checkBoxDiv`} key={`checkBox_${grpCd}`}>
{checkBox}
</div>
)
}
export default CheckBox;

View File

@ -0,0 +1,46 @@
import React, {useEffect, useState} from "react";
import Form from "react-bootstrap/Form";
import * as EgovNet from "api/egovFetch";
function SelectOption({name, grpCd, selectedValue}){
const [options, setOptions] = useState();
const [value, setValue] = useState(selectedValue)
useEffect(() => {
getCodeItemList()
}, []);
useEffect(() => {
setValue(selectedValue)
}, [selectedValue]);
function getCodeItemList(){
EgovNet.requestFetch(
'/commonCode/code-item?grpCd='+grpCd,
{
method: "GET"
},
(resp) => {
let optionTag = [];
//
resp.result.codeList.forEach(function (item, index) {
optionTag.push(
<option value={item.itemCd} key={`${grpCd}option${index}`}>{item.itemNm}</option>
);
});
setOptions(optionTag);
},
function (resp) {
console.log("err response : ", resp);
}
);
}
return (
<Form.Select name={name} value={value} onChange={(e)=>{setValue(e.target.value)}}>
{options}
</Form.Select>
)
}
export default SelectOption;

View File

@ -40,6 +40,19 @@ function EgovLeftNavAdmin(props) {
<div className="inner"> <div className="inner">
<h2 className={"nav_title"}>사이트관리</h2> <h2 className={"nav_title"}>사이트관리</h2>
<Accordion defaultActiveKey={activeKey}> <Accordion defaultActiveKey={activeKey}>
<Accordion.Item eventKey={"7"}>
<Accordion.Header>사이트 관리</Accordion.Header>
<Accordion.Body>
<ul className="menu4">
<li><NavLink to={URL.ADMIN_SCHEDULE} className={({ isActive }) => (isActive ? "cur" : "")}>Dashboard</NavLink></li>
{/*<li><NavLink to={URL.ADMIN_BOARD} className={({ isActive }) => (isActive ? "cur" : "")}></NavLink></li>
<li><NavLink to={URL.ADMIN_USAGE} className={({ isActive }) => (isActive ? "cur" : "")}>게시판사용관리</NavLink></li>
<li><NavLink to={URL.ADMIN_NOTICE} className={({ isActive }) => (isActive ? "cur" : "")}>공지사항관리</NavLink></li>
<li><NavLink to={URL.ADMIN_GALLERY} className={({ isActive }) => (isActive ? "cur" : "")}>사이트갤러리관리</NavLink></li>
<li><NavLink to={URL.ADMIN_MANAGER} className={({ isActive }) => (isActive ? "cur" : "")}>사이트관리자 암호변경</NavLink></li>*/}
</ul>
</Accordion.Body>
</Accordion.Item>
<Accordion.Item eventKey={"0"}> <Accordion.Item eventKey={"0"}>
<Accordion.Header>환경설정</Accordion.Header> <Accordion.Header>환경설정</Accordion.Header>
<Accordion.Body> <Accordion.Body>
@ -93,7 +106,7 @@ function EgovLeftNavAdmin(props) {
<li><NavLink to={URL.ADMIN__CONTENTS__SURVEY} className={({ isActive }) => (isActive ? "cur" : "")}>설문 관리</NavLink></li> <li><NavLink to={URL.ADMIN__CONTENTS__SURVEY} className={({ isActive }) => (isActive ? "cur" : "")}>설문 관리</NavLink></li>
<li><NavLink to={URL.ADMIN__CONTENTS__POP_UP} className={({ isActive }) => (isActive ? "cur" : "")}>팝업 관리</NavLink></li> <li><NavLink to={URL.ADMIN__CONTENTS__POP_UP} className={({ isActive }) => (isActive ? "cur" : "")}>팝업 관리</NavLink></li>
<li><NavLink to={URL.ADMIN__CONTENTS__STANDARDS_RESEARCH} className={({ isActive }) => (isActive ? "cur" : "")}>건설기준연구 관리</NavLink></li> <li><NavLink to={URL.ADMIN__CONTENTS__STANDARDS_RESEARCH} className={({ isActive }) => (isActive ? "cur" : "")}>건설기준연구 관리</NavLink></li>
<li><NavLink to={URL.ADMIN__CONTENTS__TEXT_MESSAGES} className={({ isActive }) => (isActive ? "cur" : "")}>문자 발송</NavLink></li> {/*<li><NavLink to={URL.ADMIN__CONTENTS__TEXT_MESSAGES} className={({ isActive }) => (isActive ? "cur" : "")}>문자 발송</NavLink></li>*/}
</ul> </ul>
</Accordion.Body> </Accordion.Body>
</Accordion.Item> </Accordion.Item>
@ -119,19 +132,6 @@ function EgovLeftNavAdmin(props) {
</ul> </ul>
</Accordion.Body> </Accordion.Body>
</Accordion.Item> </Accordion.Item>
<Accordion.Item eventKey={"7"}>
<Accordion.Header>전자정부 기본 메뉴</Accordion.Header>
<Accordion.Body>
<ul className="menu4">
<li><NavLink to={URL.ADMIN_SCHEDULE} className={({ isActive }) => (isActive ? "cur" : "")}>일정관리</NavLink></li>
<li><NavLink to={URL.ADMIN_BOARD} className={({ isActive }) => (isActive ? "cur" : "")}>게시판생성관리</NavLink></li>
<li><NavLink to={URL.ADMIN_USAGE} className={({ isActive }) => (isActive ? "cur" : "")}>게시판사용관리</NavLink></li>
<li><NavLink to={URL.ADMIN_NOTICE} className={({ isActive }) => (isActive ? "cur" : "")}>공지사항관리</NavLink></li>
<li><NavLink to={URL.ADMIN_GALLERY} className={({ isActive }) => (isActive ? "cur" : "")}>사이트갤러리관리</NavLink></li>
<li><NavLink to={URL.ADMIN_MANAGER} className={({ isActive }) => (isActive ? "cur" : "")}>사이트관리자 암호변경</NavLink></li>
</ul>
</Accordion.Body>
</Accordion.Item>
</Accordion> </Accordion>
</div> </div>

View File

@ -251,6 +251,7 @@ select::-ms-expand {display:none;}
.active {background-color: #007bff; color: #fff;} .active {background-color: #007bff; color: #fff;}
.f_input {height: 46px; padding: 0 20px; border: 0; border-radius: 5px; color: #222; font-size: 16px; background: #f7f7f7;} .f_input {height: 46px; padding: 0 20px; border: 0; border-radius: 5px; color: #222; font-size: 16px; background: #f7f7f7;}
.f_input1 {width:200px; height: 32px; padding: 0 30px 0 0; border: 0; border-radius: 5px; color: #222; font-size: 16px; background: #f7f7f7 url(css/images/bg_btn_calendar.png) no-repeat;background-position: right center; background-size: 32px 32px; cursor: pointer;} /* made by lim f_input1*/
.f_input2 {height: 46px; padding: 0 20px; border: 1px solid #dde2e5; border-radius: 5px !important; color: #222; font-size: 16px; background: #fff;} .f_input2 {height: 46px; padding: 0 20px; border: 1px solid #dde2e5; border-radius: 5px !important; color: #222; font-size: 16px; background: #fff;}
.f_txtar {padding: 10px 19px; border: 1px solid #dde2e5; border-radius: 5px; color: #222; font-size: 16px; line-height: 24px; resize: none;} .f_txtar {padding: 10px 19px; border: 1px solid #dde2e5; border-radius: 5px; color: #222; font-size: 16px; line-height: 24px; resize: none;}
@ -301,4 +302,30 @@ select::-ms-expand {display:none;}
.react-datepicker__input-container {display: inline-block; vertical-align: top; width: auto;} .react-datepicker__input-container {display: inline-block; vertical-align: top; width: auto;}
/* 리액트 관련 */ /* 리액트 관련 */
.react-datepicker__tab-loop {display: inline-block;} .react-datepicker__tab-loop {display: inline-block;}
/* recharts */
.recharts-tooltip-wrapper .custom-tooltip {
background-color: hsla(0,0%,100%,.8);
border: 1px solid #f5f5f5;
line-height: 24px;
margin: 0;
padding: 10px;
width: 200px
}
.recharts-tooltip-wrapper .custom-tooltip .label {
color: #666;
margin: 0
}
.recharts-tooltip-wrapper .custom-tooltip .desc {
color: #999;
margin: 0
}
.recharts-tooltip-wrapper .custom-tooltip .intro {
border-top: 1px solid #f5f5f5;
font-weight: 700;
margin: 0
}

View File

@ -14,6 +14,7 @@
.Plogin .login_box button span {display: block; position: relative; height: 100%;} .Plogin .login_box button span {display: block; position: relative; height: 100%;}
.Plogin .login_box .chk {margin-top: 20px;} .Plogin .login_box .chk {margin-top: 20px;}
.Plogin .login_box .chk em {display: inline-block; height: 30px; margin-left: 40px; color: #666; font-size: 16px;} .Plogin .login_box .chk em {display: inline-block; height: 30px; margin-left: 40px; color: #666; font-size: 16px;}
.Plogin .login_box .chk label {display: inline-block; height: 30px; color: #666; font-size: 16px;}
.Plogin .list {margin-top: 44px; padding: 0 360px;} .Plogin .list {margin-top: 44px; padding: 0 360px;}
.Plogin .list li {position: relative; padding-left: 15px; color: #666; font-size: 16px; line-height: 26px;} .Plogin .list li {position: relative; padding-left: 15px; color: #666; font-size: 16px; line-height: 26px;}
.Plogin .list li::before {content: ""; display: block; position: absolute; left: 0; top: 12px; width: 4px; height: 4px; background: #666;} .Plogin .list li::before {content: ""; display: block; position: absolute; left: 0; top: 12px; width: 4px; height: 4px; background: #666;}
@ -168,6 +169,28 @@
.userList .result .list_item > div:nth-child(6) {width: 100px;} .userList .result .list_item > div:nth-child(6) {width: 100px;}
.userList .result .list_item > div:nth-child(7) {width: 100px;} .userList .result .list_item > div:nth-child(7) {width: 100px;}
/* 사이트관리 > 환경설정 > 메뉴관리 */
.menuList .head > span:nth-child(1) {width: 60px;}
.menuList .head > span:nth-child(2) {width: 100px;}
.menuList .head > span:nth-child(3) {width: 100px;}
.menuList .head > span:nth-child(4) {width: 120px;}
.menuList .head > span:nth-child(5) {width: 100px;}
.menuList .head > span:nth-child(6) {width: 100px;}
.menuList .head > span:nth-child(7) {width: 100px;}
.menuList .head > span:nth-child(8) {width: 100px;}
.menuList .head > span:nth-child(9) {width: 100px;}
.menuList .head > span:nth-child(10) {width: 100px;}
.menuList .result .list_item > div:nth-child(1) {width: 60px;}
.menuList .result .list_item > div:nth-child(2) {width: 100px;}
.menuList .result .list_item > div:nth-child(3) {width: 100px;}
.menuList .result .list_item > div:nth-child(4) {width: 120px;}
.menuList .result .list_item > div:nth-child(5) {width: 100px;}
.menuList .result .list_item > div:nth-child(6) {width: 100px;}
.menuList .result .list_item > div:nth-child(7) {width: 100px;}
.menuList .result .list_item > div:nth-child(8) {width: 100px;}
.menuList .result .list_item > div:nth-child(9) {width: 100px;}
.menuList .result .list_item > div:nth-child(10) {width: 100px;}
/* 사이트소개 */ /* 사이트소개 */
.SITE_INTRO .ds_1 .t_1 {margin-top: 52px; color: #000; font-size: 26px; font-weight: 500; text-align: center;} .SITE_INTRO .ds_1 .t_1 {margin-top: 52px; color: #000; font-size: 26px; font-weight: 500; text-align: center;}
.SITE_INTRO .ds_1 .li_1 {position: relative; margin-top: 34px; font-size: 0; text-align: center;} .SITE_INTRO .ds_1 .li_1 {position: relative; margin-top: 34px; font-size: 0; text-align: center;}
@ -250,6 +273,12 @@
.BRD009 .result .list_item > div:nth-child(5) {width: 150px;} .BRD009 .result .list_item > div:nth-child(5) {width: 150px;}
.BRD009 .result .list_item > div:nth-child(6) {width: 150px;} .BRD009 .result .list_item > div:nth-child(6) {width: 150px;}
/* 로그현황 - 메뉴별/사용자별 접속현황*/
.BRD010 .head > span:nth-child(1) {width: 60%;}
.BRD010 .head > span:nth-child(2) {width: 40%;}
.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%;}
/* 게시판 사용관리 등록 */ /* 게시판 사용관리 등록 */
.BOARD_USE_LIST .board_view2 dl dt {width: 185px;} .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;} .BOARD_USE_LIST .board_view2 dl:nth-child(2) dd .f_input2 {width: 490px; margin-left: 17px;}

View File

@ -447,6 +447,13 @@
.BRD009 .result .list_item > div:nth-child(6)::after {content: ""; display: inline-block; width: 1px; height: 11px; margin-left: 6px; background: #ccc; vertical-align: 0px;} .BRD009 .result .list_item > div:nth-child(6)::after {content: ""; display: inline-block; width: 1px; height: 11px; margin-left: 6px; background: #ccc; vertical-align: 0px;}
.BRD009 .result .list_item > div:nth-child(6)::after {content: none;} .BRD009 .result .list_item > div:nth-child(6)::after {content: none;}
/* 로그현황 - 메뉴별/사용자별 접속현황*/
.BRD010 .head {border-top: 1px solid #dde2e5;}
.BRD010 .result .list_item {padding: 16px 0; border-bottom: 1px solid #dde2e5;}
.BRD010 .result .list_item > div {border-bottom: 0; font-size: 14px;}
.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;}
.BOARD_USE_LIST .board_view2 dl dt {width: 95px;} .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_select {width: 100%;}
.BOARD_USE_LIST .board_view2 dl:nth-child(2) dd .f_input2 {width: 100%; margin: 15px 0 0 0;} .BOARD_USE_LIST .board_view2 dl:nth-child(2) dd .f_input2 {width: 100%; margin: 15px 0 0 0;}
@ -553,5 +560,7 @@
.BRD009 .result .list_item > div:nth-child(4)::after, .BRD009 .result .list_item > div:nth-child(4)::after,
.BRD009 .result .list_item > div:nth-child(5)::after, .BRD009 .result .list_item > div:nth-child(5)::after,
.BRD009 .result .list_item > div:nth-child(6)::after {margin-left: 15px;} .BRD009 .result .list_item > div:nth-child(6)::after {margin-left: 15px;}
/* 로그현황 - 메뉴별/사용자별 접속현황*/
/*.BRD010 .result .list_item > div:nth-child(1)*/
} }

View File

@ -1,11 +1,54 @@
import React from 'react'; import React, {useCallback, useEffect, useState} from 'react';
import {Link} from "react-router-dom";
import URL from "constants/url";
import { default as EgovLeftNav } from 'components/leftmenu/EgovLeftNavAdmin';
function MenuMgt(props) { function MenuMgt({}) {
return ( return (
<div className="container"> <div className="container">
MenuMgt <div className="c_wrap">
<div className="location">
<ul>
<li><Link to={URL.MAIN} className="home">Home</Link></li>
<li>사이트관리</li>
<li>환경설정</li>
<li><Link to={URL.ADMIN__USERS__LIST}>메뉴 관리</Link></li>
</ul>
</div>
<div className="layout">
{/* <!-- Navigation --> */}
<EgovLeftNav/>
<div className="contents NOTICE_LIST" id="contents">
{/* <!-- 본문 --> */}
<div className="top_tit">
<h1 className="tit_1">메뉴 관리</h1>
</div>
<h2 className="tit_2"></h2>
<div className="board_list menuList">
<div className="head">
<span>아이디</span>
<span>이름</span>
<span>그룹</span>
<span>레벨</span>
<span>정렬</span>
<span>URI</span>
<span>타입</span>
<span>CSS</span>
<span>IMG</span>
<span>삭제</span>
</div>
<div className="result">
{/*{listTag}*/}
</div>
</div>
</div>
</div>
</div>
</div> </div>
); );
} }

View File

@ -1,13 +1,230 @@
import React from 'react'; import React, {useState, useEffect, useCallback, useRef, PureComponent} from 'react';
import { Link, useLocation } from 'react-router-dom';
import {BarChart, Bar, Rectangle, XAxis, YAxis, CartesianGrid, Tooltip, Legend, ResponsiveContainer} from 'recharts';
import DatePicker from 'react-datepicker';
import 'react-datepicker/dist/react-datepicker.css';
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 MenuAccessInfo(props) { function MenuConnections(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 [listTag, setListTag] = useState([]);
const retrieveList = useCallback((srchCnd) => {
// console.groupCollapsed("EgovAdminUsageList.retrieveList()");
const retrieveListURL = '/admin/logs/menu';
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(<p className="no_data" key="0">데이터가 없습니다.</p>);
} else {
resp.result.resultList.forEach(function (item, index) {
// if (index === 0) mutListTag = []; //
const listIdx = itemIdxByPage(resultCnt, currentPageNo, pageSize, index);
mutListTag.push(
<div key={listIdx} className="list_item">
<div>{item[1]}</div>
<div style={{textAlign: 'right', paddingRight: '10px'}}>{item[2].toLocaleString()}</div>
</div>
);
});
}
setListTag(mutListTag);
let chartDataArray = resp.result.resultList.map((item, index) => ({
logCnt: item[1], // Assuming logCnt is the x-axis data
"접속수": item[2], // Assuming menuTitle is the y-axis data
}));
setChartData(chartDataArray);
},
function (resp) {
console.log("err response : ", resp);
}
);
// console.groupEnd("EgovAdminPrivacyList.retrieveList()");
},[listTag]);
const CustomTooltip = ({ active, payload, label }) => {
if (active && payload && payload.length) {
return (
<div className="custom-tooltip">
<p className="intro">메뉴별 접속현황</p>
<p className="label">{`${label} : ${payload[0].value}`}</p>
{/*<p className="desc">Anything you want can be displayed here.</p>*/}
</div>
);
}
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 ( return (
<div className="container"> <div className="container">
MenuAccessInfo <div className="c_wrap">
{/* <!-- Location --> */}
<div className="location">
<ul>
<li><Link to={URL.MAIN} className="home">Home</Link></li>
<li><Link to={URL.ADMIN} >사이트관리</Link></li>
<li>로그현황</li>
<li>메뉴별 접속현황</li>
</ul>
</div>
{/* <!--// Location --> */}
<div className="layout">
{/* <!-- Navigation --> */}
<EgovLeftNav></EgovLeftNav>
{/* <!--// Navigation --> */}
<div className="contents NOTICE_LIST" id="contents">
{/* <!-- 본문 --> */}
<div className="top_tit">
<h1 className="tit_1">메뉴별 접속현황</h1>
</div>
{/* <!-- 검색조건 --> */}
<div className="condition">
<ul>
<li className="half L">
<DatePicker
dateFormat='yyyy-MM-dd' //
shouldCloseOnSelect // datepicker
minDate={new Date('2017-01-01')} // minDate
maxDate={new Date()} // maxDate
selected={start_date}
locale={ko}
className="f_input1 al_c"
selectsStart
startDate={start_date}
endDate={end_date}
onChange={(date) => {
setStartDate(date);
setSearchCondition({
start_date: format(date, "yyyy-MM-dd"),
end_date: format(end_date, "yyyy-MM-dd")
});
}}
/> -
</li>
<li className="half R">
<DatePicker
dateFormat='yyyy-MM-dd' //
shouldCloseOnSelect // datepicker
minDate={new Date('2017-01-01')} // minDate
maxDate={new Date()} // maxDate
selected={end_date}
locale={ko}
className="f_input1 al_c"
selectsEnd
startDate={start_date}
endDate={end_date}
onChange={(date) => {
setEndDate(date);
setSearchCondition({
start_date: format(start_date, "yyyy-MM-dd"),
end_date: format(date, "yyyy-MM-dd")
});
}}
/>
</li>
</ul>
</div>
{/* <!--// 검색조건 --> */}
{/* <!-- 목록 --> */}
<div className="logs_list row">
<div className="col-sm-4 pe-0">
<div className="board_list BRD010">
<div className="head">
<span>메뉴명</span>
<span>접속횟수</span>
</div>
<div className="result overflow-auto">
{listTag}
</div>
</div>
</div>
<div className="col-sm-8 ps-0">
<ResponsiveContainer width="100%" height={477}>
<BarChart data={chartData} layout="vertical"
height={477}
margin={{
top: 0,
right: 0,
left: 20,
bottom: 0,
}}
>
<CartesianGrid strokeDasharray="3 3" />
<XAxis type="number" />
<YAxis type="category" dataKey="logCnt" tick={{ fontSize: 10, whiteSpace: 'nowrap' }} />
<Tooltip content={<CustomTooltip/>} />
<Legend />
<Bar dataKey="접속수" fill="#87CEFA" activeBar={<Rectangle fill="gold" stroke="purple" />} />
</BarChart>
</ResponsiveContainer>
</div>
</div>
{/* <!--// 목록 --> */}
{/* <!--// 본문 --> */}
</div>
</div>
</div>
</div> </div>
); );
} }
export default MenuAccessInfo; export default MenuConnections;

View File

@ -96,6 +96,7 @@ function PrivacyConnections(props) {
<li><Link to={URL.MAIN} className="home">Home</Link></li> <li><Link to={URL.MAIN} className="home">Home</Link></li>
<li><Link to={URL.ADMIN} >사이트관리</Link></li> <li><Link to={URL.ADMIN} >사이트관리</Link></li>
<li>로그현황</li> <li>로그현황</li>
<li>개인정보 로그현황</li>
</ul> </ul>
</div> </div>
{/* <!--// Location --> */} {/* <!--// Location --> */}
@ -112,7 +113,7 @@ function PrivacyConnections(props) {
<h1 className="tit_1">개인정보 로그현황</h1> <h1 className="tit_1">개인정보 로그현황</h1>
</div> </div>
{/* <!-- 게시판목록 --> */} {/* <!-- 개인정보 로그목록 --> */}
<div className="board_list BRD009"> <div className="board_list BRD009">
<div className="head"> <div className="head">
<span>번호</span> <span>번호</span>
@ -126,7 +127,7 @@ function PrivacyConnections(props) {
{listTag} {listTag}
</div> </div>
</div> </div>
{/* <!--// 게시판목록 --> */} {/* <!--// 개인정보 로그목록 --> */}
<div className="board_bot"> <div className="board_bot">
{/* <!-- Paging --> */} {/* <!-- Paging --> */}

View File

@ -1,11 +1,228 @@
import React from 'react'; import React, {useState, useEffect, useCallback, useRef, PureComponent} from 'react';
import { Link, useLocation } from 'react-router-dom';
import {BarChart, Bar, Rectangle, XAxis, YAxis, CartesianGrid, Tooltip, Legend, ResponsiveContainer} from 'recharts';
import DatePicker from 'react-datepicker';
import 'react-datepicker/dist/react-datepicker.css';
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 UserConnections(props) { function UserConnections(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 [listTag, setListTag] = useState([]);
const retrieveList = useCallback((srchCnd) => {
// console.groupCollapsed("EgovAdminUsageList.retrieveList()");
const retrieveListURL = '/admin/logs/user';
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(<p className="no_data" key="0">데이터가 없습니다.</p>);
} else {
resp.result.resultList.forEach(function (item, index) {
// if (index === 0) mutListTag = []; //
const listIdx = itemIdxByPage(resultCnt, currentPageNo, pageSize, index);
mutListTag.push(
<div key={listIdx} className="list_item">
<div>{item[0]}</div>
<div style={{textAlign: 'right', paddingRight: '10px'}}>{item[1].toLocaleString()}</div>
</div>
);
});
}
setListTag(mutListTag);
let chartDataArray = resp.result.resultList.map((item, index) => ({
logCnt: item[0], // Assuming logCnt is the x-axis data
"접속수": item[1], // Assuming menuTitle is the y-axis data
}));
setChartData(chartDataArray);
},
function (resp) {
console.log("err response : ", resp);
}
);
// console.groupEnd("EgovAdminPrivacyList.retrieveList()");
},[listTag]);
const CustomTooltip = ({ active, payload, label }) => {
if (active && payload && payload.length) {
return (
<div className="custom-tooltip">
<p className="intro">사용자 접속현황</p>
<p className="label">{`${label} : ${payload[0].value}`}</p>
{/*<p className="desc">Anything you want can be displayed here.</p>*/}
</div>
);
}
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 ( return (
<div className="container"> <div className="container">
UserConnections <div className="c_wrap">
{/* <!-- Location --> */}
<div className="location">
<ul>
<li><Link to={URL.MAIN} className="home">Home</Link></li>
<li><Link to={URL.ADMIN} >사이트관리</Link></li>
<li>로그현황</li>
<li>사용자 접속현황</li>
</ul>
</div>
{/* <!--// Location --> */}
<div className="layout">
{/* <!-- Navigation --> */}
<EgovLeftNav></EgovLeftNav>
{/* <!--// Navigation --> */}
<div className="contents NOTICE_LIST" id="contents">
{/* <!-- 본문 --> */}
<div className="top_tit">
<h1 className="tit_1">사용자 접속현황</h1>
</div>
{/* <!-- 검색조건 --> */}
<div className="condition">
<ul>
<li className="half L">
<DatePicker
dateFormat='yyyy-MM-dd' //
shouldCloseOnSelect // datepicker
minDate={new Date('2017-01-01')} // minDate
maxDate={new Date()} // maxDate
selected={start_date}
locale={ko}
className="f_input1 al_c"
selectsStart
startDate={start_date}
endDate={end_date}
onChange={(date) => {
setStartDate(date);
setSearchCondition({
start_date: format(date, "yyyy-MM-dd"),
end_date: format(end_date, "yyyy-MM-dd")
});
}}
/> -
</li>
<li className="half R">
<DatePicker
dateFormat='yyyy-MM-dd' //
shouldCloseOnSelect // datepicker
minDate={new Date('2017-01-01')} // minDate
maxDate={new Date()} // maxDate
selected={end_date}
locale={ko}
className="f_input1 al_c"
selectsEnd
startDate={start_date}
endDate={end_date}
onChange={(date) => {
setEndDate(date);
setSearchCondition({
start_date: format(start_date, "yyyy-MM-dd"),
end_date: format(date, "yyyy-MM-dd")
});
}}
/>
</li>
</ul>
</div>
{/* <!--// 검색조건 --> */}
{/* <!-- 목록 --> */}
<div className="logs_list row">
<div className="col-sm-4 pe-0">
<div className="board_list BRD010">
<div className="head">
<span>접속일자</span>
<span>접속횟수</span>
</div>
<div className="result overflow-auto">
{listTag}
</div>
</div>
</div>
<div className="col-sm-8 ps-0">
<ResponsiveContainer width="100%" height={477}>
<BarChart data={chartData} layout="vertical"
height={477}
margin={{
top: 0,
right: 0,
left: 20,
bottom: 0,
}}
>
<CartesianGrid strokeDasharray="3 3" />
<XAxis type="number" />
<YAxis type="category" dataKey="logCnt" tick={{ fontSize: 10, whiteSpace: 'nowrap' }} />
<Tooltip content={<CustomTooltip/>} />
<Legend />
<Bar dataKey="접속수" fill="#87CEFA" activeBar={<Rectangle fill="gold" stroke="purple" />} />
</BarChart>
</ResponsiveContainer>
</div>
</div>
{/* <!--// 목록 --> */}
{/* <!--// 본문 --> */}
</div>
</div>
</div>
</div> </div>
); );
} }

View File

@ -337,82 +337,13 @@ function EgovAdminScheduleList(props) {
<h1 className="tit_1">사이트관리</h1> <h1 className="tit_1">사이트관리</h1>
</div> </div>
<h2 className="tit_2">일정관리</h2> <h2 className="tit_2"></h2>
<ChartToggle isDailyChart={isDailyChart} onToggle={handleChartToggle}/> <ChartToggle isDailyChart={isDailyChart} onToggle={handleChartToggle}/>
<div style={{width: 1000, height: 300}}> <div style={{width: 1000, height: 300}}>
<UserLogChart/> <UserLogChart/>
</div> </div>
{/* <!-- 검색조건 --> */}
<div className="condition">
<ul>
<li>
<label className="f_select" htmlFor="sel1">
<select name="schdulSe" id="sel1" title="조건"
onChange={e => {
setSearchCondition({...searchCondition, schdulSe: e.target.value});
}}
>
<option value="">전체</option>
<option value="1">회의</option>
<option value="2">세미나</option>
<option value="3">강의</option>
<option value="4">교육</option>
<option value="5">기타</option>
</select>
</label>
</li>
<li className="half L">
<button className="prev"
onClick={() => {
changeDate(CODE.DATE_YEAR, -1);
}}
></button>
<span>{searchCondition.year}</span>
<button className="next"
onClick={() => {
changeDate(CODE.DATE_YEAR, 1);
}}
></button>
</li>
<li className="half R">
<button className="prev"
onClick={() => {
changeDate(CODE.DATE_MONTH, -1);
}}
></button>
<span>{(searchCondition.month + 1)}</span>
<button className="next"
onClick={() => {
changeDate(CODE.DATE_MONTH, 1);
}}
></button>
</li>
</ul>
</div>
{/* <!--// 검색조건 --> */}
<div className="calendar_list">
<table>
<thead>
<tr>
<th></th>
<th></th>
<th></th>
<th></th>
<th></th>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
{calendarTag}
</tbody>
</table>
</div>
{/* <!--// 본문 --> */}
</div> </div>
</div> </div>
</div> </div>

View File

@ -1,26 +1,27 @@
import React, {useCallback, useEffect, useRef, useState} from 'react'; import React, {useCallback, useEffect, useState} from 'react';
import {Link, useLocation} from "react-router-dom"; import {Link} from "react-router-dom";
import URL from "constants/url"; import URL from "constants/url";
import { default as EgovLeftNav } from 'components/leftmenu/EgovLeftNavAdmin'; import { default as EgovLeftNav } from 'components/leftmenu/EgovLeftNavAdmin';
import EgovPaging from "components/EgovPaging"; import EgovPaging from "components/EgovPaging";
import * as EgovNet from "api/egovFetch"; import * as EgovNet from "api/egovFetch";
import {itemIdxByPage} from "utils/calc";
import Modal from "react-bootstrap/Modal"; import Modal from "react-bootstrap/Modal";
import UserInfoModal from "./UserInfoModal"; import UserInfoModal from "./UserInfoModal";
import CODE from "../../../constants/code";
function List(props) { function List({}) {
const location = useLocation(); const [searchCondition, setSearchCondition] = useState({
pageIndex: 1,
userSe: '',
searchCondition: 'id',
searchKeyword: ''
});
const [searchCondition, setSearchCondition] = useState(location.state?.searchCondition || { pageIndex: 1, searchCnd: '0', searchWrd: '' });// ||
const [listTag, setListTag] = useState([]); const [listTag, setListTag] = useState([]);
const [paginationInfo, setPaginationInfo] = useState({}); const [paginationInfo, setPaginationInfo] = useState({});
const cndRef = useRef();
const wrdRef = useRef();
const [show, setShow] = useState(false); const [show, setShow] = useState(false);
const [modalBody, setModalBody] = useState(); const [modalBody, setModalBody] = useState();
@ -28,7 +29,7 @@ function List(props) {
const handleShow = () => setShow(true); const handleShow = () => setShow(true);
const retrieveList = useCallback((searchCondition) => { const retrieveList = useCallback((searchCondition) => {
const params = "?"; const params = EgovNet.convParams(searchCondition);
EgovNet.requestFetch( EgovNet.requestFetch(
'/admin/users/list'+params, '/admin/users/list'+params,
{ {
@ -36,28 +37,20 @@ function List(props) {
}, },
(resp) => { (resp) => {
setPaginationInfo(resp.result.paginationInfo); setPaginationInfo(resp.result.paginationInfo);
let mutListTag = []; let mutListTag = [];
const resultCnt = parseInt(resp.result.contentCnt);
const currentPageNo = resp.result.paginationInfo.pageIndex;
const pageSize = resp.result.paginationInfo.rowCnt;
setListTag([]); setListTag([]);
// //
resp.result.userList.forEach(function (item, index) { resp.result.userList.forEach(function (item, index) {
const listIdx = itemIdxByPage(resultCnt , currentPageNo, pageSize, index);
mutListTag.push( mutListTag.push(
<div className={"list_item"}> <div className={"list_item"} key={"userListDiv_"+index}>
<div>{item.userSe}</div> <div>{item.userSe}</div>
<div><a href={"#"} onClick={()=>{userInfoModal(item.userSeq)}}>{item.userId}</a></div> <div><a href={"#"} onClick={()=>{userInfoModal(item.userSeq)}}>{item.userId}</a></div>
<div>{item.userNm}</div> <div>{item.userNm}</div>
<div>{item.email}</div> <div>{item.email}</div>
<div>{item.phoneNum}</div> <div>{item.phoneNum}</div>
<div>{item.status}</div> <div>{item.status}</div>
<div><button className={"btn btn_red_h31 px-1"}>삭제</button></div> <div><button className={"btn btn_red_h31 px-1"} onClick={()=>{removeUserInfo(item.userSeq)}}>삭제</button></div>
</div> </div>
); );
}); });
@ -74,10 +67,41 @@ function List(props) {
retrieveList(searchCondition); retrieveList(searchCondition);
}, []); }, []);
useEffect(() => {
retrieveList(searchCondition);
}, [searchCondition.pageIndex]);
const movePage = useCallback((passedPage) => {
setSearchCondition({...searchCondition, pageIndex: passedPage})
});
function userInfoModal(userSeq){ function userInfoModal(userSeq){
handleShow() handleShow()
setModalBody(<UserInfoModal userSeq={userSeq}></UserInfoModal>) setModalBody(<UserInfoModal userSeq={userSeq} reloadFunction={retrieveList}></UserInfoModal>)
} }
const removeUserInfo = useCallback((seq)=>{
if(window.confirm("삭제하시겠습니까?\n복구할 수 없습니다.")){
EgovNet.requestFetch(
'/admin/users/info',
{
method: "DELETE",
headers: {
'Content-type': 'application/json'
},
body: JSON.stringify({userSeq: seq})
},
(resp) => {
if (Number(resp.resultCode) === Number(CODE.RCV_SUCCESS)) {
alert("삭제되었습니다.")
retrieveList(searchCondition)
}else{
alert("삭제를 실패하였습니다.")
}
}
)
}
});
return ( return (
<div className="container"> <div className="container">
@ -105,18 +129,19 @@ function List(props) {
<ul> <ul>
<li className="third_1 L"> <li className="third_1 L">
<label className="f_select" htmlFor="sel1"> <label className="f_select" htmlFor="sel1">
<select id="sel1" title="조건" defaultValue={searchCondition.searchCnd} ref={cndRef}
onChange={e => {cndRef.current.value = e.target.value;}}> <select id="sel1" title="구분" defaultValue={searchCondition.userSe}
<option value="0">전체</option> onChange={(e) => {setSearchCondition({...searchCondition, userSe: e.target.value})}}>
<option value="1">일반사용자</option> <option value="">전체</option>
<option value="2">관리자</option> <option value="ACC_TP01">관리자</option>
<option value="ACC_TP02">일반사용자</option>
</select> </select>
</label> </label>
</li> </li>
<li className="third_1 L"> <li className="third_1 L">
<label className="f_select" htmlFor="sel1"> <label className="f_select" htmlFor="sel1">
<select id="sel1" title="조건" defaultValue={searchCondition.searchCnd} ref={cndRef} <select id="sel1" title="조건" defaultValue={searchCondition.searchCondition}
onChange={e => {cndRef.current.value = e.target.value;}}> onChange={(e) => {setSearchCondition({...searchCondition, searchCondition: e.target.value})}}>
<option value="id">아이디</option> <option value="id">아이디</option>
<option value="name">이름</option> <option value="name">이름</option>
<option value="email">이메일</option> <option value="email">이메일</option>
@ -126,15 +151,9 @@ function List(props) {
</li> </li>
<li className="third_2 R"> <li className="third_2 R">
<span className="f_search w_500"> <span className="f_search w_500">
<input type="text" name="" defaultValue={searchCondition.searchWrd} placeholder="" ref={wrdRef} <input type="text" name="" defaultValue={searchCondition.searchKeyword} placeholder=""
onChange={e => { onChange={(e) => {setSearchCondition({...searchCondition, searchKeyword: e.target.value})}}/>
wrdRef.current.value = e.target.value; <button type="button" onClick={() => {retrieveList(searchCondition)}}>조회</button>
}}
/>
<button type="button"
onClick={() => {
retrieveList({ ...searchCondition, pageIndex: 1, searchCnd: cndRef.current.value, searchWrd: wrdRef.current.value });
}}>조회</button>
</span> </span>
</li> </li>
</ul> </ul>
@ -156,15 +175,7 @@ function List(props) {
</div> </div>
<div className="board_bot"> <div className="board_bot">
<EgovPaging pagination={paginationInfo} <EgovPaging pagination={paginationInfo} moveToPage={passedPage => {movePage(passedPage)}} />
moveToPage={passedPage => {
retrieveList({
...searchCondition,
pageIndex: passedPage,
searchCnd: cndRef.current.value,
searchWrd: wrdRef.current.value
})
}} />
</div> </div>
</div> </div>
</div> </div>

View File

@ -1,14 +1,17 @@
import React, {useEffect, useState} from "react" import React, {useCallback, useEffect, useState} from "react"
import Modal from "react-bootstrap/Modal"; import Modal from "react-bootstrap/Modal";
import * as EgovNet from "../../../api/egovFetch"; import * as EgovNet from "api/egovFetch";
import Form from "react-bootstrap/Form"; import Form from "react-bootstrap/Form";
import Row from "react-bootstrap/Row"; import Row from "react-bootstrap/Row";
import Col from "react-bootstrap/Col"; import Col from "react-bootstrap/Col";
import Button from "react-bootstrap/Button"; import Button from "react-bootstrap/Button";
import SelectOption from "components/commonCode/SelectOption";
import CheckBox from "components/commonCode/CheckBox";
import CODE from "../../../constants/code";
function UserInfoModal({userSeq}){ function UserInfoModal({userSeq, reloadFunction}){
const [userInfo, setUserInfo] = useState({ userId: '', password: '', passwordChk: '', userNm: '', email: '', phoneNum: ''}); const [userInfo, setUserInfo] = useState({ userSeq: '', userId: '', password: '', passwordChk: '', userNm: '', email: '', phoneNum: '', userSe:'', userRole:'', status:''});
function getModalContent(){ function getModalContent(){
EgovNet.requestFetch( EgovNet.requestFetch(
@ -17,15 +20,20 @@ function UserInfoModal({userSeq}){
method: "GET" method: "GET"
}, },
(resp) => { (resp) => {
const respInfo = { const respInfo = resp.result.userInfo;
userId: resp.result.userInfo.userId, const info = {
userNm: resp.result.userInfo.userNm, userSeq: respInfo.userSeq,
email: resp.result.userInfo.email, userId: respInfo.userId,
phoneNum: resp.result.userInfo.phoneNum, userNm: respInfo.userNm,
email: respInfo.email,
phoneNum: respInfo.phoneNum,
password: "", password: "",
passwordChk: "", passwordChk: "",
userSe: respInfo.userSe,
userRole: respInfo.userRole,
status: respInfo.status
} }
setUserInfo(respInfo); setUserInfo(info);
}, },
(resp) => { (resp) => {
console.log("err response : ", resp); console.log("err response : ", resp);
@ -33,8 +41,51 @@ function UserInfoModal({userSeq}){
); );
} }
function userInfoChange(){ function userInfoChange(e){
e.preventDefault();
e.stopPropagation();
const form = e.target;
const info = {
userSeq: form.userSeq.value,
userId: form.userId.value,
password: form.password.value,
passwordChk: form.passwordChk.value,
userNm: form.userNm.value,
email: form.email.value,
phoneNum: form.phoneNum.value,
userSe: form.userSe.value,
userRole: '',
status: form.status.value,
}
let userRole = '';
form.userRole.forEach(function (input){
if(input.checked){
userRole += input.value+','
}
})
if(userRole){
info.userRole = userRole.slice(0, -1)
}
EgovNet.requestFetch(
'/admin/users/info',
{
method: "PUT",
headers: {
'Content-type': 'application/json'
},
body: JSON.stringify(info)
},
(resp) => {
if (Number(resp.resultCode) === Number(CODE.RCV_SUCCESS)) {
alert("저장되었습니다.")
reloadFunction();
}else if(Number(resp.resultCode) === Number(CODE.RCV_ERROR_AUTH)){
console.log("토큰 갱신중.")
}else{
alert(resp.result.resultMessage)
}
}
)
} }
useEffect(() => { useEffect(() => {
@ -43,89 +94,84 @@ function UserInfoModal({userSeq}){
return ( return (
<> <>
<Modal.Header className="bookmarkModalHeader" closeButton> <Modal.Header closeButton>
<Modal.Title> <Modal.Title>
{userInfo.userNm} 상세정보 {userInfo.userNm} 상세정보
</Modal.Title> </Modal.Title>
</Modal.Header> </Modal.Header>
<Modal.Body> <Modal.Body>
<Form onSubmit={userInfoChange} noValidate> <Form onSubmit={(e) =>{userInfoChange(e)}} noValidate>
<Form.Group as={Row} className="mb-3" controlId="formHorizontalEmail"> <input type={"hidden"} name={"userSeq"} defaultValue={userInfo.userSeq} />
<Form.Group as={Row} className="mb-3">
<Form.Label column sm={3}> <Form.Label column sm={3}>
아이디 아이디
</Form.Label> </Form.Label>
<Col sm={9}> <Col sm={9}>
<Form.Control type="text" name="userId" placeholder="아이디" required value={userInfo?.userId} <Form.Control type="text" name="userId" placeholder="아이디" required defaultValue={userInfo?.userId} readOnly/>
onChange={e => setUserInfo({ ...userInfo, userId: e.target.value })}/>
</Col> </Col>
</Form.Group> </Form.Group>
<Form.Group as={Row} className="mb-3" controlId="formHorizontalEmail"> <Form.Group as={Row} className="mb-3">
<Form.Label column sm={3}>
이름
</Form.Label>
<Col sm={9}>
<Form.Control type="text" name="userNm" placeholder="이름" required value={userInfo?.userNm}
onChange={e => setUserInfo({ ...userInfo, userNm: e.target.value })}/>
</Col>
</Form.Group>
<Form.Group as={Row} className="mb-3" controlId="formHorizontalEmail">
<Form.Label column sm={3}>
이메일
</Form.Label>
<Col sm={9}>
<Form.Control type="email" name="email" placeholder="email" required value={userInfo?.email}
onChange={e => setUserInfo({ ...userInfo, email: e.target.value })}/>
</Col>
</Form.Group>
<Form.Group as={Row} className="mb-3" controlId="formHorizontalEmail">
<Form.Label column sm={3}>
연락처
</Form.Label>
<Col sm={9}>
<Form.Control type="text" name="phoneNum" placeholder="연락처" required value={userInfo?.phoneNum}
onChange={e => setUserInfo({ ...userInfo, phoneNum: e.target.value })}/>
</Col>
</Form.Group>
<Form.Group as={Row} className="mb-3" controlId="formHorizontalEmail">
<Form.Label column sm={3}> <Form.Label column sm={3}>
비밀번호 비밀번호
</Form.Label> </Form.Label>
<Col sm={9}> <Col sm={9}>
<Form.Control type="password" name="password" placeholder="비밀번호 변경 시 입력" <Form.Control type="password" name="password" placeholder="비밀번호 변경 시 입력" />
onChange={e => setUserInfo({ ...userInfo, password: e.target.value })}/>
</Col> </Col>
</Form.Group> </Form.Group>
<Form.Group as={Row} className="mb-3" controlId="formHorizontalEmail"> <Form.Group as={Row} className="mb-3">
<Form.Label column sm={3}> <Form.Label column sm={3}>
비밀번호 확인 비밀번호 확인
</Form.Label> </Form.Label>
<Col sm={9}> <Col sm={9}>
<Form.Control type="password" name="passwordChk" placeholder="비밀번호 변경 시 입력" <Form.Control type="password" name="passwordChk" placeholder="비밀번호 변경 시 입력" />
onChange={e => setUserInfo({ ...userInfo, passwordChk: e.target.value })}/>
</Col> </Col>
</Form.Group> </Form.Group>
<Form.Group as={Row} className="mb-3" controlId="formHorizontalEmail"> <Form.Group as={Row} className="mb-3">
<Form.Label column sm={3}>
이름
</Form.Label>
<Col sm={9}>
<Form.Control type="text" name="userNm" placeholder="이름" required defaultValue={userInfo?.userNm} />
</Col>
</Form.Group>
<Form.Group as={Row} className="mb-3">
<Form.Label column sm={3}>
이메일
</Form.Label>
<Col sm={9}>
<Form.Control type="email" name="email" placeholder="email" required defaultValue={userInfo?.email} />
</Col>
</Form.Group>
<Form.Group as={Row} className="mb-3">
<Form.Label column sm={3}>
연락처
</Form.Label>
<Col sm={9}>
<Form.Control type="text" name="phoneNum" placeholder="연락처" required defaultValue={userInfo?.phoneNum} />
</Col>
</Form.Group>
<Form.Group as={Row} className="mb-3">
<Form.Label column sm={3}> <Form.Label column sm={3}>
사용자 유형 사용자 유형
</Form.Label> </Form.Label>
<Col sm={9}> <Col sm={9}>
<SelectOption name={"userSe"} grpCd={"ACC_TYPE"} selectedValue={userInfo?.userSe} />
</Col> </Col>
</Form.Group> </Form.Group>
<Form.Group as={Row} className="mb-3" controlId="formHorizontalEmail"> <Form.Group as={Row} className="mb-3">
<Form.Label column sm={3}> <Form.Label column sm={3}>
사용자 권한 사용자 권한
</Form.Label> </Form.Label>
<Col sm={9}> <Col sm={9}>
<CheckBox name={"userRole"} grpCd={"ROLE"} selectedValue={userInfo?.userRole} />
</Col> </Col>
</Form.Group> </Form.Group>
<Form.Group as={Row} className="mb-3" controlId="formHorizontalEmail"> <Form.Group as={Row} className="mb-3">
<Form.Label column sm={3}> <Form.Label column sm={3}>
상태 상태
</Form.Label> </Form.Label>
<Col sm={9}> <Col sm={9}>
<SelectOption name={"status"} grpCd={"ACC_STUS"} selectedValue={userInfo?.status} />
</Col> </Col>
</Form.Group> </Form.Group>
<Row className="mb-3"> <Row className="mb-3">

View File

@ -5,6 +5,7 @@ import {parseJwt} from "../../utils/parseJwt";
import URL from 'constants/url'; import URL from 'constants/url';
import CODE from 'constants/code'; import CODE from 'constants/code';
import Form from "react-bootstrap/Form";
import Row from 'react-bootstrap/Row'; import Row from 'react-bootstrap/Row';
import Col from 'react-bootstrap/Col'; import Col from 'react-bootstrap/Col';
import Modal from "react-bootstrap/Modal"; import Modal from "react-bootstrap/Modal";
@ -55,10 +56,8 @@ function EgovLoginContent(props) {
if (idFlag === false) { if (idFlag === false) {
setLocalItem(KEY_ID, ""); setLocalItem(KEY_ID, "");
checkRef.current.className = "f_chk"
} else { } else {
checkRef.current.className = "f_chk on" }
};
}, []); }, []);
useEffect(() => { useEffect(() => {
@ -143,9 +142,11 @@ function EgovLoginContent(props) {
</span> </span>
<Row className="chk justify-content-between"> <Row className="chk justify-content-between">
<Col xs={3}> <Col xs={3}>
<label className="f_chk" htmlFor="saveid" ref={checkRef}> <Form.Check inline label={"ID 저장"} id={"saveid"} name={""} checked={saveIDFlag} onChange={handleSaveIDFlag}/>
{/*<label className="f_chk" htmlFor="saveid" ref={checkRef}>
<input type="checkbox" name="" id="saveid" onChange={handleSaveIDFlag} checked={saveIDFlag}/> <em>ID저장</em> <input type="checkbox" name="" id="saveid" onChange={handleSaveIDFlag} checked={saveIDFlag}/> <em>ID저장</em>
</label> </label>*/}
</Col> </Col>
<Col xs={"auto"}> <Col xs={"auto"}>
<em className="clickable" onClick={idFindModal}>ID 찾기</em> <em className="clickable" onClick={idFindModal}>ID 찾기</em>

View File

@ -3,27 +3,18 @@ package com.dbnt.kcscbackend.admin.committee.schedules.service.impl;
import com.dbnt.kcscbackend.admin.committee.schedules.model.CreateScheduleVO; import com.dbnt.kcscbackend.admin.committee.schedules.model.CreateScheduleVO;
import com.dbnt.kcscbackend.admin.committee.schedules.service.EgovIndvdlSchdulManageService; import com.dbnt.kcscbackend.admin.committee.schedules.service.EgovIndvdlSchdulManageService;
import com.dbnt.kcscbackend.admin.config.repository.TcCodeItemRepository;
import com.dbnt.kcscbackend.admin.config.repository.TnCmtEventRepository;
import com.dbnt.kcscbackend.admin.config.repository.TnCmtOrgRepository;
import com.dbnt.kcscbackend.auth.entity.LoginVO; import com.dbnt.kcscbackend.auth.entity.LoginVO;
import com.dbnt.kcscbackend.commonCode.entity.TnCmtEvent;
import com.dbnt.kcscbackend.config.common.ResponseCode; import com.dbnt.kcscbackend.config.common.ResponseCode;
import com.dbnt.kcscbackend.commonCode.repository.TcCodeItemRepository;
import com.dbnt.kcscbackend.commonCode.repository.TnCmtEventRepository;
import com.dbnt.kcscbackend.commonCode.repository.TnCmtOrgRepository;
import com.dbnt.kcscbackend.config.common.ResultVO; import com.dbnt.kcscbackend.config.common.ResultVO;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.apache.tomcat.util.json.JSONParser;
import org.egovframe.rte.fdl.cmmn.EgovAbstractServiceImpl; import org.egovframe.rte.fdl.cmmn.EgovAbstractServiceImpl;
import org.springframework.boot.configurationprocessor.json.JSONObject;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.*; import java.util.*;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ -129,14 +120,14 @@ public class EgovIndvdlSchdulManageServiceImpl extends EgovAbstractServiceImpl i
Map<String, Object> response = tnCmtEventRepository.spAddTnCmtEvent( Map<String, Object> response = tnCmtEventRepository.spAddTnCmtEvent(
createScheduleVO.getDivMeet(), createScheduleVO.getDivMeet(), // 구분
createScheduleVO.getUpCommittee(), createScheduleVO.getUpCommittee(), // 심의위원회 상위 코드 번호
createScheduleVO.getCommittee(), createScheduleVO.getCommittee(), // 심의위원회 하위 코드 번호
createScheduleVO.getTitle(), createScheduleVO.getTitle(), // 제목
createScheduleVO.getLocation(), createScheduleVO.getLocation(), // 장소
createScheduleVO.getContents(), createScheduleVO.getContents(), // 내용
createScheduleVO.getStartDate(), createScheduleVO.getStartDate(), // 날짜/시간의 시작 일시
createScheduleVO.getEndDate(), createScheduleVO.getEndDate(), // 날짜/시간의 종료 일시
"admin", "admin",
null, null,
null, null,
@ -168,10 +159,28 @@ public class EgovIndvdlSchdulManageServiceImpl extends EgovAbstractServiceImpl i
); );
int isValid = tnCmtEventRepository.sp_is_valid_tn_cmt_event_id( scheduleId ); int isValid = tnCmtEventRepository.sp_is_valid_tn_cmt_event_id( scheduleId.intValue() );
if( isValid == 0 ) {
throw new Exception("대상이 존재하지 않습니다.");
}
TnCmtEvent tnCmtEvent = tnCmtEventRepository.findByEvtSeq(scheduleId);
Map<String, Object> dto = new HashMap<String, Object>(); Map<String, Object> dto = new HashMap<String, Object>();
//dto.put("schdulId", response.get("_evt_seq") ); dto.put("evtSeq", tnCmtEvent.getEvtSeq()); // sequence
dto.put("divMeet", tnCmtEvent.getEvtType()); // 구분
dto.put("upCommittee", tnCmtEvent.getUpCmtSeq()); // 심의위원회 상위 코드 번호
dto.put("committee", tnCmtEvent.getCmtSeq()); // 심의위원회 하위 코드 번호
dto.put("title", tnCmtEvent.getEvtTitle()); // 제목
dto.put("location", tnCmtEvent.getEvtLocation()); // 장소
dto.put("contents", tnCmtEvent.getEvtContents()); // 내용
dto.put("startDate", tnCmtEvent.getEvtStartDt()); // 날짜/시간의 시작 일시
dto.put("endDate", tnCmtEvent.getEvtEndDt()); // 날짜/시간의 종료 일시
// 문자열로 리턴하도록 수정해야 함.
resultVO.setResult(dto); resultVO.setResult(dto);
resultVO.setResultCode(ResponseCode.SUCCESS.getCode()); resultVO.setResultCode(ResponseCode.SUCCESS.getCode());

View File

@ -1,7 +1,7 @@
package com.dbnt.kcscbackend.admin.config; package com.dbnt.kcscbackend.admin.config;
import com.dbnt.kcscbackend.admin.config.entity.TcCodeGrp; import com.dbnt.kcscbackend.commonCode.entity.TcCodeGrp;
import com.dbnt.kcscbackend.admin.config.entity.TcCodeItem; import com.dbnt.kcscbackend.commonCode.entity.TcCodeItem;
import com.dbnt.kcscbackend.admin.config.service.AdminConfigService; import com.dbnt.kcscbackend.admin.config.service.AdminConfigService;
import com.dbnt.kcscbackend.auth.entity.LoginVO; import com.dbnt.kcscbackend.auth.entity.LoginVO;
import com.dbnt.kcscbackend.config.common.BaseController; import com.dbnt.kcscbackend.config.common.BaseController;
@ -44,7 +44,7 @@ public class AdminConfigController extends BaseController {
public ResultVO getCodeGrp() throws Exception{ public ResultVO getCodeGrp() throws Exception{
ResultVO resultVO = new ResultVO(); ResultVO resultVO = new ResultVO();
Map<String, Object> resultMap = new HashMap<>(); Map<String, Object> resultMap = new HashMap<>();
resultMap.put("codeGrpList", adminConfigService.selectCodeGrpList()); resultMap.put("codeGrpList", adminConfigService.selectCodeGrpList());
resultVO.setResult(resultMap); resultVO.setResult(resultMap);
return resultVO; return resultVO;
} }
@ -215,4 +215,21 @@ public class AdminConfigController extends BaseController {
return resultVO; return resultVO;
} }
@Operation(
summary = "메뉴 조회",
description = "메뉴 조회",
tags = {"AdminConfigController"}
)
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "조회 성공"),
@ApiResponse(responseCode = "403", description = "인가된 사용자가 아님")
})
@RequestMapping(method = RequestMethod.GET, value = "/menu-mgt")
public ResultVO getMenuMgt(){
ResultVO resultVO = new ResultVO();
Map<String, Object> resultMap = new HashMap<>();
resultMap.put("menuList", adminConfigService.selectMenuList());
resultVO.setResult(resultMap);
return resultVO;
}
} }

View File

@ -0,0 +1,53 @@
package com.dbnt.kcscbackend.admin.config.entity;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.hibernate.annotations.DynamicInsert;
import org.hibernate.annotations.DynamicUpdate;
import org.springframework.format.annotation.DateTimeFormat;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import java.time.LocalDateTime;
@Getter
@Setter
@Entity
@NoArgsConstructor
@DynamicInsert
@DynamicUpdate
@Table(name = "tc_menu")
public class TcMenu {
@Id
@Column(name = "menu_id")
private String menuId;
@Column(name = "role_grp_id")
private String roleGrpId;
@Column(name = "menu_title")
private String menuTitle;
@Column(name = "menu_group")
private String menuGroup;
@Column(name = "menu_level")
private String menuLevel;
@Column(name = "menu_sort")
private String menuSort;
@Column(name = "menu_url")
private String menuUrl;
@Column(name = "menu_type_cd")
private String menuTypeCd;
@Column(name = "frst_crt_id")
private String frstCrtId;
@Column(name = "frst_crt_dt")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime frstCrtDt;
@Column(name = "last_chg_id")
private String lastChgId;
@Column(name = "last_chg_dt")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime lastChgDt;
@Column(name = "use_yn")
private String useYn;
}

View File

@ -0,0 +1,10 @@
package com.dbnt.kcscbackend.admin.config.repository;
import com.dbnt.kcscbackend.admin.config.entity.TcMenu;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.List;
public interface TcMenuRepository extends JpaRepository<TcMenu, String> {
List<TcMenu> findByUseYnOrderByMenuIdAsc(String useYn);
}

View File

@ -1,9 +1,11 @@
package com.dbnt.kcscbackend.admin.config.service; package com.dbnt.kcscbackend.admin.config.service;
import com.dbnt.kcscbackend.admin.config.entity.TcCodeGrp; import com.dbnt.kcscbackend.admin.config.entity.TcMenu;
import com.dbnt.kcscbackend.admin.config.entity.TcCodeItem; import com.dbnt.kcscbackend.admin.config.repository.TcMenuRepository;
import com.dbnt.kcscbackend.admin.config.repository.TcCodeGrpRepository; import com.dbnt.kcscbackend.commonCode.entity.TcCodeGrp;
import com.dbnt.kcscbackend.admin.config.repository.TcCodeItemRepository; import com.dbnt.kcscbackend.commonCode.entity.TcCodeItem;
import com.dbnt.kcscbackend.commonCode.repository.TcCodeGrpRepository;
import com.dbnt.kcscbackend.commonCode.repository.TcCodeItemRepository;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.egovframe.rte.fdl.cmmn.EgovAbstractServiceImpl; import org.egovframe.rte.fdl.cmmn.EgovAbstractServiceImpl;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@ -17,6 +19,7 @@ public class AdminConfigService extends EgovAbstractServiceImpl {
private final TcCodeGrpRepository codeGrpRepository; private final TcCodeGrpRepository codeGrpRepository;
private final TcCodeItemRepository codeItemRepository; private final TcCodeItemRepository codeItemRepository;
private final TcMenuRepository menuRepository;
public List<TcCodeGrp> selectCodeGrpList(){ public List<TcCodeGrp> selectCodeGrpList(){
return codeGrpRepository.findByUseYn("Y"); return codeGrpRepository.findByUseYn("Y");
@ -95,4 +98,8 @@ public class AdminConfigService extends EgovAbstractServiceImpl {
return "validGrpCd"; return "validGrpCd";
} }
} }
public List<TcMenu> selectMenuList() {
return menuRepository.findByUseYnOrderByMenuIdAsc("Y");
}
} }

View File

@ -1,7 +1,10 @@
package com.dbnt.kcscbackend.admin.logs; 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.entity.ThPrivacyLog;
import com.dbnt.kcscbackend.admin.logs.service.AdminMenuService;
import com.dbnt.kcscbackend.admin.logs.service.AdminLogsService; import com.dbnt.kcscbackend.admin.logs.service.AdminLogsService;
import com.dbnt.kcscbackend.admin.logs.service.AdminUserService;
import com.dbnt.kcscbackend.auth.entity.LoginVO; import com.dbnt.kcscbackend.auth.entity.LoginVO;
import com.dbnt.kcscbackend.config.common.BaseController; import com.dbnt.kcscbackend.config.common.BaseController;
import com.dbnt.kcscbackend.config.common.ResponseCode; import com.dbnt.kcscbackend.config.common.ResponseCode;
@ -11,17 +14,16 @@ import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses; import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.egovframe.rte.fdl.property.EgovPropertyService;
import org.egovframe.rte.ptl.mvc.tags.ui.pagination.PaginationInfo;
import org.springframework.security.core.annotation.AuthenticationPrincipal; import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.http.MediaType; import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController; import java.text.SimpleDateFormat;
import org.springframework.web.bind.annotation.RequestBody; import java.time.LocalDate;
import java.util.Date;
import javax.annotation.Resource;
import java.util.HashMap; import java.util.HashMap;
import java.util.List;
import java.util.Map; import java.util.Map;
@RestController @RestController
@ -30,20 +32,76 @@ import java.util.Map;
@Tag(name="AdminLogsController", description = "사이트관리 로그현황 메뉴 컨트롤러") @Tag(name="AdminLogsController", description = "사이트관리 로그현황 메뉴 컨트롤러")
public class AdminLogsController extends BaseController { public class AdminLogsController extends BaseController {
@Resource(name = "propertiesService") private final AdminMenuService adminMenuService;
protected EgovPropertyService propertyService; private final AdminUserService adminUserService;
private final AdminLogsService adminLogsService; private final AdminLogsService adminLogsService;
@Operation( @Operation(
summary = "로그현황 - 개인정보 로그", summary = "로그현황 - 메뉴별 접속현황",
description = "개인정보 로그현황", description = "메뉴별 접속현황",
tags = {"AdminLogsController"} tags = {"AdminLogsController"}
) )
@ApiResponses(value = { @ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "조회 성공"), @ApiResponse(responseCode = "200", description = "조회 성공"),
@ApiResponse(responseCode = "403", description = "인가된 사용자가 아님") @ApiResponse(responseCode = "403", description = "인가된 사용자가 아님")
}) })
@RequestMapping(method = RequestMethod.POST, value = "/menu", consumes = MediaType.APPLICATION_JSON_VALUE)
public ResultVO MenuListCount(@RequestBody Map<String, String> dateRange,
@AuthenticationPrincipal LoginVO user)
throws Exception {
ResultVO resultVO = new ResultVO();
Map<String, Object> resultMap = new HashMap<>();
String startDate = dateRange.get("start_date");
String endDate = dateRange.get("end_date");
resultMap.put("resultCnt", adminMenuService.selectMenuCountCnt(startDate, endDate));
resultMap.put("resultList", adminMenuService.selectMenuCount(startDate, endDate));
resultVO.setResultCode(ResponseCode.SUCCESS.getCode());
resultVO.setResultMessage(ResponseCode.SUCCESS.getMessage());
resultVO.setResult(resultMap);
return resultVO;
}
@Operation(
summary = "로그현황 - 사용자 접속현황",
description = "사용자 접속현황",
tags = {"AdminLogsController"}
)
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "조회 성공"),
@ApiResponse(responseCode = "403", description = "인가된 사용자가 아님")
})
@RequestMapping(method = RequestMethod.POST, value = "/user", consumes = MediaType.APPLICATION_JSON_VALUE)
public ResultVO UserListCount(@RequestBody Map<String, String> dateRange,
@AuthenticationPrincipal LoginVO user)
throws Exception {
ResultVO resultVO = new ResultVO();
Map<String, Object> resultMap = new HashMap<>();
String startDate = dateRange.get("start_date");
String endDate = dateRange.get("end_date");
resultMap.put("resultCnt", adminUserService.selectUserCountCnt(startDate, endDate));
resultMap.put("resultList", adminUserService.selectUserCount(startDate, endDate));
resultVO.setResultCode(ResponseCode.SUCCESS.getCode());
resultVO.setResultMessage(ResponseCode.SUCCESS.getMessage());
resultVO.setResult(resultMap);
return resultVO;
}
@Operation(
summary = "로그현황 - 개인정보 로그",
description = "개인정보 로그현황",
tags = {"AdminLogsController"}
)
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "조회 성공"),
@ApiResponse(responseCode = "403", description = "인가된 사용자가 아님")
})
@RequestMapping(method = RequestMethod.POST, value = "/privacy", consumes = MediaType.APPLICATION_JSON_VALUE) @RequestMapping(method = RequestMethod.POST, value = "/privacy", consumes = MediaType.APPLICATION_JSON_VALUE)
public ResultVO selectPrivacyLogsList(@RequestBody ThPrivacyLog thPrivacyLog, @AuthenticationPrincipal LoginVO user) public ResultVO selectPrivacyLogsList(@RequestBody ThPrivacyLog thPrivacyLog, @AuthenticationPrincipal LoginVO user)
throws Exception { throws Exception {
@ -62,5 +120,4 @@ public class AdminLogsController extends BaseController {
return resultVO; return resultVO;
} }
} }

View File

@ -0,0 +1,40 @@
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 = "tn_daily_menu_log")
public class TnDailyMenuLog {
@Id
@Column(name = "dml_seq")
private Long dmlSeq;
@Column(name = "menu_id")
private String menuId;
@Column(name = "menu_title")
private String menuTitle;
@Column(name = "log_cnt")
private Long logCnt;
@Column(name = "log_dt")
@DateTimeFormat(pattern = "yyyy-MM-dd")
private LocalDate logDt;
}

View File

@ -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 = "tn_daily_user_log")
public class TnDailyUserConnLog {
@Id
@Column(name = "dul_seq")
private Long dulSeq;
@Column(name = "log_cnt")
private Long logCnt;
@Column(name = "log_dt")
@DateTimeFormat(pattern = "yyyy-MM-dd")
private LocalDate logDt;
}

View File

@ -0,0 +1,26 @@
package com.dbnt.kcscbackend.admin.logs.repository;
import com.dbnt.kcscbackend.admin.logs.entity.TnDailyMenuLog;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import java.time.LocalDate;
import java.util.List;
public interface MenuLogsRepository extends JpaRepository<TnDailyMenuLog, Long> {
@Query(value = "SELECT COUNT(DISTINCT menu_id) "
+ "FROM tn_daily_menu_log "
+ "WHERE log_dt BETWEEN TO_DATE(:startDate, 'YYYY-MM-DD') AND TO_DATE(:endDate, 'YYYY-MM-DD')", nativeQuery = true)
long countDistinctMenuIds(@Param("startDate") String startDate, @Param("endDate") String endDate);
@Query(value = "SELECT menu_id, MAX(menu_title) as menu_title, sum(log_cnt) as log_cnt "
+ "FROM tn_daily_menu_log "
+ "WHERE log_dt BETWEEN TO_DATE(:startDate, 'YYYY-MM-DD') AND TO_DATE(:endDate, 'YYYY-MM-DD') "
+ "GROUP BY menu_id "
+ "ORDER BY log_cnt desc", nativeQuery = true)
List<Object[]> selectCountMenu(@Param("startDate") String startDate, @Param("endDate") String endDate);
}

View File

@ -6,7 +6,5 @@ import org.springframework.data.jpa.repository.JpaRepository;
import java.util.List; import java.util.List;
public interface PrivacyLogsRepository extends JpaRepository<ThPrivacyLog, String> { public interface PrivacyLogsRepository extends JpaRepository<ThPrivacyLog, String> {
long count(); // 전체 레코드 수를 반환하는 메서드
List<ThPrivacyLog> findAllByOrderByUplSeqDesc(); List<ThPrivacyLog> findAllByOrderByUplSeqDesc();
} }

View File

@ -0,0 +1,25 @@
package com.dbnt.kcscbackend.admin.logs.repository;
import com.dbnt.kcscbackend.admin.logs.entity.TnDailyUserConnLog;
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 UserLogsRepository extends JpaRepository<TnDailyUserConnLog, Long> {
@Query(value = "SELECT COUNT(DISTINCT log_dt) "
+ "FROM tn_daily_user_log "
+ "WHERE log_dt BETWEEN TO_DATE(:startDate, 'YYYY-MM-DD') AND TO_DATE(:endDate, 'YYYY-MM-DD')", nativeQuery = true)
long countDistinctUserIds(@Param("startDate") String startDate, @Param("endDate") String endDate);
@Query(value = "SELECT TO_CHAR(log_dt, 'YYYY-MM-DD') as log_dt, sum(log_cnt) as log_cnt "
+ "FROM tn_daily_user_log "
+ "WHERE log_dt BETWEEN TO_DATE(:startDate, 'YYYY-MM-DD') AND TO_DATE(:endDate, 'YYYY-MM-DD') "
+ "GROUP BY TO_CHAR(log_dt, 'YYYY-MM-DD') "
+ "ORDER BY log_dt asc", nativeQuery = true)
List<Object[]> selectCountUser(@Param("startDate") String startDate, @Param("endDate") String endDate);
}

View File

@ -16,9 +16,6 @@ public class AdminLogsService extends EgovAbstractServiceImpl {
private final PrivacyLogsRepository privacyLogsRepository; private final PrivacyLogsRepository privacyLogsRepository;
// public List<ThPrivacyLog> selectPrivacyList(){
// return privacyLogsRepository.findAll();
// }
public Map<String, Object> selectPrivacyList() { public Map<String, Object> selectPrivacyList() {
Map<String, Object> resultMap = new HashMap<>(); Map<String, Object> resultMap = new HashMap<>();

View File

@ -0,0 +1,27 @@
package com.dbnt.kcscbackend.admin.logs.service;
import com.dbnt.kcscbackend.admin.logs.entity.TnDailyMenuLog;
import com.dbnt.kcscbackend.admin.logs.repository.MenuLogsRepository;
import lombok.RequiredArgsConstructor;
import org.egovframe.rte.fdl.cmmn.EgovAbstractServiceImpl;
import org.springframework.stereotype.Service;
import java.time.LocalDate;
import java.util.List;
@Service
@RequiredArgsConstructor
public class AdminMenuService extends EgovAbstractServiceImpl {
private final MenuLogsRepository menuLogsRepository;
// 메뉴별 접속횟수
public List<Object[]> selectMenuCount(String startDate, String endDate) {
return menuLogsRepository.selectCountMenu(startDate, endDate);
}
// 전체 레코드 수 가져오기
public long selectMenuCountCnt(String startDate, String endDate) {
return menuLogsRepository.countDistinctMenuIds(startDate, endDate);
}
}

View File

@ -0,0 +1,25 @@
package com.dbnt.kcscbackend.admin.logs.service;
import com.dbnt.kcscbackend.admin.logs.repository.UserLogsRepository;
import lombok.RequiredArgsConstructor;
import org.egovframe.rte.fdl.cmmn.EgovAbstractServiceImpl;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
@RequiredArgsConstructor
public class AdminUserService extends EgovAbstractServiceImpl {
private final UserLogsRepository userLogsRepository;
// 메뉴별 접속횟수
public List<Object[]> selectUserCount(String startDate, String endDate) {
return userLogsRepository.selectCountUser(startDate, endDate);
}
// 전체 레코드 수 가져오기
public long selectUserCountCnt(String startDate, String endDate) {
return userLogsRepository.countDistinctUserIds(startDate, endDate);
}
}

View File

@ -2,18 +2,26 @@ package com.dbnt.kcscbackend.admin.users;
import com.dbnt.kcscbackend.admin.users.service.AdminUsersService; import com.dbnt.kcscbackend.admin.users.service.AdminUsersService;
import com.dbnt.kcscbackend.auth.entity.LoginVO;
import com.dbnt.kcscbackend.auth.entity.UserInfo; import com.dbnt.kcscbackend.auth.entity.UserInfo;
import com.dbnt.kcscbackend.config.common.BaseController; import com.dbnt.kcscbackend.config.common.BaseController;
import com.dbnt.kcscbackend.config.common.ResponseCode;
import com.dbnt.kcscbackend.config.common.ResultVO; import com.dbnt.kcscbackend.config.common.ResultVO;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses; import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.springframework.http.MediaType;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.validation.Errors;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import javax.validation.Valid;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
@ -65,4 +73,65 @@ public class AdminUsersController extends BaseController {
return resultVO; return resultVO;
} }
@Operation(
summary = "사용자 정보 수정",
description = "사용자 정보 수정",
tags = {"AdminUsersController"}
)
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "수정 성공"),
@ApiResponse(responseCode = "403", description = "인가된 사용자가 아님")
})
@RequestMapping(method = RequestMethod.PUT, value = "/info")
public ResultVO modifyUserInfo(@RequestBody @Valid UserInfo info, Errors errors, @AuthenticationPrincipal LoginVO user) throws Exception{
ResultVO resultVO = new ResultVO();
if(errors.hasErrors()){
StringBuilder msg = new StringBuilder();
for(FieldError error: errors.getFieldErrors()){
msg.append(error.getDefaultMessage());
msg.append("\n");
}
resultVO.setResultCode(ResponseCode.INPUT_CHECK_ERROR.getCode());
resultVO.setResultMessage(msg.toString());
}else if(!info.getPassword().equals(info.getPasswordChk())){
resultVO.setResultCode(ResponseCode.SAVE_ERROR.getCode());
resultVO.setResultMessage("비밀번호 확인이 잘못 입력되었습니다.");
}else {
Integer insertResult = adminUsersService.updateUserInfo(info, user.getId());
if(insertResult!=null){
if(insertResult==-1){
resultVO.setResultCode(ResponseCode.SAVE_ERROR.getCode());
resultVO.setResultMessage("수정 대상이 존재하지 않습니다.");
}else if(insertResult==-2){
resultVO.setResultCode(ResponseCode.SAVE_ERROR.getCode());
resultVO.setResultMessage("가입된 이메일입니다.");
}else{
resultVO.setResultCode(ResponseCode.SUCCESS.getCode());
resultVO.setResultMessage("저장 되었습니다.");
}
}else{
resultVO.setResultCode(ResponseCode.SAVE_ERROR.getCode());
resultVO.setResultMessage("저장에 실패하였습니다.");
}
}
return resultVO;
}
@Operation(
summary = "사용자 정보 삭제",
description = "사용자 정보 삭제",
tags = {"AdminUsersController"}
)
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "삭제 성공"),
@ApiResponse(responseCode = "403", description = "인가된 사용자가 아님")
})
@RequestMapping(method = RequestMethod.DELETE, value = "/info", consumes = MediaType.APPLICATION_JSON_VALUE)
public ResultVO deleteUserInfo(@RequestBody UserInfo info) throws Exception{
ResultVO resultVO = new ResultVO();
adminUsersService.deleteUserInfo(info.getUserSeq());
resultVO.setResultCode(ResponseCode.SUCCESS.getCode());
return resultVO;
}
} }

View File

@ -4,13 +4,16 @@ import com.dbnt.kcscbackend.admin.users.mapper.AdminUsersMapper;
import com.dbnt.kcscbackend.auth.entity.UserInfo; import com.dbnt.kcscbackend.auth.entity.UserInfo;
import com.dbnt.kcscbackend.auth.repository.UserInfoRepository; import com.dbnt.kcscbackend.auth.repository.UserInfoRepository;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.egovframe.rte.fdl.cmmn.EgovAbstractServiceImpl;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDateTime;
import java.util.List; import java.util.List;
@Service @Service
@RequiredArgsConstructor @RequiredArgsConstructor
public class AdminUsersService { public class AdminUsersService extends EgovAbstractServiceImpl {
private final UserInfoRepository userInfoRepository; private final UserInfoRepository userInfoRepository;
private final AdminUsersMapper usersMapper; private final AdminUsersMapper usersMapper;
@ -28,4 +31,37 @@ public class AdminUsersService {
info.setPassword(null); info.setPassword(null);
return info; return info;
} }
@Transactional
public Integer updateUserInfo(UserInfo info, String updateUser) {
UserInfo savedInfo = userInfoRepository.findById(info.getUserSeq()).orElse(null);
UserInfo emailChk = userInfoRepository.findByEmail(info.getEmail()).orElse(null);
if(savedInfo==null){
return -1;
}else if(emailChk != null){
if(!emailChk.getUserSeq().equals(info.getUserSeq())){
return -2;
}
}
savedInfo.setUserNm(info.getUserNm());
if(!info.getPassword().isEmpty()){
savedInfo.setPassword(info.convertPassword(info.getPassword()));
}
savedInfo.setEmail(info.getEmail());
savedInfo.setPhoneNum(info.getPhoneNum());
savedInfo.setUserSe(info.getUserSe());
savedInfo.setUserRole(info.getUserRole());
savedInfo.setStatus(info.getStatus());
savedInfo.setLastChgId(updateUser);
savedInfo.setLastChgDt(LocalDateTime.now());
return savedInfo.getUserSeq();
}
@Transactional
public void deleteUserInfo(Integer userSeq) {
userInfoRepository.deleteById(userSeq);
}
} }

View File

@ -2,6 +2,7 @@ package com.dbnt.kcscbackend.auth.entity;
import com.dbnt.kcscbackend.config.common.BoardParams; import com.dbnt.kcscbackend.config.common.BoardParams;
import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnore;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Getter; import lombok.Getter;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import lombok.Setter; import lombok.Setter;
@ -11,8 +12,12 @@ import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.crypto.password.Pbkdf2PasswordEncoder;
import javax.persistence.*; import javax.persistence.*;
import javax.validation.constraints.Email;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Pattern;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatter;
import java.util.Collection; import java.util.Collection;
@ -32,16 +37,23 @@ public class UserInfo extends BoardParams implements UserDetails{
@Column(name = "user_seq") @Column(name = "user_seq")
private Integer userSeq; private Integer userSeq;
@Column(name = "user_id") @Column(name = "user_id")
@Pattern(regexp = "^[a-zA-Z]{1}[a-zA-Z0-9_]{4,11}$")
@NotBlank(message = "아이디를 입력해주세요.")
private String userId; private String userId;
@Column(name = "password") @Column(name = "password")
private String password; private String password;
@Column(name = "email") @Column(name = "email")
@Email(message = "이메일 형식에 맞지 않습니다.")
@Schema(description = "이메일주소")
@NotBlank(message = "이메일을 입력해주세요.")
private String email; private String email;
@Column(name = "user_se") @Column(name = "user_se")
private String userSe; private String userSe;
@Column(name = "user_nm") @Column(name = "user_nm")
@NotBlank(message = "이름을 입력해주세요.")
private String userNm; private String userNm;
@Column(name = "phone_num") @Column(name = "phone_num")
@NotBlank(message = "연락처를 입력해주세요.")
private String phoneNum; private String phoneNum;
@Column(name = "user_role") @Column(name = "user_role")
private String userRole; private String userRole;
@ -56,6 +68,9 @@ public class UserInfo extends BoardParams implements UserDetails{
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime lastChgDt; private LocalDateTime lastChgDt;
@Transient
private String passwordChk;
@Override @Override
@JsonIgnore @JsonIgnore
public Collection<? extends GrantedAuthority> getAuthorities() { public Collection<? extends GrantedAuthority> getAuthorities() {
@ -92,4 +107,11 @@ public class UserInfo extends BoardParams implements UserDetails{
return getStatus().equals("USE_ST"); return getStatus().equals("USE_ST");
} }
public String convertPassword(String password){
Pbkdf2PasswordEncoder passwordEncoder = new Pbkdf2PasswordEncoder();
return passwordEncoder.encode(password);
}
} }

View File

@ -59,7 +59,7 @@ public class EgovLoginServiceImpl extends EgovAbstractServiceImpl implements Ego
} }
UserInfo info = new UserInfo(); UserInfo info = new UserInfo();
info.setUserId(loginVO.getId()); info.setUserId(loginVO.getId());
info.setPassword(convertPassword(loginVO.getPassword())); info.setPassword(info.convertPassword(loginVO.getPassword()));
info.setUserNm(loginVO.getUserNm()); info.setUserNm(loginVO.getUserNm());
info.setEmail(loginVO.getEmail()); info.setEmail(loginVO.getEmail());
info.setPhoneNum(loginVO.getPhoneNum()); info.setPhoneNum(loginVO.getPhoneNum());
@ -85,7 +85,7 @@ public class EgovLoginServiceImpl extends EgovAbstractServiceImpl implements Ego
int rdNum = rd.nextInt(95)+33; int rdNum = rd.nextInt(95)+33;
password.append((char)rdNum); password.append((char)rdNum);
} }
user.setPassword(convertPassword(password.toString())); user.setPassword(user.convertPassword(password.toString()));
return password.toString(); return password.toString();
} }
return null; return null;
@ -184,9 +184,4 @@ public class EgovLoginServiceImpl extends EgovAbstractServiceImpl implements Ego
return result; return result;
} }
private String convertPassword(String password){
Pbkdf2PasswordEncoder passwordEncoder = new Pbkdf2PasswordEncoder();
return passwordEncoder.encode(password);
}
} }

View File

@ -0,0 +1,43 @@
package com.dbnt.kcscbackend.commonCode;
import com.dbnt.kcscbackend.commonCode.entity.TcCodeItem;
import com.dbnt.kcscbackend.commonCode.service.CommonCodeService;
import com.dbnt.kcscbackend.config.common.ResultVO;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
import java.util.Map;
@RestController
@RequiredArgsConstructor
@RequestMapping("/commonCode")
@Tag(name="CommonCodeController", description = "공통코드 컨트롤러")
public class CommonCodeController {
private final CommonCodeService commonCodeService;
@Operation(
summary = "코드 아이템 목록 조회",
description = "코드 아이템 목록 조회",
tags = {"CommonCodeController"}
)
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "조회 성공"),
@ApiResponse(responseCode = "403", description = "인가된 사용자가 아님")
})
@RequestMapping(method = RequestMethod.GET, value = "/code-item")
public ResultVO getCodeItemList(TcCodeItem codeItem) throws Exception{
ResultVO resultVO = new ResultVO();
Map<String, Object> resultMap = new HashMap<>();
resultMap.put("codeList", commonCodeService.selectCodeItemList(codeItem.getGrpCd()));
resultVO.setResult(resultMap);
return resultVO;
}
}

View File

@ -1,4 +1,4 @@
package com.dbnt.kcscbackend.admin.config.entity; package com.dbnt.kcscbackend.commonCode.entity;
import lombok.Getter; import lombok.Getter;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;

View File

@ -1,4 +1,4 @@
package com.dbnt.kcscbackend.admin.config.entity; package com.dbnt.kcscbackend.commonCode.entity;
import lombok.*; import lombok.*;
import org.hibernate.annotations.DynamicInsert; import org.hibernate.annotations.DynamicInsert;

View File

@ -1,4 +1,4 @@
package com.dbnt.kcscbackend.admin.config.entity; package com.dbnt.kcscbackend.commonCode.entity;
import lombok.*; import lombok.*;
import org.hibernate.annotations.DynamicInsert; import org.hibernate.annotations.DynamicInsert;
@ -21,57 +21,57 @@ public class TnCmtEvent {
@Id @Id
@GeneratedValue(strategy = GenerationType.IDENTITY) @GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "evt_seq") @Column(name = "evt_seq")
private Long evt_seq; private Long evtSeq;
@Column(name = "evt_type") @Column(name = "evt_type")
private String evt_type; private String evtType;
@Column(name = "up_cmt_seq") @Column(name = "up_cmt_seq")
private Long up_cmt_seq; private Long upCmtSeq;
@Column(name = "cmt_seq") @Column(name = "cmt_seq")
private Long cmt_seq; private Long cmtSeq;
@Column(name = "evt_title") @Column(name = "evt_title")
private String evt_title; private String evtTitle;
@Column(name = "evt_location") @Column(name = "evt_location")
private String evt_location; private String evtLocation;
@Column(name = "evt_contents") @Column(name = "evt_contents")
private String evt_contents; private String evtContents;
@Column(name = "evt_start_dt") @Column(name = "evt_start_dt")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime evt_start_dt; private LocalDateTime evtStartDt;
@Column(name = "evt_end_dt") @Column(name = "evt_end_dt")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime evt_end_dt; private LocalDateTime evtEndDt;
@Column(name = "frst_crt_id") @Column(name = "frst_crt_id")
private String frst_crt_id; private String frstCrtId;
@Column(name = "frst_crt_dt") @Column(name = "frst_crt_dt")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime frst_crt_dt; private LocalDateTime frstCrtDt;
@Column(name = "last_chg_id") @Column(name = "last_chg_id")
private String last_chg_id; private String lastChgId;
@Column(name = "last_chg_dt") @Column(name = "last_chg_dt")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime last_chg_dt; private LocalDateTime lastChgDt;
@Column(name = "use_yn") @Column(name = "use_yn")
private String use_yn; private String useYn;
@Embeddable @Embeddable
@Data @Data
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
public static class TnCmtEventId implements Serializable { public static class TnCmtEventId implements Serializable {
private Long evt_seq; private Long evtSeq;
} }
} }

View File

@ -1,4 +1,4 @@
package com.dbnt.kcscbackend.admin.config.entity; package com.dbnt.kcscbackend.commonCode.entity;
import lombok.*; import lombok.*;
import org.hibernate.annotations.DynamicInsert; import org.hibernate.annotations.DynamicInsert;

View File

@ -1,6 +1,6 @@
package com.dbnt.kcscbackend.admin.config.repository; package com.dbnt.kcscbackend.commonCode.repository;
import com.dbnt.kcscbackend.admin.config.entity.TcCodeGrp; import com.dbnt.kcscbackend.commonCode.entity.TcCodeGrp;
import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaRepository;
import java.util.List; import java.util.List;

View File

@ -1,6 +1,6 @@
package com.dbnt.kcscbackend.admin.config.repository; package com.dbnt.kcscbackend.commonCode.repository;
import com.dbnt.kcscbackend.admin.config.entity.TcCodeItem; import com.dbnt.kcscbackend.commonCode.entity.TcCodeItem;
import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaRepository;
import java.util.List; import java.util.List;

View File

@ -1,24 +1,21 @@
package com.dbnt.kcscbackend.admin.config.repository; package com.dbnt.kcscbackend.commonCode.repository;
import com.dbnt.kcscbackend.admin.config.entity.TnCmtEvent;
import com.dbnt.kcscbackend.admin.config.entity.TnCmtOrg; import com.dbnt.kcscbackend.commonCode.entity.TnCmtEvent;
import com.fasterxml.jackson.annotation.JsonFormat; import com.dbnt.kcscbackend.commonCode.entity.TnCmtOrg;
import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query; import org.springframework.data.jpa.repository.Query;
import org.springframework.data.jpa.repository.query.Procedure; import org.springframework.data.jpa.repository.query.Procedure;
import org.springframework.data.repository.query.Param; import org.springframework.data.repository.query.Param;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import java.sql.Timestamp;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
public interface TnCmtEventRepository extends JpaRepository<TnCmtEvent, TnCmtEvent.TnCmtEventId> { public interface TnCmtEventRepository extends JpaRepository<TnCmtEvent, TnCmtEvent.TnCmtEventId> {
@Transactional @Transactional
@ -85,7 +82,7 @@ public interface TnCmtEventRepository extends JpaRepository<TnCmtEvent, TnCmtEve
//Map<String, Object> sp_is_valid_tn_cmt_event_id( @Param("_evt_seq") Long evtSeq ); //Map<String, Object> sp_is_valid_tn_cmt_event_id( @Param("_evt_seq") Long evtSeq );
@Procedure @Procedure
int sp_is_valid_tn_cmt_event_id( Long evtSeq ); int sp_is_valid_tn_cmt_event_id( Integer evtSeq );
@Query(value = "CALL sp_is_valid_tn_cmt_event_id ( :_evt_seq )", @Query(value = "CALL sp_is_valid_tn_cmt_event_id ( :_evt_seq )",
nativeQuery = true) nativeQuery = true)
@ -95,5 +92,9 @@ public interface TnCmtEventRepository extends JpaRepository<TnCmtEvent, TnCmtEve
TnCmtEvent findByEvtSeq(Long evtSeq);
} }

View File

@ -1,7 +1,6 @@
package com.dbnt.kcscbackend.admin.config.repository; package com.dbnt.kcscbackend.commonCode.repository;
import com.dbnt.kcscbackend.admin.config.entity.TcCodeItem; import com.dbnt.kcscbackend.commonCode.entity.TnCmtOrg;
import com.dbnt.kcscbackend.admin.config.entity.TnCmtOrg;
import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaRepository;
import java.util.List; import java.util.List;

View File

@ -0,0 +1,24 @@
package com.dbnt.kcscbackend.commonCode.service;
import com.dbnt.kcscbackend.commonCode.entity.TcCodeItem;
import com.dbnt.kcscbackend.commonCode.repository.TcCodeGrpRepository;
import com.dbnt.kcscbackend.commonCode.repository.TcCodeItemRepository;
import lombok.RequiredArgsConstructor;
import org.egovframe.rte.fdl.cmmn.EgovAbstractServiceImpl;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
@RequiredArgsConstructor
public class CommonCodeService extends EgovAbstractServiceImpl{
private final TcCodeGrpRepository codeGrpRepository;
private final TcCodeItemRepository codeItemRepository;
public List<TcCodeItem> selectCodeItemList(String grpCd) {
return codeItemRepository.findByGrpCdAndUseYnOrderByGrpOrder(grpCd, "Y");
}
}

View File

@ -13,8 +13,8 @@ spring.datasource.hikari.maximum-pool-size=4
#spring.datasource.username=kcsc #spring.datasource.username=kcsc
#spring.datasource.password=dbnt0928! #spring.datasource.password=dbnt0928!
spring.datasource.driverClassName=net.sf.log4jdbc.sql.jdbcapi.DriverSpy spring.datasource.driverClassName=net.sf.log4jdbc.sql.jdbcapi.DriverSpy
spring.datasource.url=jdbc:log4jdbc:postgresql://127.0.0.1:5432/kcsc #spring.datasource.url=jdbc:log4jdbc:postgresql://127.0.0.1:5432/kcsc
#spring.datasource.url=jdbc:log4jdbc:postgresql://118.219.150.34:50503/kcsc spring.datasource.url=jdbc:log4jdbc:postgresql://118.219.150.34:50503/kcsc
spring.datasource.username=dbnt0031 spring.datasource.username=dbnt0031
spring.datasource.password=dbnt0928! spring.datasource.password=dbnt0928!

View File

@ -31,17 +31,19 @@
<if test='userSe != null and userSe != ""'> <if test='userSe != null and userSe != ""'>
and user_se = #{userSe} and user_se = #{userSe}
</if> </if>
<if test='searchCondition == "id"'> <if test='searchKeyword != null and searchKeyword != ""'>
and user_id like '%'||#{searchKeyword}||'%' <if test='searchCondition == "id"'>
</if> and user_id like '%'||#{searchKeyword}||'%'
<if test='searchCondition == "name"'> </if>
and user_nm like '%'||#{searchKeyword}||'%' <if test='searchCondition == "name"'>
</if> and user_nm like '%'||#{searchKeyword}||'%'
<if test='searchCondition == "email"'> </if>
and email like '%'||#{searchKeyword}||'%' <if test='searchCondition == "email"'>
</if> and email like '%'||#{searchKeyword}||'%'
<if test='searchCondition == "phoneNum"'> </if>
and phone_num like '%'||#{searchKeyword}||'%' <if test='searchCondition == "phoneNum"'>
and phone_num like '%'||#{searchKeyword}||'%'
</if>
</if> </if>
</where> </where>
</sql> </sql>