Compare commits
16 Commits
c3582ed28c
...
5fc1e01f57
| Author | SHA1 | Date |
|---|---|---|
|
|
5fc1e01f57 | |
|
|
6e4266dde9 | |
|
|
a4441cc083 | |
|
|
d90fbbec3e | |
|
|
43d6706469 | |
|
|
e333191efd | |
|
|
5b49f4ec85 | |
|
|
a8049966fe | |
|
|
94aff6bed9 | |
|
|
2d6f03f8f2 | |
|
|
2b962e7f7f | |
|
|
f1f0602d4e | |
|
|
38edb60201 | |
|
|
3079a00832 | |
|
|
458594779c | |
|
|
cf69ff4893 |
|
|
@ -25,6 +25,7 @@
|
||||||
"react-csv": "^2.2.2",
|
"react-csv": "^2.2.2",
|
||||||
"react-datepicker": "^4.8.0",
|
"react-datepicker": "^4.8.0",
|
||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
|
"react-drag-drop-files": "^2.3.10",
|
||||||
"react-element-to-jsx-string": "^15.0.0",
|
"react-element-to-jsx-string": "^15.0.0",
|
||||||
"react-icons": "^4.11.0",
|
"react-icons": "^4.11.0",
|
||||||
"react-loader-spinner": "^5.4.5",
|
"react-loader-spinner": "^5.4.5",
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,27 @@
|
||||||
|
import React, { useState } from "react";
|
||||||
|
import { FileUploader } from "react-drag-drop-files";
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* https://www.npmjs.com/package/react-drag-drop-files를 참고해주세요.
|
||||||
|
* @param {fileTypes} const fileTypes = ["JPG", "PNG", "GIF"];
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
function FileDragDrop({fileTypes, children, multiple, label, onDrop, handleChange, file, setFile, dropMessageStyle}) {
|
||||||
|
|
||||||
|
return (
|
||||||
|
<FileUploader
|
||||||
|
handleChange={handleChange}
|
||||||
|
name="file"
|
||||||
|
types={fileTypes ? fileTypes : "*"}
|
||||||
|
multiple={multiple && false}
|
||||||
|
label={label}
|
||||||
|
onDrop={onDrop}
|
||||||
|
dropMessageStyle={dropMessageStyle}
|
||||||
|
>
|
||||||
|
{children && children}
|
||||||
|
</FileUploader>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default FileDragDrop;
|
||||||
|
|
@ -115,7 +115,7 @@ function ListCreateUpdateDelete(props) {
|
||||||
</Grid>
|
</Grid>
|
||||||
</Typography>
|
</Typography>
|
||||||
<Demo>
|
<Demo>
|
||||||
<List dense={false} sx={{ px: 0, '&': { minHeight: '315px', height: '650px', overflowY: 'auto'}}}>
|
<List dense={false} sx={{ px: 0, '&': { minHeight: '315px', height: '615px', overflowY: 'auto'}}}>
|
||||||
{generate(
|
{generate(
|
||||||
props.items,
|
props.items,
|
||||||
<ListItem
|
<ListItem
|
||||||
|
|
|
||||||
|
|
@ -170,22 +170,16 @@
|
||||||
.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: 100px;}
|
.menuList .head > span:nth-child(1) {width: 120px;}
|
||||||
.menuList .head > span:nth-child(2) {width: 150px;}
|
.menuList .head > span:nth-child(2) {width: 100px;}
|
||||||
.menuList .head > span:nth-child(3) {width: 100px;}
|
.menuList .head > span:nth-child(3) {width: 200px;}
|
||||||
.menuList .head > span:nth-child(4) {width: 60px;}
|
.menuList .head > span:nth-child(4) {width: 100px;}
|
||||||
.menuList .head > span:nth-child(5) {width: 60px;}
|
.menuList .head > span:nth-child(5) {width: 100px;}
|
||||||
.menuList .head > span:nth-child(6) {width: 200px;}
|
.menuList .result .list_item > div:nth-child(1) {width: 120px;}
|
||||||
.menuList .head > span:nth-child(7) {width: 100px;}
|
.menuList .result .list_item > div:nth-child(2) {width: 100px;}
|
||||||
.menuList .head > span:nth-child(8) {width: 100px;}
|
.menuList .result .list_item > div:nth-child(3) {width: 200px;}
|
||||||
.menuList .result .list_item > div:nth-child(1) {width: 100px;}
|
.menuList .result .list_item > div:nth-child(4) {width: 100px;}
|
||||||
.menuList .result .list_item > div:nth-child(2) {width: 150px;}
|
.menuList .result .list_item > div:nth-child(5) {width: 100px;}
|
||||||
.menuList .result .list_item > div:nth-child(3) {width: 100px;}
|
|
||||||
.menuList .result .list_item > div:nth-child(4) {width: 60px;}
|
|
||||||
.menuList .result .list_item > div:nth-child(5) {width: 60px;}
|
|
||||||
.menuList .result .list_item > div:nth-child(6) {width: 200px;}
|
|
||||||
.menuList .result .list_item > div:nth-child(7) {width: 100px;}
|
|
||||||
.menuList .result .list_item > div:nth-child(8) {width: 100px;}
|
|
||||||
|
|
||||||
/* 사이트관리 > 환경설정 > 메뉴권한관리 */
|
/* 사이트관리 > 환경설정 > 메뉴권한관리 */
|
||||||
.roleList .head > span:nth-child(1) {width: 120px;}
|
.roleList .head > span:nth-child(1) {width: 120px;}
|
||||||
|
|
|
||||||
|
|
@ -33,11 +33,8 @@ function MenuMgt({}) {
|
||||||
resp.result.menuList.forEach(function (item, index) {
|
resp.result.menuList.forEach(function (item, index) {
|
||||||
mutListTag.push(
|
mutListTag.push(
|
||||||
<div className={"list_item"} key={"userListDiv_"+index}>
|
<div className={"list_item"} key={"userListDiv_"+index}>
|
||||||
<div>{item.menuId}</div>
|
<div>{item.menuGroup?'└ ':''}{item.menuId}</div>
|
||||||
<div>{item.menuTitle}</div>
|
<div>{item.menuTitle}</div>
|
||||||
<div>{item.menuGroup}</div>
|
|
||||||
<div>{item.menuLevel}</div>
|
|
||||||
<div>{item.menuSort}</div>
|
|
||||||
<div>{item.menuUrl}</div>
|
<div>{item.menuUrl}</div>
|
||||||
<div>{item.menuTypeValue}</div>
|
<div>{item.menuTypeValue}</div>
|
||||||
<div>
|
<div>
|
||||||
|
|
@ -90,10 +87,7 @@ function MenuMgt({}) {
|
||||||
<div className="head">
|
<div className="head">
|
||||||
<span>메뉴 코드</span>
|
<span>메뉴 코드</span>
|
||||||
<span>메뉴 이름</span>
|
<span>메뉴 이름</span>
|
||||||
<span>부모 메뉴</span>
|
<span>경로</span>
|
||||||
<span>레벨</span>
|
|
||||||
<span>정렬</span>
|
|
||||||
<span>URI</span>
|
|
||||||
<span>타입</span>
|
<span>타입</span>
|
||||||
<span>
|
<span>
|
||||||
<button className={"btn btn_blue_h31 px-1"} onClick={()=>{editMenu(undefined)}}>추가</button>
|
<button className={"btn btn_blue_h31 px-1"} onClick={()=>{editMenu(undefined)}}>추가</button>
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,7 @@ function MenuModal({savedInfo, reloadFunction}){
|
||||||
}else if(Number(resp.resultCode) === Number(CODE.RCV_ERROR_AUTH)){
|
}else if(Number(resp.resultCode) === Number(CODE.RCV_ERROR_AUTH)){
|
||||||
console.log("토큰 갱신중.")
|
console.log("토큰 갱신중.")
|
||||||
}else{
|
}else{
|
||||||
alert(resp.result.resultMessage)
|
alert(resp.resultMessage)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
@ -78,6 +78,14 @@ function MenuModal({savedInfo, reloadFunction}){
|
||||||
</Modal.Header>
|
</Modal.Header>
|
||||||
<Modal.Body>
|
<Modal.Body>
|
||||||
<Form onSubmit={(e) =>{editMenu(e)}} noValidate>
|
<Form onSubmit={(e) =>{editMenu(e)}} noValidate>
|
||||||
|
<Form.Group as={Row} className="mb-3">
|
||||||
|
<Form.Label column sm={3}>
|
||||||
|
그룹 코드
|
||||||
|
</Form.Label>
|
||||||
|
<Col sm={9}>
|
||||||
|
<Form.Control type="email" name="menuGroup" placeholder="그룹" required defaultValue={savedInfo?.menuGroup} />
|
||||||
|
</Col>
|
||||||
|
</Form.Group>
|
||||||
<Form.Group as={Row} className="mb-3">
|
<Form.Group as={Row} className="mb-3">
|
||||||
<Form.Label column sm={3}>
|
<Form.Label column sm={3}>
|
||||||
메뉴 코드
|
메뉴 코드
|
||||||
|
|
@ -94,15 +102,7 @@ function MenuModal({savedInfo, reloadFunction}){
|
||||||
<Form.Control type="text" name="menuTitle" placeholder="이름" required defaultValue={savedInfo?.menuTitle} />
|
<Form.Control type="text" name="menuTitle" placeholder="이름" required defaultValue={savedInfo?.menuTitle} />
|
||||||
</Col>
|
</Col>
|
||||||
</Form.Group>
|
</Form.Group>
|
||||||
<Form.Group as={Row} className="mb-3">
|
<Form.Group as={Row} className="mb-3 d-none">
|
||||||
<Form.Label column sm={3}>
|
|
||||||
부모 메뉴
|
|
||||||
</Form.Label>
|
|
||||||
<Col sm={9}>
|
|
||||||
<Form.Control type="email" name="menuGroup" placeholder="그룹" required defaultValue={savedInfo?.menuGroup} />
|
|
||||||
</Col>
|
|
||||||
</Form.Group>
|
|
||||||
<Form.Group as={Row} className="mb-3">
|
|
||||||
<Form.Label column sm={3}>
|
<Form.Label column sm={3}>
|
||||||
레벨
|
레벨
|
||||||
</Form.Label>
|
</Form.Label>
|
||||||
|
|
@ -110,7 +110,7 @@ function MenuModal({savedInfo, reloadFunction}){
|
||||||
<Form.Control type="number" min={"0"} name="menuLevel" placeholder="레벨" required defaultValue={savedInfo!==undefined?savedInfo.menuLevel:0} />
|
<Form.Control type="number" min={"0"} name="menuLevel" placeholder="레벨" required defaultValue={savedInfo!==undefined?savedInfo.menuLevel:0} />
|
||||||
</Col>
|
</Col>
|
||||||
</Form.Group>
|
</Form.Group>
|
||||||
<Form.Group as={Row} className="mb-3">
|
<Form.Group as={Row} className="mb-3 d-none">
|
||||||
<Form.Label column sm={3}>
|
<Form.Label column sm={3}>
|
||||||
정렬
|
정렬
|
||||||
</Form.Label>
|
</Form.Label>
|
||||||
|
|
@ -120,7 +120,7 @@ function MenuModal({savedInfo, reloadFunction}){
|
||||||
</Form.Group>
|
</Form.Group>
|
||||||
<Form.Group as={Row} className="mb-3">
|
<Form.Group as={Row} className="mb-3">
|
||||||
<Form.Label column sm={3}>
|
<Form.Label column sm={3}>
|
||||||
URI
|
경로
|
||||||
</Form.Label>
|
</Form.Label>
|
||||||
<Col sm={9}>
|
<Col sm={9}>
|
||||||
<Form.Control type="text" name="menuUrl" placeholder="URI" required defaultValue={savedInfo?.menuUrl} />
|
<Form.Control type="text" name="menuUrl" placeholder="URI" required defaultValue={savedInfo?.menuUrl} />
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
import React, { useState, useEffect } from 'react';
|
import React, { useState, useEffect } from 'react';
|
||||||
import { Link, useLocation, useNavigate } from 'react-router-dom';
|
import { Link, useLocation, useNavigate } from 'react-router-dom';
|
||||||
import DatePicker from "react-datepicker";
|
import DatePicker from "react-datepicker";
|
||||||
|
import FileDragDrop from "../../../../components/file/FileDragDrop";
|
||||||
|
import AttachFileIcon from '@mui/icons-material/AttachFile';
|
||||||
|
|
||||||
import EgovAttachFile from 'components/EgovAttachFile';
|
import EgovAttachFile from 'components/EgovAttachFile';
|
||||||
import RichTextEditor from "../../../../components/editor/RichTextEditor";
|
import RichTextEditor from "../../../../components/editor/RichTextEditor";
|
||||||
|
|
@ -19,11 +21,30 @@ const StyledDiv = styled.div`
|
||||||
|
|
||||||
.board_view2 {
|
.board_view2 {
|
||||||
margin-bottom: 30px;
|
margin-bottom: 30px;
|
||||||
|
dl.file-attach-wrapper dd {
|
||||||
|
padding: 0px;
|
||||||
|
|
||||||
|
|
||||||
|
.file_attach {
|
||||||
|
width: 100%;
|
||||||
|
label {
|
||||||
|
width: 100%;
|
||||||
|
padding: 0px 0px;
|
||||||
|
div {
|
||||||
|
padding: 30px 10px;
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function PopupEditor(props) {
|
function PopupEditor(props) {
|
||||||
|
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
|
@ -38,7 +59,7 @@ function PopupEditor(props) {
|
||||||
const [schdulBgndeMM, setSchdulBgndeMM] = useState();
|
const [schdulBgndeMM, setSchdulBgndeMM] = useState();
|
||||||
const [schdulEnddeHH, setSchdulEnddeHH] = useState();
|
const [schdulEnddeHH, setSchdulEnddeHH] = useState();
|
||||||
const [schdulEnddeMM, setSchdulEnddeMM] = useState();
|
const [schdulEnddeMM, setSchdulEnddeMM] = useState();
|
||||||
const [boardAttachFiles, setBoardAttachFiles] = useState();
|
const [fileName, setFileName] = useState();
|
||||||
|
|
||||||
const [confirm, setConfirm] = React.useState();
|
const [confirm, setConfirm] = React.useState();
|
||||||
|
|
||||||
|
|
@ -118,6 +139,10 @@ function PopupEditor(props) {
|
||||||
});
|
});
|
||||||
setText(rawDetail.contents);
|
setText(rawDetail.contents);
|
||||||
setTextOriginal(rawDetail.contents);
|
setTextOriginal(rawDetail.contents);
|
||||||
|
|
||||||
|
if( rawDetail.fileName ) {
|
||||||
|
setFileName(rawDetail.fileName);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -141,6 +166,9 @@ function PopupEditor(props) {
|
||||||
formData.delete("contents");
|
formData.delete("contents");
|
||||||
formData.append("contents", text);
|
formData.append("contents", text);
|
||||||
|
|
||||||
|
//첨부파일
|
||||||
|
formData.append("file", file);
|
||||||
|
|
||||||
if (formValidator(formData)) {
|
if (formValidator(formData)) {
|
||||||
const requestOptions = {
|
const requestOptions = {
|
||||||
method: modeInfo.method,
|
method: modeInfo.method,
|
||||||
|
|
@ -165,9 +193,11 @@ function PopupEditor(props) {
|
||||||
|
|
||||||
|
|
||||||
if (modeInfo.mode === CODE.MODE_CREATE) {
|
if (modeInfo.mode === CODE.MODE_CREATE) {
|
||||||
setConfirm({...confirm, open: true, body: "추가하시겠습니까?", yesCallback: requestTask, yesCallbackParams: {requestUrl:modeInfo.editURL}});
|
//setConfirm({...confirm, open: true, body: "추가하시겠습니까?", yesCallback: requestTask, yesCallbackParams: {requestUrl:modeInfo.editURL}});
|
||||||
|
requestTask({requestUrl:modeInfo.editURL});
|
||||||
} else if (modeInfo.mode === CODE.MODE_MODIFY) {
|
} else if (modeInfo.mode === CODE.MODE_MODIFY) {
|
||||||
setConfirm({...confirm, open: true, body: "수정하시겠습니까?", yesCallback: requestTask, yesCallbackParams: {requestUrl:`${modeInfo.editURL}/${location.state?.popupId}`}});
|
//setConfirm({...confirm, open: true, body: "수정하시겠습니까?", yesCallback: requestTask, yesCallbackParams: {requestUrl:`${modeInfo.editURL}/${location.state?.popupId}`}});
|
||||||
|
requestTask({requestUrl:`${modeInfo.editURL}/${location.state?.popupId}`});
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -233,6 +263,24 @@ function PopupEditor(props) {
|
||||||
return number < 10 ? "0" + number : number.toString();
|
return number < 10 ? "0" + number : number.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const fileTypes = ["JPG", "PNG", "GIF", "PDF", "HWP", "HWPX", "ZIP", "JPEG", "MP4", "TXT"];
|
||||||
|
const onDrop = (e) => {
|
||||||
|
//alert('ddd');
|
||||||
|
};
|
||||||
|
|
||||||
|
const [file, setFile] = useState(null);
|
||||||
|
const handleChange = (file) => {
|
||||||
|
setFile(file);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
useEffect(function () {
|
||||||
|
if( file ) {
|
||||||
|
console.log('%o', file);
|
||||||
|
}
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
}, [file]);
|
||||||
|
|
||||||
|
|
||||||
const Location = React.memo(function Location() {
|
const Location = React.memo(function Location() {
|
||||||
return (
|
return (
|
||||||
|
|
@ -263,7 +311,7 @@ function PopupEditor(props) {
|
||||||
{/* <!-- 본문 --> */}
|
{/* <!-- 본문 --> */}
|
||||||
<StyledDiv>
|
<StyledDiv>
|
||||||
<div className="top_tit">
|
<div className="top_tit">
|
||||||
<h1 className="tit_1">팝업 추가</h1>
|
<h1 className="tit_1">팝업 관리</h1>
|
||||||
</div>
|
</div>
|
||||||
{/* <!-- 상단 입력 form --> */}
|
{/* <!-- 상단 입력 form --> */}
|
||||||
<div className='board_view2'>
|
<div className='board_view2'>
|
||||||
|
|
@ -316,21 +364,27 @@ function PopupEditor(props) {
|
||||||
</span>
|
</span>
|
||||||
</dd>
|
</dd>
|
||||||
</dl>
|
</dl>
|
||||||
<EgovAttachFile
|
<dl className="file-attach-wrapper">
|
||||||
fnChangeFile={(attachfile) => {
|
<dt>첨부파일</dt>
|
||||||
console.log("====>>> Changed attachfile file = ", attachfile);
|
<dd>
|
||||||
const arrayConcat = { ...popupDetail}; // 기존 단일 파일 업로드에서 다중파일 객체 추가로 변환(아래 for문으로)
|
<span className="file_attach">
|
||||||
for ( let i = 0; i < attachfile.length; i++) {
|
<FileDragDrop
|
||||||
arrayConcat[`file_${i}`] = attachfile[i];
|
className="file-drag-drop"
|
||||||
}
|
multiple={false}
|
||||||
setPopupDetail(arrayConcat);
|
fileTypes={fileTypes}
|
||||||
}}
|
onDrop={onDrop}
|
||||||
fnDeleteFile={(deletedFile) => {
|
handleChange={handleChange}
|
||||||
console.log("====>>> Delete deletedFile = ", deletedFile);
|
dropMessageStyle={{backgroundColor: '#cfe2ff'}}
|
||||||
setBoardAttachFiles(deletedFile);
|
>
|
||||||
}}
|
<div>
|
||||||
boardFiles={boardAttachFiles}
|
<AttachFileIcon />
|
||||||
mode={props.mode} />
|
{file ? file.name : fileName ? fileName : "파일을 마우스로 끌어놓으세요."}
|
||||||
|
</div>
|
||||||
|
</FileDragDrop>
|
||||||
|
</span>
|
||||||
|
</dd>
|
||||||
|
</dl>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
{/* <!--// 상단 입력 form --> */}
|
{/* <!--// 상단 입력 form --> */}
|
||||||
|
|
||||||
|
|
@ -341,20 +395,20 @@ function PopupEditor(props) {
|
||||||
{/* <!-- 버튼영역 --> */}
|
{/* <!-- 버튼영역 --> */}
|
||||||
<div className="board_btn_area">
|
<div className="board_btn_area">
|
||||||
<div className="left_col btn1">
|
<div className="left_col btn1">
|
||||||
|
<button className="btn btn_blue_h46 w_100"
|
||||||
|
onClick={onClickList}>목록</button>
|
||||||
|
</div>
|
||||||
|
<div className="right_col btn1">
|
||||||
<button className="btn btn_skyblue_h46 w_100"
|
<button className="btn btn_skyblue_h46 w_100"
|
||||||
onClick={() => createPopup()}
|
onClick={() => createPopup()}
|
||||||
> 저장</button>
|
> 저장</button>
|
||||||
{modeInfo.mode === CODE.MODE_MODIFY &&
|
{modeInfo.mode === CODE.MODE_MODIFY &&
|
||||||
<button className="btn btn_skyblue_h46 w_100"
|
<button className="btn btn_red_h46 w_100"
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
onClickDelete(location.state?.popupId);
|
onClickDelete(location.state?.popupId);
|
||||||
}}>삭제</button>
|
}}>삭제</button>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
<div className="right_col btn1">
|
|
||||||
<button className="btn btn_blue_h46 w_100"
|
|
||||||
onClick={onClickList}>목록</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
{/* <!--// 버튼영역 --> */}
|
{/* <!--// 버튼영역 --> */}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,13 +14,27 @@ import styled from "styled-components";
|
||||||
|
|
||||||
const StyledDiv = styled.div`
|
const StyledDiv = styled.div`
|
||||||
.BRD008 {
|
.BRD008 {
|
||||||
.head > span:nth-child(3) {
|
.head {
|
||||||
|
span:nth-child(3) {
|
||||||
width: 200px;
|
width: 200px;
|
||||||
}
|
}
|
||||||
.result .list_item > div:nth-child(3) {
|
span:nth-child(4) {
|
||||||
width: 200px;
|
width: 200px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.result .list_item {
|
||||||
|
& > div {
|
||||||
|
&:nth-child(3) {
|
||||||
|
width: 200px;
|
||||||
|
}
|
||||||
|
&:nth-child(4) {
|
||||||
|
width: 200px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
.board-bot {
|
.board-bot {
|
||||||
margin-top: 20px;
|
margin-top: 20px;
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ import { default as EgovLeftNav } from 'components/leftmenu/EgovLeftNavAdmin';
|
||||||
import EgovPaging from 'components/EgovPaging';
|
import EgovPaging from 'components/EgovPaging';
|
||||||
|
|
||||||
import { itemIdxByPage } from 'utils/calc';
|
import { itemIdxByPage } from 'utils/calc';
|
||||||
|
import {format} from "date-fns";
|
||||||
|
|
||||||
function PrivacyConnections(props) {
|
function PrivacyConnections(props) {
|
||||||
// console.group("EgovAdminPrivacyList");
|
// console.group("EgovAdminPrivacyList");
|
||||||
|
|
@ -66,7 +67,7 @@ function PrivacyConnections(props) {
|
||||||
<div>{item.targetUserId}</div>
|
<div>{item.targetUserId}</div>
|
||||||
<div>{item.accessType === "PRV_LIST" ? "사용자현황 조회" : item.accessType === "PRV_VIEW" ? "User 상세조회" : "User 수정"}</div>
|
<div>{item.accessType === "PRV_LIST" ? "사용자현황 조회" : item.accessType === "PRV_VIEW" ? "User 상세조회" : "User 수정"}</div>
|
||||||
<div>{item.ipAddress}</div>
|
<div>{item.ipAddress}</div>
|
||||||
<div>{item.accessDt}</div>
|
<div>{item.accessDt ? format(item.accessDt, "yyyy-MM-dd HH:mm") : ""}</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -122,7 +123,7 @@ function PrivacyConnections(props) {
|
||||||
<span>수정 ID</span>
|
<span>수정 ID</span>
|
||||||
<span>타입</span>
|
<span>타입</span>
|
||||||
<span>접속IP</span>
|
<span>접속IP</span>
|
||||||
<span>변경일자</span>
|
<span>일자</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="result">
|
<div className="result">
|
||||||
{listTag}
|
{listTag}
|
||||||
|
|
|
||||||
|
|
@ -1,24 +1,18 @@
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { useState } from 'react';
|
import React, { useState, useEffect, useCallback } from 'react';
|
||||||
import { Link as RouterLink } from 'react-router-dom';
|
import { Link as RouterLink } from 'react-router-dom';
|
||||||
|
|
||||||
// material-ui
|
// material-ui
|
||||||
import { Box, Link, Table, TableBody, TableCell, TableContainer, TableHead, TableRow } from '@mui/material';
|
import { Box, Link, Table, TableBody, TableCell, TableContainer, TableHead, TableRow } from '@mui/material';
|
||||||
|
|
||||||
|
import * as EgovNet from 'api/egovFetch';
|
||||||
|
import {itemIdxByPage} from "../../../utils/calc";
|
||||||
|
import {format} from "date-fns";
|
||||||
|
|
||||||
function createData(trackingNo, title, dt, name) {
|
function createData(trackingNo, title, dt, name) {
|
||||||
return { trackingNo, title, dt, name };
|
return { trackingNo, title, dt, name };
|
||||||
}
|
}
|
||||||
|
|
||||||
const rows = [
|
|
||||||
createData(1, '흙막이 가시설 띠장 전단 설계시 플래지 ...', '2024-02-04 13:22', '홍길동'),
|
|
||||||
createData(2, '콘크리트 벽체 설계기준 적용 유무 확인 ...', '2024-02-04 13:22', '홍길동'),
|
|
||||||
createData(3, '한중콘크리트 초기양생 관련', '2024-02-04 13:22', '홍길동'),
|
|
||||||
createData(4, 'KDS 21 30 00 : 2022가설흙...', '2024-02-04 13:22', '홍길동'),
|
|
||||||
createData(5, '인테리어필름 시방서 관련', '2024-02-04 13:22', '홍길동'),
|
|
||||||
createData(6, '고온고압증기양생기포콘크리트(ALC) 구조', '2024-02-04 13:22', '홍길동'),
|
|
||||||
createData(7, '지반을 최저등급으로 가정한 경우란', '2024-02-04 13:22', '홍길동')
|
|
||||||
];
|
|
||||||
|
|
||||||
function descendingComparator(a, b, orderBy) {
|
function descendingComparator(a, b, orderBy) {
|
||||||
if (b[orderBy] < a[orderBy]) {
|
if (b[orderBy] < a[orderBy]) {
|
||||||
return -1;
|
return -1;
|
||||||
|
|
@ -110,6 +104,68 @@ export default function OrderTable() {
|
||||||
const [orderBy] = useState('trackingNo');
|
const [orderBy] = useState('trackingNo');
|
||||||
const [selected] = useState([]);
|
const [selected] = useState([]);
|
||||||
|
|
||||||
|
const [listTag, setListTag] = useState([]);
|
||||||
|
|
||||||
|
const retrieveList = useCallback(() => {
|
||||||
|
// console.groupCollapsed("EgovAdminUsageList.retrieveList()");
|
||||||
|
|
||||||
|
const retrieveListURL = '/admin/dashboard/question';
|
||||||
|
|
||||||
|
const requestOptions = {
|
||||||
|
method: "POST",
|
||||||
|
headers: {
|
||||||
|
'Content-type': 'application/json',
|
||||||
|
},
|
||||||
|
body: JSON.stringify()
|
||||||
|
}
|
||||||
|
|
||||||
|
EgovNet.requestFetch(retrieveListURL,
|
||||||
|
requestOptions,
|
||||||
|
(resp) => {
|
||||||
|
let mutListTag = [];
|
||||||
|
|
||||||
|
const resultCnt = parseInt(resp.result.QuestionList.length);
|
||||||
|
// const currentPageNo = 1; // resp.result.paginationInfo.currentPageNo;
|
||||||
|
// const pageSize = resultCnt; // resp.result.paginationInfo.pageSize;
|
||||||
|
|
||||||
|
// 리스트 항목 구성
|
||||||
|
if (resultCnt === 0) {
|
||||||
|
mutListTag.push(createData('', '데이터가 없습니다.', '', ''));
|
||||||
|
} else {
|
||||||
|
resp.result.QuestionList.forEach(function (item, index) {
|
||||||
|
if (index === 0) mutListTag = []; // 목록 초기화
|
||||||
|
// const listIdx = itemIdxByPage(resultCnt, currentPageNo, pageSize, index);
|
||||||
|
|
||||||
|
mutListTag.push(
|
||||||
|
createData(index+1, item[0], item[1], item[2]),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
setListTag(mutListTag);
|
||||||
|
},
|
||||||
|
function (resp) {
|
||||||
|
console.log("err response : ", resp);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
// console.groupEnd("EgovAdminPrivacyList.retrieveList()");
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
},[listTag]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
retrieveList();
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
// const rows = [listTag
|
||||||
|
// createData(1, '흙막이 가시설 띠장 전단 설계시 플래지 ...', '2024-02-04 13:22', '홍길동'),
|
||||||
|
// createData(2, '콘크리트 벽체 설계기준 적용 유무 확인 ...', '2024-02-04 13:22', '홍길동'),
|
||||||
|
// createData(3, '한중콘크리트 초기양생 관련', '2024-02-04 13:22', '홍길동'),
|
||||||
|
// createData(4, 'KDS 21 30 00 : 2022가설흙...', '2024-02-04 13:22', '홍길동'),
|
||||||
|
// createData(5, '인테리어필름 시방서 관련', '2024-02-04 13:22', '홍길동'),
|
||||||
|
// createData(6, '고온고압증기양생기포콘크리트(ALC) 구조', '2024-02-04 13:22', '홍길동'),
|
||||||
|
// createData(7, '지반을 최저등급으로 가정한 경우란', '2024-02-04 13:22', '홍길동')
|
||||||
|
// ];
|
||||||
|
|
||||||
const isSelected = (trackingNo) => selected.indexOf(trackingNo) !== -1;
|
const isSelected = (trackingNo) => selected.indexOf(trackingNo) !== -1;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
@ -137,7 +193,7 @@ export default function OrderTable() {
|
||||||
>
|
>
|
||||||
<OrderTableHead order={order} orderBy={orderBy} />
|
<OrderTableHead order={order} orderBy={orderBy} />
|
||||||
<TableBody>
|
<TableBody>
|
||||||
{stableSort(rows, getComparator(order, orderBy)).map((row, index) => {
|
{stableSort(listTag, getComparator(order, orderBy)).map((row, index) => {
|
||||||
const isItemSelected = isSelected(row.trackingNo);
|
const isItemSelected = isSelected(row.trackingNo);
|
||||||
const labelId = `enhanced-table-checkbox-${index}`;
|
const labelId = `enhanced-table-checkbox-${index}`;
|
||||||
|
|
||||||
|
|
@ -153,7 +209,7 @@ export default function OrderTable() {
|
||||||
>
|
>
|
||||||
<TableCell width="10%" align="left" component="th" id={labelId} scope="row">{row.trackingNo}</TableCell>
|
<TableCell width="10%" align="left" component="th" id={labelId} scope="row">{row.trackingNo}</TableCell>
|
||||||
<TableCell width="50%" align="left"><Link color="secondary" component={RouterLink} to="" sx={{ overflow: 'hidden', textOverflow: 'ellipsis', display: 'block'}}>{row.title}</Link></TableCell>
|
<TableCell width="50%" align="left"><Link color="secondary" component={RouterLink} to="" sx={{ overflow: 'hidden', textOverflow: 'ellipsis', display: 'block'}}>{row.title}</Link></TableCell>
|
||||||
<TableCell width="25%" align="center">{row.dt}</TableCell>
|
<TableCell width="25%" align="center">{row.dt? format(row.dt, "yyyy-MM-dd HH:mm") : ""}</TableCell>
|
||||||
<TableCell width="15%" align="center">{row.name}</TableCell>
|
<TableCell width="15%" align="center">{row.name}</TableCell>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,8 @@
|
||||||
import React, {useState, useEffect, useCallback} from 'react'; // PureComponent
|
import React, {useState, useEffect, useCallback} from 'react'; // PureComponent
|
||||||
import {Link} from 'react-router-dom'; //useLocation
|
import {Link} from 'react-router-dom'; //useLocation
|
||||||
|
|
||||||
// import {BarChart, Bar, XAxis, YAxis, CartesianGrid, Tooltip, Legend, ResponsiveContainer} from 'recharts';
|
|
||||||
|
|
||||||
import * as EgovNet from 'api/egovFetch';
|
import * as EgovNet from 'api/egovFetch';
|
||||||
import URL from 'constants/url';
|
import URL from 'constants/url';
|
||||||
// import CODE from 'constants/code';
|
|
||||||
|
|
||||||
// material-ui
|
// material-ui
|
||||||
import { Box, Button, Grid, Stack, Typography } from '@mui/material';
|
import { Box, Button, Grid, Stack, Typography } from '@mui/material';
|
||||||
|
|
@ -27,34 +24,12 @@ function EgovAdminDashboard(props) {
|
||||||
// console.log("EgovAdminScheduleList [location] : ", location);
|
// console.log("EgovAdminScheduleList [location] : ", location);
|
||||||
|
|
||||||
const DATE = new Date();
|
const DATE = new Date();
|
||||||
// const TODAY = new Date(DATE.getFullYear(), DATE.getMonth(), DATE.getDate());
|
|
||||||
//
|
|
||||||
// const [searchCondition, setSearchCondition] = useState(location.state?.searchCondition || {schdulSe: '', year: TODAY.getFullYear(), month: TODAY.getMonth(), date: TODAY.getDate()});
|
|
||||||
// const [calendarTag, setCalendarTag] = useState([]);
|
|
||||||
|
|
||||||
// const innerConsole = (...args) => {
|
|
||||||
// console.log(...args);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// const changeDate = (target, amount) => {
|
|
||||||
// let changedDate;
|
|
||||||
//
|
|
||||||
// if (target === CODE.DATE_YEAR) {
|
|
||||||
// changedDate = new Date(searchCondition.year + amount, searchCondition.month, searchCondition.date);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// if (target === CODE.DATE_MONTH) {
|
|
||||||
// changedDate = new Date(searchCondition.year, searchCondition.month + amount, searchCondition.date);
|
|
||||||
// }
|
|
||||||
// setSearchCondition({...searchCondition, year: changedDate.getFullYear(), month: changedDate.getMonth(), date: changedDate.getDate()});
|
|
||||||
// }
|
|
||||||
|
|
||||||
// const [countTag, setCountTag] = useState([]);
|
|
||||||
const [dashboardCnt, setDashboardCnt] = useState({
|
const [dashboardCnt, setDashboardCnt] = useState({
|
||||||
ConnMonthlyCount: [[0, 0.0, 0]],
|
ConnMonthlyCount: [[0, 0.0, 0]],
|
||||||
DocuMonthlyCount: [[0, 0.0, 0]]
|
ErrorMonthlyCount: [[0, 0.0, 0]],
|
||||||
|
DocuMonthlyCount: [[0, 0.0, 0]],
|
||||||
|
CompMonthlyCount: [[0, 0.0, 0]]
|
||||||
});
|
});
|
||||||
// const [item0, setItem0] = useState([]);
|
|
||||||
|
|
||||||
const retrieveList = useCallback(() => {
|
const retrieveList = useCallback(() => {
|
||||||
const retrieveListURL = '/admin/dashboard/dash-count';
|
const retrieveListURL = '/admin/dashboard/dash-count';
|
||||||
|
|
@ -69,21 +44,8 @@ function EgovAdminDashboard(props) {
|
||||||
EgovNet.requestFetch(retrieveListURL,
|
EgovNet.requestFetch(retrieveListURL,
|
||||||
requestOptions,
|
requestOptions,
|
||||||
(resp) => {
|
(resp) => {
|
||||||
// let mutCountTag = [];
|
|
||||||
setDashboardCnt(resp.result);
|
setDashboardCnt(resp.result);
|
||||||
console.log(resp.result.ConnMonthlyCount);
|
// console.log(resp.result.CompMonthlyCount);
|
||||||
|
|
||||||
// mutCountTag.push(
|
|
||||||
// <div key={listIdx} className="list_item">
|
|
||||||
// <div>{listIdx}</div>
|
|
||||||
// <div>{item.userId}</div>
|
|
||||||
// <div>{item.targetUserId}</div>
|
|
||||||
// <div>{item.accessType === "PRV_LIST" ? "사용자현황 조회" : item.accessType === "PRV_VIEW" ? "User 상세조회" : "User 수정"}</div>
|
|
||||||
// <div>{item.ipAddress}</div>
|
|
||||||
// <div>{item.accessDt}</div>
|
|
||||||
// </div>
|
|
||||||
// );
|
|
||||||
// setCountTag(mutCountTag);
|
|
||||||
},
|
},
|
||||||
function (resp) {
|
function (resp) {
|
||||||
console.log("err response : ", resp);
|
console.log("err response : ", resp);
|
||||||
|
|
@ -92,123 +54,10 @@ function EgovAdminDashboard(props) {
|
||||||
// eslint-disable-next-lie react-hooks/exhaustive-deps
|
// eslint-disable-next-lie react-hooks/exhaustive-deps
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
|
||||||
// const Location = React.memo(function Location() {
|
|
||||||
// return (
|
|
||||||
// <div className="location">
|
|
||||||
// <ul>
|
|
||||||
// <li><Link to={URL.MAIN} className="home">Home</Link></li>
|
|
||||||
// <li><Link to={URL.ADMIN}>사이트관리</Link></li>
|
|
||||||
// <li>Dashboard</li>
|
|
||||||
// </ul>
|
|
||||||
// </div>
|
|
||||||
// )
|
|
||||||
// });
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
retrieveList();
|
retrieveList();
|
||||||
}, [retrieveList]);
|
}, [retrieveList]);
|
||||||
|
|
||||||
// const [dailyUserLogList, setDailyUserLogList] = useState([]);
|
|
||||||
// const [isDailyChart, setIsDailyChart] = useState(true);
|
|
||||||
//
|
|
||||||
// const getDailyUserLogList = useCallback(() => {
|
|
||||||
// // console.groupCollapsed("EgovAdminScheduleList.getDailyUserLogList()");
|
|
||||||
// //
|
|
||||||
// // console.log("@@@ isDailyChart : " + isDailyChart);
|
|
||||||
//
|
|
||||||
// const dailyUserLogListURL = isDailyChart ? '/admin/dashboard/daily-user-log-list' : '/admin/dashboard/monthly-user-log-list';
|
|
||||||
//
|
|
||||||
// const requestOptions = {
|
|
||||||
// method: "GET",
|
|
||||||
// headers: {
|
|
||||||
// 'Content-type': 'application/json',
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// EgovNet.requestFetch(dailyUserLogListURL,
|
|
||||||
// requestOptions,
|
|
||||||
// (resp) => {
|
|
||||||
// setDailyUserLogList(resp.result.dailyUserLogList);
|
|
||||||
// // console.log("@@@ : " + dailyUserLogList);
|
|
||||||
// },
|
|
||||||
// function (resp) {
|
|
||||||
// // console.log("err response : ", resp);
|
|
||||||
// }
|
|
||||||
// );
|
|
||||||
// // console.groupEnd("EgovAdminScheduleList.getDailyUserLogList()");
|
|
||||||
// // eslint-disable-next-line react-hooks/exhaustive-deps
|
|
||||||
// }, [isDailyChart]);
|
|
||||||
//
|
|
||||||
// useEffect(() => {
|
|
||||||
// getDailyUserLogList();
|
|
||||||
// // eslint-disable-next-line react-hooks/exhaustive-deps
|
|
||||||
// }, [isDailyChart]);
|
|
||||||
//
|
|
||||||
// const handleChartToggle = () => {
|
|
||||||
// setIsDailyChart(!isDailyChart);
|
|
||||||
// };
|
|
||||||
//
|
|
||||||
// const ChartToggle = ({onToggle}) => {
|
|
||||||
//
|
|
||||||
// const handleToggle = () => {
|
|
||||||
// onToggle(!isDailyChart);
|
|
||||||
// };
|
|
||||||
//
|
|
||||||
// return (
|
|
||||||
// <button onClick={handleToggle}>
|
|
||||||
// {isDailyChart ? '월별차트보기' : '일별차트보기'}
|
|
||||||
// </button>
|
|
||||||
// )
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// const data = dailyUserLogList.map(item => ({
|
|
||||||
// logDt: item.logDt,
|
|
||||||
// uv: item.mobileCnt,
|
|
||||||
// "사용자 접속현황": item.logCnt,
|
|
||||||
// amt: item.pcCnt,
|
|
||||||
// }));
|
|
||||||
//
|
|
||||||
// const CustomTooltip = ({active, payload, label}) => {
|
|
||||||
// if (active && payload && payload.length) {
|
|
||||||
// return (
|
|
||||||
// <div className="custom-tooltip">
|
|
||||||
// <p className="desc">사용자 접속 현황</p>
|
|
||||||
// <p className="label">{`${label} : ${payload[0].value}`}</p>
|
|
||||||
// </div>
|
|
||||||
// );
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// return null;
|
|
||||||
// };
|
|
||||||
|
|
||||||
// class UserLogChart extends PureComponent {
|
|
||||||
// render() {
|
|
||||||
// return (
|
|
||||||
// <ResponsiveContainer width="100%" height="100%">
|
|
||||||
// <BarChart
|
|
||||||
// width={500}
|
|
||||||
// height={300}
|
|
||||||
// data={data}
|
|
||||||
// margin={{
|
|
||||||
// top: 5,
|
|
||||||
// right: 30,
|
|
||||||
// left: 20,
|
|
||||||
// bottom: 5,
|
|
||||||
// }}
|
|
||||||
// >
|
|
||||||
// <CartesianGrid strokeDasharray="3 3"/>
|
|
||||||
// <XAxis dataKey="logDt"/>
|
|
||||||
// <YAxis/>
|
|
||||||
// <Tooltip content={<CustomTooltip/>}/>
|
|
||||||
// <Legend/>
|
|
||||||
// <Bar dataKey="사용자 접속현황" barSize={20} fill="#87CEFA"/>
|
|
||||||
// </BarChart>
|
|
||||||
// </ResponsiveContainer>
|
|
||||||
// );
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// console.log("------------------------------EgovAdminScheduleList [End]");
|
// console.log("------------------------------EgovAdminScheduleList [End]");
|
||||||
// console.groupEnd("EgovAdminScheduleList");
|
// console.groupEnd("EgovAdminScheduleList");
|
||||||
|
|
||||||
|
|
@ -255,13 +104,13 @@ function EgovAdminDashboard(props) {
|
||||||
<AnalyticEcommerce title={`총접속자수 (${DATE.getMonth() + 1}월)`} count={dashboardCnt.ConnMonthlyCount[0]?.[0]?.toLocaleString() || '0'} percentage={parseFloat(dashboardCnt.ConnMonthlyCount[0]?.[1]) || 0} extra={dashboardCnt.ConnMonthlyCount[0]?.[2]?.toLocaleString() || '0'} isLoss={dashboardCnt.ConnMonthlyCount[0]?.[1] < 0} color={dashboardCnt.ConnMonthlyCount[0]?.[1] < 0 ? "warning" : "primary"} />
|
<AnalyticEcommerce title={`총접속자수 (${DATE.getMonth() + 1}월)`} count={dashboardCnt.ConnMonthlyCount[0]?.[0]?.toLocaleString() || '0'} percentage={parseFloat(dashboardCnt.ConnMonthlyCount[0]?.[1]) || 0} extra={dashboardCnt.ConnMonthlyCount[0]?.[2]?.toLocaleString() || '0'} isLoss={dashboardCnt.ConnMonthlyCount[0]?.[1] < 0} color={dashboardCnt.ConnMonthlyCount[0]?.[1] < 0 ? "warning" : "primary"} />
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid item xs={12} sm={6} md={4} lg={3}>
|
<Grid item xs={12} sm={6} md={4} lg={3}>
|
||||||
<AnalyticEcommerce title={`건설기준 오류건수 (${DATE.getMonth() + 1}월)`} count="78,250" percentage={70.5} extra="8,900" />
|
<AnalyticEcommerce title={`건설기준 오류건수 (${DATE.getMonth() + 1}월)`} count={dashboardCnt.ErrorMonthlyCount[0]?.[0]?.toLocaleString() || '0'} percentage={parseFloat(dashboardCnt.ErrorMonthlyCount[0]?.[1]) || 0} extra={dashboardCnt.ErrorMonthlyCount[0]?.[2]?.toLocaleString() || '0'} isLoss={dashboardCnt.ErrorMonthlyCount[0]?.[1] < 0} color={dashboardCnt.ErrorMonthlyCount[0]?.[1] < 0 ? "warning" : "primary"} />
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid item xs={12} sm={6} md={4} lg={3}>
|
<Grid item xs={12} sm={6} md={4} lg={3}>
|
||||||
<AnalyticEcommerce title={`기준코드 등록건수 (${DATE.getMonth() + 1}월)`} count={dashboardCnt.DocuMonthlyCount[0]?.[0]?.toLocaleString() || '0'} percentage={parseFloat(dashboardCnt.DocuMonthlyCount[0]?.[1]) || 0} extra={dashboardCnt.DocuMonthlyCount[0]?.[2]?.toLocaleString() || '0'} isLoss={dashboardCnt.DocuMonthlyCount[0]?.[1] < 0} color={dashboardCnt.DocuMonthlyCount[0]?.[1] < 0 ? "warning" : "primary"} />
|
<AnalyticEcommerce title={`기준코드 등록건수 (${DATE.getMonth() + 1}월)`} count={dashboardCnt.DocuMonthlyCount[0]?.[0]?.toLocaleString() || '0'} percentage={parseFloat(dashboardCnt.DocuMonthlyCount[0]?.[1]) || 0} extra={dashboardCnt.DocuMonthlyCount[0]?.[2]?.toLocaleString() || '0'} isLoss={dashboardCnt.DocuMonthlyCount[0]?.[1] < 0} color={dashboardCnt.DocuMonthlyCount[0]?.[1] < 0 ? "warning" : "primary"} />
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid item xs={12} sm={6} md={4} lg={3}>
|
<Grid item xs={12} sm={6} md={4} lg={3}>
|
||||||
<AnalyticEcommerce title={`민원건수 (${DATE.getMonth() + 1}월)`} count="5" percentage={80} extra="1" isLoss color="warning" />
|
<AnalyticEcommerce title={`민원건수 (${DATE.getMonth() + 1}월)`} count={dashboardCnt.CompMonthlyCount[0]?.[0]?.toLocaleString() || '0'} percentage={parseFloat(dashboardCnt.CompMonthlyCount[0]?.[1]) || 0} extra={dashboardCnt.CompMonthlyCount[0]?.[2]?.toLocaleString() || '0'} isLoss={dashboardCnt.CompMonthlyCount[0]?.[1] < 0} color={dashboardCnt.CompMonthlyCount[0]?.[1] < 0 ? "warning" : "primary"} />
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
<Grid item md={8} sx={{ display: { sm: 'none', md: 'block', lg: 'none' } }} />
|
<Grid item md={8} sx={{ display: { sm: 'none', md: 'block', lg: 'none' } }} />
|
||||||
|
|
|
||||||
|
|
@ -64,10 +64,6 @@ function List({}) {
|
||||||
);
|
);
|
||||||
},[]);
|
},[]);
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
retrieveList(searchCondition);
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
retrieveList(searchCondition);
|
retrieveList(searchCondition);
|
||||||
}, [searchCondition.pageIndex]);
|
}, [searchCondition.pageIndex]);
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,9 @@
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { SERVER_URL } from 'config';
|
import * as File from "utils/file"
|
||||||
import {Button, Modal, Nav} from "react-bootstrap";
|
import {Button, Modal, Nav} from "react-bootstrap";
|
||||||
|
|
||||||
function HistoryModal({closeFn, standardCode}){
|
function HistoryModal({closeFn, standardCode}){
|
||||||
|
|
||||||
function fileDownload(fileSeq){
|
|
||||||
window.open(encodeURI(SERVER_URL+'/file/download?fileSeq='+fileSeq));
|
|
||||||
}
|
|
||||||
|
|
||||||
return(
|
return(
|
||||||
<>
|
<>
|
||||||
<Modal.Header closeButton>
|
<Modal.Header closeButton>
|
||||||
|
|
@ -30,11 +26,11 @@ function HistoryModal({closeFn, standardCode}){
|
||||||
<div className="mainCategory">{history.rvsnYmd.split('T')[0]}</div>
|
<div className="mainCategory">{history.rvsnYmd.split('T')[0]}</div>
|
||||||
<div className="middleCategory">
|
<div className="middleCategory">
|
||||||
{history.docFileGrpId}
|
{history.docFileGrpId}
|
||||||
{history.docFileGrpId?<Button size={"sm"} variant={"outline-secondary"} onClick={()=>fileDownload(history.docFileGrpId)}>다운로드 </Button>:''}
|
{history.docFileGrpId?<Button size={"sm"} variant={"outline-secondary"} onClick={()=>File.standardCode(history.docFileGrpId)}>다운로드 </Button>:''}
|
||||||
</div>
|
</div>
|
||||||
<div className="kcscCd">
|
<div className="kcscCd">
|
||||||
{history.rvsnFileGrpId}
|
{history.rvsnFileGrpId}
|
||||||
{history.rvsnFileGrpId?<Button size={"sm"} variant={"outline-secondary"} onClick={()=>fileDownload(history.rvsnFileGrpId)}>다운로드 </Button>:''}
|
{history.rvsnFileGrpId?<Button size={"sm"} variant={"outline-secondary"} onClick={()=>File.download(history.rvsnFileGrpId)}>다운로드 </Button>:''}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,7 @@
|
||||||
import React, { useState, useEffect, useCallback } from 'react';
|
import React, { useState, useEffect, useCallback } from 'react';
|
||||||
import { useLocation, useParams } from 'react-router-dom';
|
import { useLocation, useParams } from 'react-router-dom';
|
||||||
import SbItem from './SbItem'
|
|
||||||
import Loading from 'components/Loading'
|
import Loading from 'components/Loading'
|
||||||
import BookmarkModal from './BookmarkModal';
|
import BookmarkModal from './BookmarkModal';
|
||||||
import {SbContainer} from './Sb.style'
|
|
||||||
import {VwDiv, VwPtag} from './Vw.style'
|
import {VwDiv, VwPtag} from './Vw.style'
|
||||||
import Form from 'react-bootstrap/Form'
|
import Form from 'react-bootstrap/Form'
|
||||||
import Row from 'react-bootstrap/Row';
|
import Row from 'react-bootstrap/Row';
|
||||||
|
|
@ -16,6 +14,7 @@ import {parseJwt} from "utils/parseJwt";
|
||||||
import Button from "react-bootstrap/Button";
|
import Button from "react-bootstrap/Button";
|
||||||
import {InputGroup} from "react-bootstrap";
|
import {InputGroup} from "react-bootstrap";
|
||||||
import ViewerTree from "./ViewerTree";
|
import ViewerTree from "./ViewerTree";
|
||||||
|
import * as File from "utils/file";
|
||||||
|
|
||||||
function CodeViewer(props) {
|
function CodeViewer(props) {
|
||||||
const [treeLoading, setTreeLoading] = useState(true);
|
const [treeLoading, setTreeLoading] = useState(true);
|
||||||
|
|
@ -73,6 +72,8 @@ function CodeViewer(props) {
|
||||||
let optionTag = [];
|
let optionTag = [];
|
||||||
let activeIndex = 0;
|
let activeIndex = 0;
|
||||||
let docTitle = "";
|
let docTitle = "";
|
||||||
|
let docFileGrpId = "";
|
||||||
|
let rvsnFileGrpId = "";
|
||||||
if(ymd===undefined){
|
if(ymd===undefined){
|
||||||
activeIndex = docInfo.length-1
|
activeIndex = docInfo.length-1
|
||||||
docTitle = docInfo[docInfo.length-1].doc_nm
|
docTitle = docInfo[docInfo.length-1].doc_nm
|
||||||
|
|
@ -95,7 +96,10 @@ function CodeViewer(props) {
|
||||||
if(index === activeIndex){
|
if(index === activeIndex){
|
||||||
buttonClass += "docInfoActive"
|
buttonClass += "docInfoActive"
|
||||||
pClass += "yearInfoActive"
|
pClass += "yearInfoActive"
|
||||||
|
docFileGrpId = item.doc_file_grp_id;
|
||||||
|
rvsnFileGrpId = item.rvsn_file_grp_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
optionTag.push(
|
optionTag.push(
|
||||||
<Col>
|
<Col>
|
||||||
<input type="button"
|
<input type="button"
|
||||||
|
|
@ -109,7 +113,22 @@ function CodeViewer(props) {
|
||||||
<p className={pClass}>{item.doc_yr}</p>
|
<p className={pClass}>{item.doc_yr}</p>
|
||||||
</Col>)
|
</Col>)
|
||||||
})
|
})
|
||||||
headTag.push(<Row className="docInfoRow"><Col className="docInfoTitle">{docCode} {docTitle}</Col>{optionTag}</Row>)
|
headTag.push(
|
||||||
|
<>
|
||||||
|
<Col xs={"auto"}>
|
||||||
|
<Row className="docInfoRow">
|
||||||
|
<Col className="docInfoTitle">{docCode} {docTitle}</Col>
|
||||||
|
{optionTag}
|
||||||
|
</Row>
|
||||||
|
</Col>
|
||||||
|
<Col>
|
||||||
|
<input type="button" className="btn btn-sm btn-primary optionBtn" value="연혁"/>
|
||||||
|
<input type="button" className="btn btn-sm btn-primary optionBtn" value="2단비교"/>
|
||||||
|
{rvsnFileGrpId?<input type="button" className="btn btn-sm btn-primary optionBtn" value="신구조문" onClick={()=>{File.download(rvsnFileGrpId)}}/>:''}
|
||||||
|
{docFileGrpId?<input type="button" className="btn btn-sm btn-primary optionBtn" value="첨부파일" onClick={()=>{File.standardCode(docFileGrpId)}}/>:''}
|
||||||
|
</Col>
|
||||||
|
</>
|
||||||
|
)
|
||||||
}else{
|
}else{
|
||||||
headTag.push(<div>검색된 결과가 없습니다.</div>); // 코드 목록 초기값
|
headTag.push(<div>검색된 결과가 없습니다.</div>); // 코드 목록 초기값
|
||||||
}
|
}
|
||||||
|
|
@ -409,13 +428,7 @@ function CodeViewer(props) {
|
||||||
<Row className="justify-content-between">
|
<Row className="justify-content-between">
|
||||||
<Col xs={"auto"}>
|
<Col xs={"auto"}>
|
||||||
<Row>
|
<Row>
|
||||||
<Col xs={"auto"}>{docInfo}</Col>
|
{docInfo}
|
||||||
<Col>
|
|
||||||
<input type="button" className="btn btn-sm btn-primary optionBtn" value="연혁"/>
|
|
||||||
<input type="button" className="btn btn-sm btn-primary optionBtn" value="2단비교"/>
|
|
||||||
<input type="button" className="btn btn-sm btn-primary optionBtn" value="신구조문"/>
|
|
||||||
<input type="button" className="btn btn-sm btn-primary optionBtn" value="첨부파일"/>
|
|
||||||
</Col>
|
|
||||||
</Row>
|
</Row>
|
||||||
</Col>
|
</Col>
|
||||||
<Col xs={"auto"}>
|
<Col xs={"auto"}>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
import {SERVER_URL} from "../config";
|
||||||
|
import {parseJwt} from "./parseJwt";
|
||||||
|
import {getLocalItem} from "./storage";
|
||||||
|
|
||||||
|
export function download(fileSeq){
|
||||||
|
window.open(encodeURI(SERVER_URL+'/file/download?fileSeq='+fileSeq));
|
||||||
|
}
|
||||||
|
export function standardCode(fileSeq){
|
||||||
|
const sessionUser = parseJwt(getLocalItem('accessToken'));
|
||||||
|
window.open(encodeURI(SERVER_URL+'/file/standardCode-download?userId='+sessionUser?.id+'&fileSeq='+fileSeq));
|
||||||
|
}
|
||||||
|
|
@ -8613,6 +8613,14 @@ react-dom@^18.2.0:
|
||||||
loose-envify "^1.1.0"
|
loose-envify "^1.1.0"
|
||||||
scheduler "^0.23.0"
|
scheduler "^0.23.0"
|
||||||
|
|
||||||
|
react-drag-drop-files@^2.3.10:
|
||||||
|
version "2.3.10"
|
||||||
|
resolved "https://registry.yarnpkg.com/react-drag-drop-files/-/react-drag-drop-files-2.3.10.tgz#3f6ea316f8ad66a6f76b312cc4108c7c14065b06"
|
||||||
|
integrity sha512-Fv614W9+OtXFB5O+gjompTxQZLYGO7wJeT4paETGiXtiADB9yPOMGYD4A3PMCTY9Be874/wcpl+2dm3MvCIRzg==
|
||||||
|
dependencies:
|
||||||
|
prop-types "^15.7.2"
|
||||||
|
styled-components "^5.3.0"
|
||||||
|
|
||||||
react-element-to-jsx-string@^15.0.0:
|
react-element-to-jsx-string@^15.0.0:
|
||||||
version "15.0.0"
|
version "15.0.0"
|
||||||
resolved "https://registry.npmjs.org/react-element-to-jsx-string/-/react-element-to-jsx-string-15.0.0.tgz"
|
resolved "https://registry.npmjs.org/react-element-to-jsx-string/-/react-element-to-jsx-string-15.0.0.tgz"
|
||||||
|
|
@ -9604,7 +9612,7 @@ style-loader@^3.3.1:
|
||||||
resolved "https://registry.npmjs.org/style-loader/-/style-loader-3.3.1.tgz"
|
resolved "https://registry.npmjs.org/style-loader/-/style-loader-3.3.1.tgz"
|
||||||
integrity sha512-GPcQ+LDJbrcxHORTRes6Jy2sfvK2kS6hpSfI/fXhPt+spVzxF6LJ1dHLN9zIGmVaaP044YKaIatFaufENRiDoQ==
|
integrity sha512-GPcQ+LDJbrcxHORTRes6Jy2sfvK2kS6hpSfI/fXhPt+spVzxF6LJ1dHLN9zIGmVaaP044YKaIatFaufENRiDoQ==
|
||||||
|
|
||||||
styled-components@^5.3.5:
|
styled-components@^5.3.0, styled-components@^5.3.5:
|
||||||
version "5.3.11"
|
version "5.3.11"
|
||||||
resolved "https://registry.npmjs.org/styled-components/-/styled-components-5.3.11.tgz"
|
resolved "https://registry.npmjs.org/styled-components/-/styled-components-5.3.11.tgz"
|
||||||
integrity sha512-uuzIIfnVkagcVHv9nE0VPlHPSCmXIUGKfJ42LNjxCCTDTL5sgnJ8Z7GZBq0EnLYGln77tPpEpExt2+qa+cZqSw==
|
integrity sha512-uuzIIfnVkagcVHv9nE0VPlHPSCmXIUGKfJ42LNjxCCTDTL5sgnJ8Z7GZBq0EnLYGln77tPpEpExt2+qa+cZqSw==
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@ public class TcMenu {
|
||||||
@Column(name = "menu_sort")
|
@Column(name = "menu_sort")
|
||||||
private Integer menuSort;
|
private Integer menuSort;
|
||||||
@Column(name = "menu_url")
|
@Column(name = "menu_url")
|
||||||
@NotBlank(message = "메뉴URI를 입력해주세요.")
|
@NotBlank(message = "경로를 입력해주세요.")
|
||||||
private String menuUrl;
|
private String menuUrl;
|
||||||
@Column(name = "menu_type_cd")
|
@Column(name = "menu_type_cd")
|
||||||
@NotBlank(message = "타입을 선택해주세요.")
|
@NotBlank(message = "타입을 선택해주세요.")
|
||||||
|
|
|
||||||
|
|
@ -44,9 +44,9 @@ public class AdminDashboardController extends BaseController {
|
||||||
Map<String, Object> resultMap = new HashMap<>();
|
Map<String, Object> resultMap = new HashMap<>();
|
||||||
|
|
||||||
resultMap.put("ConnMonthlyCount", adminDashboardService.selectConnMonthly());
|
resultMap.put("ConnMonthlyCount", adminDashboardService.selectConnMonthly());
|
||||||
resultMap.put("DocuMonthlyCount", adminDashboardService.selectDocuMonthly());
|
resultMap.put("ErrorMonthlyCount", adminDashboardService.selectErrorMonthly());
|
||||||
// resultMap.put("loginMonthlyList", adminDashboardService.selectLoginMonthly());
|
resultMap.put("DocuMonthlyCount", adminDashboardService.selectDocumentMonthly());
|
||||||
// resultMap.put("loginDailyList", adminDashboardService.selectLoginDaily());
|
resultMap.put("CompMonthlyCount", adminDashboardService.selectComplaintMonthly());
|
||||||
|
|
||||||
resultVO.setResultCode(ResponseCode.SUCCESS.getCode());
|
resultVO.setResultCode(ResponseCode.SUCCESS.getCode());
|
||||||
resultVO.setResultMessage(ResponseCode.SUCCESS.getMessage());
|
resultVO.setResultMessage(ResponseCode.SUCCESS.getMessage());
|
||||||
|
|
@ -108,6 +108,31 @@ public class AdminDashboardController extends BaseController {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Operation(
|
||||||
|
summary = "미답변 문의사항 조회",
|
||||||
|
description = "미답변 문의사항 조회",
|
||||||
|
tags = {"AdminDashboardController"}
|
||||||
|
)
|
||||||
|
@ApiResponses(value = {
|
||||||
|
@ApiResponse(responseCode = "200", description = "조회 성공"),
|
||||||
|
@ApiResponse(responseCode = "403", description = "인가된 사용자가 아님")
|
||||||
|
})
|
||||||
|
@RequestMapping(method = RequestMethod.POST, value = "/question", consumes = MediaType.APPLICATION_JSON_VALUE)
|
||||||
|
public ResultVO getBbs(@AuthenticationPrincipal LoginVO user)
|
||||||
|
throws Exception {
|
||||||
|
|
||||||
|
ResultVO resultVO = new ResultVO();
|
||||||
|
Map<String, Object> resultMap = new HashMap<>();
|
||||||
|
|
||||||
|
resultMap.put("QuestionList", adminDashboardService.selectQuestion());
|
||||||
|
|
||||||
|
resultVO.setResultCode(ResponseCode.SUCCESS.getCode());
|
||||||
|
resultVO.setResultMessage(ResponseCode.SUCCESS.getMessage());
|
||||||
|
resultVO.setResult(resultMap);
|
||||||
|
return resultVO;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Operation(
|
@Operation(
|
||||||
summary = "해당월 접속방법 조회",
|
summary = "해당월 접속방법 조회",
|
||||||
description = "해당월 PC/MOBILE 조회",
|
description = "해당월 PC/MOBILE 조회",
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,33 @@ public interface DashboardRepository extends JpaRepository<TnDailyMenuLog, Long>
|
||||||
"FROM this_month_logs, last_month_logs", nativeQuery = true)
|
"FROM this_month_logs, last_month_logs", nativeQuery = true)
|
||||||
List<Object[]> ConnMonthlyCount();
|
List<Object[]> ConnMonthlyCount();
|
||||||
|
|
||||||
|
|
||||||
|
@Query(value = "WITH this_month_logs AS ( " +
|
||||||
|
" SELECT count(*) AS this_month_cnt " +
|
||||||
|
" FROM tn_document_content " +
|
||||||
|
" WHERE use_yn = 'Y' AND COALESCE(error_cd, '') <> '' " +
|
||||||
|
" AND frst_crt_dt >= DATE_TRUNC('month', CURRENT_DATE - INTERVAL '1 month') " +
|
||||||
|
" AND frst_crt_dt < DATE_TRUNC('month', CURRENT_DATE) " +
|
||||||
|
"), " +
|
||||||
|
"last_month_logs AS ( " +
|
||||||
|
" SELECT count(*) AS last_month_cnt " +
|
||||||
|
" FROM tn_document_content " +
|
||||||
|
" WHERE use_yn = 'Y' AND COALESCE(error_cd, '') <> '' " +
|
||||||
|
" AND frst_crt_dt >= DATE_TRUNC('month', CURRENT_DATE - INTERVAL '1 month') " +
|
||||||
|
" AND frst_crt_dt < DATE_TRUNC('month', CURRENT_DATE) " +
|
||||||
|
") " +
|
||||||
|
"SELECT " +
|
||||||
|
" this_month_cnt, " +
|
||||||
|
" CASE " +
|
||||||
|
" WHEN last_month_cnt = 0 AND this_month_cnt = 0 THEN 0" +
|
||||||
|
" WHEN last_month_cnt = 0 THEN 100" +
|
||||||
|
" ELSE ROUND(((CAST(this_month_cnt AS NUMERIC) - last_month_cnt) / last_month_cnt * 100), 1)" +
|
||||||
|
" END AS ratio, " +
|
||||||
|
" last_month_cnt " +
|
||||||
|
"FROM this_month_logs, last_month_logs", nativeQuery = true)
|
||||||
|
List<Object[]> ErrorMonthlyCount();
|
||||||
|
|
||||||
|
|
||||||
@Query(value = "WITH this_month_logs AS ( " +
|
@Query(value = "WITH this_month_logs AS ( " +
|
||||||
" SELECT count(*) AS this_month_cnt " +
|
" SELECT count(*) AS this_month_cnt " +
|
||||||
" FROM tn_document_info " +
|
" FROM tn_document_info " +
|
||||||
|
|
@ -57,6 +84,33 @@ public interface DashboardRepository extends JpaRepository<TnDailyMenuLog, Long>
|
||||||
"FROM this_month_logs, last_month_logs", nativeQuery = true)
|
"FROM this_month_logs, last_month_logs", nativeQuery = true)
|
||||||
List<Object[]> DocuMonthlyCount();
|
List<Object[]> DocuMonthlyCount();
|
||||||
|
|
||||||
|
|
||||||
|
@Query(value = "WITH this_month_logs AS ( " +
|
||||||
|
" SELECT count(*) AS this_month_cnt " +
|
||||||
|
" FROM tn_bbs_contents " +
|
||||||
|
" WHERE bbs_id = 'KCSC-QA' AND use_yn = 'Y' " +
|
||||||
|
" AND frst_crt_dt >= DATE_TRUNC('month', CURRENT_DATE) " +
|
||||||
|
" AND frst_crt_dt < DATE_TRUNC('month', CURRENT_DATE) + INTERVAL '1 month' " +
|
||||||
|
"), " +
|
||||||
|
"last_month_logs AS ( " +
|
||||||
|
" SELECT count(*) AS last_month_cnt " +
|
||||||
|
" FROM tn_bbs_contents " +
|
||||||
|
" WHERE bbs_id = 'KCSC-QA'AND use_yn = 'Y' " +
|
||||||
|
" AND frst_crt_dt >= DATE_TRUNC('month', CURRENT_DATE - INTERVAL '1 month') " +
|
||||||
|
" AND frst_crt_dt < DATE_TRUNC('month', CURRENT_DATE) " +
|
||||||
|
") " +
|
||||||
|
"SELECT " +
|
||||||
|
" this_month_cnt, " +
|
||||||
|
" CASE " +
|
||||||
|
" WHEN last_month_cnt = 0 AND this_month_cnt = 0 THEN 0" +
|
||||||
|
" WHEN last_month_cnt = 0 THEN 100" +
|
||||||
|
" ELSE ROUND(((CAST(this_month_cnt AS NUMERIC) - last_month_cnt) / last_month_cnt * 100), 1) " +
|
||||||
|
" END AS ratio, " +
|
||||||
|
" last_month_cnt " +
|
||||||
|
"FROM this_month_logs, last_month_logs", nativeQuery = true)
|
||||||
|
List<Object[]> CompMonthlyCount();
|
||||||
|
|
||||||
|
|
||||||
@Query(value = "WITH all_months AS (" +
|
@Query(value = "WITH all_months AS (" +
|
||||||
" SELECT generate_series(DATE_TRUNC('year', CURRENT_DATE), DATE_TRUNC('year', CURRENT_DATE) + INTERVAL '11 month', INTERVAL '1 month') AS month_start" +
|
" SELECT generate_series(DATE_TRUNC('year', CURRENT_DATE), DATE_TRUNC('year', CURRENT_DATE) + INTERVAL '11 month', INTERVAL '1 month') AS month_start" +
|
||||||
")" +
|
")" +
|
||||||
|
|
@ -97,7 +151,6 @@ public interface DashboardRepository extends JpaRepository<TnDailyMenuLog, Long>
|
||||||
List<Long> LoginMonthlyList();
|
List<Long> LoginMonthlyList();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Query(value = "WITH all_days AS (" +
|
@Query(value = "WITH all_days AS (" +
|
||||||
" SELECT generate_series(" +
|
" SELECT generate_series(" +
|
||||||
" DATE_TRUNC('year', CURRENT_DATE)," +
|
" DATE_TRUNC('year', CURRENT_DATE)," +
|
||||||
|
|
@ -113,7 +166,6 @@ public interface DashboardRepository extends JpaRepository<TnDailyMenuLog, Long>
|
||||||
List<Long> LoginDailyList();
|
List<Long> LoginDailyList();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Query(value = "WITH all_days AS (" +
|
@Query(value = "WITH all_days AS (" +
|
||||||
" SELECT generate_series(" +
|
" SELECT generate_series(" +
|
||||||
" DATE_TRUNC('year', CURRENT_DATE)," +
|
" DATE_TRUNC('year', CURRENT_DATE)," +
|
||||||
|
|
@ -130,6 +182,13 @@ public interface DashboardRepository extends JpaRepository<TnDailyMenuLog, Long>
|
||||||
List<Long> FileDailyList();
|
List<Long> FileDailyList();
|
||||||
|
|
||||||
|
|
||||||
|
@Query(value = "SELECT bbs_cont_title, frst_crt_dt, frst_crt_id " +
|
||||||
|
"FROM tn_bbs_contents a " +
|
||||||
|
"WHERE bbs_id = 'KCSC-QA' AND use_yn = 'Y' " +
|
||||||
|
"AND (SELECT bbs_cont_seq b FROM public.tn_bbs_contents b WHERE bbs_id = 'KCSC-QA' AND use_yn = 'Y' AND b.bbs_cont_seq_group=a.bbs_cont_seq) IS NULL " +
|
||||||
|
"ORDER BY frst_crt_dt desc", nativeQuery = true)
|
||||||
|
List<Object[]> QuestionList();
|
||||||
|
|
||||||
|
|
||||||
@Query(value = "SELECT sum(pc_cnt) AS p_cnt, sum(mobile_cnt) AS m_cnt " +
|
@Query(value = "SELECT sum(pc_cnt) AS p_cnt, sum(mobile_cnt) AS m_cnt " +
|
||||||
"FROM tn_daily_user_log " +
|
"FROM tn_daily_user_log " +
|
||||||
|
|
|
||||||
|
|
@ -1,25 +1,25 @@
|
||||||
package com.dbnt.kcscbackend.admin.dashboard.service;
|
package com.dbnt.kcscbackend.admin.dashboard.service;
|
||||||
|
|
||||||
//import com.dbnt.kcscbackend.admin.logs.entity.TnDailyUserLog;
|
//import com.dbnt.kcscbackend.admin.boards.entity.TnBbsContents;
|
||||||
//import com.dbnt.kcscbackend.admin.dashboard.repository.TnDailyUserLogRepository;
|
|
||||||
import com.dbnt.kcscbackend.admin.dashboard.repository.DashboardRepository;
|
import com.dbnt.kcscbackend.admin.dashboard.repository.DashboardRepository;
|
||||||
import com.dbnt.kcscbackend.admin.logs.entity.TnDailyUserLog;
|
|
||||||
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;
|
||||||
|
|
||||||
//import java.time.LocalDate;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class AdminDashboardService extends EgovAbstractServiceImpl {
|
public class AdminDashboardService extends EgovAbstractServiceImpl {
|
||||||
// private final TnDailyUserLogRepository tnDailyUserLogRepository;
|
|
||||||
private final DashboardRepository dashboardRepository;
|
private final DashboardRepository dashboardRepository;
|
||||||
|
|
||||||
public List<Object[]> selectConnMonthly() { return dashboardRepository.ConnMonthlyCount(); }
|
public List<Object[]> selectConnMonthly() { return dashboardRepository.ConnMonthlyCount(); }
|
||||||
|
|
||||||
public List<Object[]> selectDocuMonthly() { return dashboardRepository.DocuMonthlyCount(); }
|
public List<Object[]> selectErrorMonthly() { return dashboardRepository.ErrorMonthlyCount(); }
|
||||||
|
|
||||||
|
public List<Object[]> selectDocumentMonthly() { return dashboardRepository.DocuMonthlyCount(); }
|
||||||
|
|
||||||
|
public List<Object[]> selectComplaintMonthly() { return dashboardRepository.CompMonthlyCount(); }
|
||||||
|
|
||||||
public List<Long> selectMenuMonthly() { return dashboardRepository.MenuMonthlyList(); }
|
public List<Long> selectMenuMonthly() { return dashboardRepository.MenuMonthlyList(); }
|
||||||
|
|
||||||
|
|
@ -31,13 +31,9 @@ public class AdminDashboardService extends EgovAbstractServiceImpl {
|
||||||
|
|
||||||
public List<Long> selectFileDaily() { return dashboardRepository.FileDailyList(); }
|
public List<Long> selectFileDaily() { return dashboardRepository.FileDailyList(); }
|
||||||
|
|
||||||
|
public List<Object[]> selectQuestion() { return dashboardRepository.QuestionList(); }
|
||||||
|
|
||||||
public List<Object[]> selectConnectMonthly() { return dashboardRepository.findConnMonthly(); }
|
public List<Object[]> selectConnectMonthly() { return dashboardRepository.findConnMonthly(); }
|
||||||
|
|
||||||
// public List<TnDailyUserLog> selectDailyUserLogList(LocalDate startDate, LocalDate endDate) {
|
|
||||||
// return tnDailyUserLogRepository.findByLogDtBetweenOrderByLogDt(startDate, endDate);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// public List<Object[]> selectMonthlyUserLogList(LocalDate startDate, LocalDate endDate) {
|
|
||||||
// return tnDailyUserLogRepository.selectMonthlyUserLogStatistics(startDate, endDate);
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,8 +9,6 @@ import org.hibernate.annotations.DynamicUpdate;
|
||||||
import org.springframework.format.annotation.DateTimeFormat;
|
import org.springframework.format.annotation.DateTimeFormat;
|
||||||
|
|
||||||
import javax.persistence.*;
|
import javax.persistence.*;
|
||||||
import java.time.LocalDate;
|
|
||||||
import java.awt.*;
|
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
|
|
|
||||||
|
|
@ -3,17 +3,14 @@ package com.dbnt.kcscbackend.admin.logs.entity;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
|
||||||
import com.dbnt.kcscbackend.config.common.BoardParams;
|
import com.dbnt.kcscbackend.config.common.BoardParams;
|
||||||
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;
|
||||||
import lombok.experimental.Accessors;
|
import lombok.experimental.Accessors;
|
||||||
import org.hibernate.annotations.DynamicInsert;
|
import org.hibernate.annotations.DynamicInsert;
|
||||||
import org.hibernate.annotations.DynamicUpdate;
|
import org.hibernate.annotations.DynamicUpdate;
|
||||||
import org.springframework.format.annotation.DateTimeFormat;
|
|
||||||
|
|
||||||
import javax.persistence.*;
|
import javax.persistence.*;
|
||||||
import java.time.LocalDate;
|
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
|
|
@ -45,8 +42,7 @@ public class ThPrivacyLog extends BoardParams implements Serializable {
|
||||||
private String ipAddress;
|
private String ipAddress;
|
||||||
|
|
||||||
@Column(name = "access_dt")
|
@Column(name = "access_dt")
|
||||||
@DateTimeFormat(pattern = "yyyy-MM-dd")
|
private LocalDateTime accessDt;
|
||||||
private LocalDate accessDt;
|
|
||||||
|
|
||||||
@Column(name = "session_id")
|
@Column(name = "session_id")
|
||||||
private String sessionId;
|
private String sessionId;
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,8 @@ public interface FileLogsRepository extends JpaRepository<ThAttachFileLog, Long>
|
||||||
+ " COUNT(CASE WHEN group_cur_cd = 'O4' THEN 1 ELSE NULL END) AS CodeO4Cnt,"
|
+ " 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 "
|
+ " COUNT(CASE WHEN group_cur_cd IN ('O5', 'O6', 'O7') THEN 1 ELSE NULL END) AS CodeO5Cnt "
|
||||||
+ "FROM th_attach_file_log "
|
+ "FROM th_attach_file_log "
|
||||||
+ "WHERE access_dt BETWEEN TO_DATE(:startDate, 'YYYY-MM-DD') AND TO_DATE(:endDate, 'YYYY-MM-DD') "
|
+ "WHERE access_dt >= TO_DATE(:startDate, 'YYYY-MM-DD') "
|
||||||
|
+ "AND access_dt < TO_DATE(:endDate, 'YYYY-MM-DD') + INTERVAL '1 day' "
|
||||||
+ "GROUP BY TO_CHAR(access_dt, 'YYYY-MM-DD') "
|
+ "GROUP BY TO_CHAR(access_dt, 'YYYY-MM-DD') "
|
||||||
+ "ORDER BY log_dt asc", nativeQuery = true)
|
+ "ORDER BY log_dt asc", nativeQuery = true)
|
||||||
List<Object[]> selectCountFile(@Param("startDate") String startDate, @Param("endDate") String endDate);
|
List<Object[]> selectCountFile(@Param("startDate") String startDate, @Param("endDate") String endDate);
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,16 @@
|
||||||
package com.dbnt.kcscbackend.admin.logs.service;
|
package com.dbnt.kcscbackend.admin.logs.service;
|
||||||
|
|
||||||
|
import com.dbnt.kcscbackend.admin.logs.entity.ThAttachFileLog;
|
||||||
import com.dbnt.kcscbackend.admin.logs.entity.ThLoginLog;
|
import com.dbnt.kcscbackend.admin.logs.entity.ThLoginLog;
|
||||||
import com.dbnt.kcscbackend.admin.logs.entity.ThPrivacyLog;
|
import com.dbnt.kcscbackend.admin.logs.entity.ThPrivacyLog;
|
||||||
import com.dbnt.kcscbackend.admin.logs.entity.TnDailyUserLog;
|
import com.dbnt.kcscbackend.admin.logs.entity.TnDailyUserLog;
|
||||||
|
import com.dbnt.kcscbackend.admin.logs.repository.FileLogsRepository;
|
||||||
import com.dbnt.kcscbackend.admin.logs.repository.PrivacyLogsRepository;
|
import com.dbnt.kcscbackend.admin.logs.repository.PrivacyLogsRepository;
|
||||||
import com.dbnt.kcscbackend.admin.logs.repository.ThLoginLogRepository;
|
import com.dbnt.kcscbackend.admin.logs.repository.ThLoginLogRepository;
|
||||||
import com.dbnt.kcscbackend.admin.logs.repository.UserLogsRepository;
|
import com.dbnt.kcscbackend.admin.logs.repository.UserLogsRepository;
|
||||||
|
import com.dbnt.kcscbackend.file.entity.TnAttachFile;
|
||||||
|
import com.dbnt.kcscbackend.standardCode.entity.TnDocumentInfo;
|
||||||
|
import com.dbnt.kcscbackend.standardCode.repository.TnDocumentInfoRepository;
|
||||||
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;
|
||||||
|
|
@ -24,6 +29,8 @@ public class AdminLogsService extends EgovAbstractServiceImpl {
|
||||||
private final PrivacyLogsRepository privacyLogsRepository;
|
private final PrivacyLogsRepository privacyLogsRepository;
|
||||||
private final ThLoginLogRepository loginLogRepository;
|
private final ThLoginLogRepository loginLogRepository;
|
||||||
private final UserLogsRepository userLogsRepository;
|
private final UserLogsRepository userLogsRepository;
|
||||||
|
private final FileLogsRepository fileLogsRepository;
|
||||||
|
private final TnDocumentInfoRepository documentInfoRepository;
|
||||||
|
|
||||||
public Map<String, Object> selectPrivacyList() {
|
public Map<String, Object> selectPrivacyList() {
|
||||||
Map<String, Object> resultMap = new HashMap<>();
|
Map<String, Object> resultMap = new HashMap<>();
|
||||||
|
|
@ -47,7 +54,7 @@ public class AdminLogsService extends EgovAbstractServiceImpl {
|
||||||
public void insertPrivacyLog(String userId, String ipAddress, String accessType, String targetUserId){
|
public void insertPrivacyLog(String userId, String ipAddress, String accessType, String targetUserId){
|
||||||
ThPrivacyLog log = new ThPrivacyLog();
|
ThPrivacyLog log = new ThPrivacyLog();
|
||||||
log.setUserId(userId);
|
log.setUserId(userId);
|
||||||
log.setAccessDt(LocalDate.now());
|
log.setAccessDt(LocalDateTime.now());
|
||||||
log.setIpAddress(ipAddress);
|
log.setIpAddress(ipAddress);
|
||||||
log.setAccessType(accessType);
|
log.setAccessType(accessType);
|
||||||
log.setTargetUserId(targetUserId);
|
log.setTargetUserId(targetUserId);
|
||||||
|
|
@ -93,4 +100,26 @@ public class AdminLogsService extends EgovAbstractServiceImpl {
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
public void insertFileLog(TnAttachFile tnAttachFile, String accessId, String ipAddress){
|
||||||
|
TnDocumentInfo documentInfo = documentInfoRepository.findByDocFileGrpId(tnAttachFile.getFileSeq().toString()).orElse(null);
|
||||||
|
ThAttachFileLog fileLog = new ThAttachFileLog();
|
||||||
|
fileLog.setFileSeq((long)tnAttachFile.getFileSeq());
|
||||||
|
fileLog.setAccessType("FILE_DOWN");
|
||||||
|
fileLog.setAccessId(accessId);
|
||||||
|
fileLog.setAccessDt(LocalDateTime.now());
|
||||||
|
fileLog.setIpAddress(ipAddress);
|
||||||
|
switch (documentInfo.getKcscCd().split(" ")[0]){
|
||||||
|
case "KDS": fileLog.setGroupCurCd("10"); break;
|
||||||
|
case "KCS": fileLog.setGroupCurCd("20"); break;
|
||||||
|
case "SMCS": fileLog.setGroupCurCd("40"); break;
|
||||||
|
case "EXCS": fileLog.setGroupCurCd("50"); break;
|
||||||
|
case "KRCCS": fileLog.setGroupCurCd("60"); break;
|
||||||
|
case "KRACS": fileLog.setGroupCurCd("70"); break;
|
||||||
|
case "LHCS": fileLog.setGroupCurCd("80"); break;
|
||||||
|
case "KWCS": fileLog.setGroupCurCd("90"); break;
|
||||||
|
}
|
||||||
|
fileLogsRepository.save(fileLog);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -72,6 +72,7 @@ public class SecurityConfig {
|
||||||
"/cmm/main/**.do", // 메인페이지
|
"/cmm/main/**.do", // 메인페이지
|
||||||
"/cmm/fms/FileDown.do", //파일 다운로드
|
"/cmm/fms/FileDown.do", //파일 다운로드
|
||||||
"/file/download", //파일 다운로드
|
"/file/download", //파일 다운로드
|
||||||
|
"/file/standardCode-download", //파일 다운로드
|
||||||
"/cmm/fms/getImage.do", //갤러리 이미지보기
|
"/cmm/fms/getImage.do", //갤러리 이미지보기
|
||||||
|
|
||||||
"/cop/bbs/selectUserBBSMasterInfAPI.do", //게시판 마스터 상세 조회
|
"/cop/bbs/selectUserBBSMasterInfAPI.do", //게시판 마스터 상세 조회
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,13 @@
|
||||||
package com.dbnt.kcscbackend.file;
|
package com.dbnt.kcscbackend.file;
|
||||||
|
|
||||||
|
import com.dbnt.kcscbackend.admin.logs.service.AdminLogsService;
|
||||||
|
import com.dbnt.kcscbackend.auth.entity.LoginVO;
|
||||||
import com.dbnt.kcscbackend.config.util.ClientUtils;
|
import com.dbnt.kcscbackend.config.util.ClientUtils;
|
||||||
import com.dbnt.kcscbackend.file.entity.TnAttachFile;
|
import com.dbnt.kcscbackend.file.entity.TnAttachFile;
|
||||||
import com.dbnt.kcscbackend.file.service.FileService;
|
import com.dbnt.kcscbackend.file.service.FileService;
|
||||||
import com.dbnt.kcscbackend.standardCode.service.StandardCodeService;
|
import com.dbnt.kcscbackend.standardCode.service.StandardCodeService;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.springframework.security.core.annotation.AuthenticationPrincipal;
|
||||||
import org.springframework.util.FileCopyUtils;
|
import org.springframework.util.FileCopyUtils;
|
||||||
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;
|
||||||
|
|
@ -20,37 +23,22 @@ import java.io.*;
|
||||||
public class FileController {
|
public class FileController {
|
||||||
|
|
||||||
private final FileService fileService;
|
private final FileService fileService;
|
||||||
private final StandardCodeService standardCodeService;
|
private final AdminLogsService adminLogsService;
|
||||||
|
|
||||||
@RequestMapping(method = RequestMethod.GET, value = "/download")
|
@RequestMapping(method = RequestMethod.GET, value = "/download")
|
||||||
public void download(HttpServletRequest request, HttpServletResponse response, TnAttachFile tnAttachFile) throws Exception{
|
public void download(HttpServletRequest request, HttpServletResponse response, TnAttachFile tnAttachFile) throws Exception{
|
||||||
|
|
||||||
tnAttachFile = fileService.selectTnAttachFile(tnAttachFile);
|
tnAttachFile = fileService.selectTnAttachFile(tnAttachFile);
|
||||||
|
fileDownload(request, response, tnAttachFile);
|
||||||
if(tnAttachFile != null){
|
|
||||||
BufferedInputStream in;
|
|
||||||
BufferedOutputStream out;
|
|
||||||
try {
|
|
||||||
File file = new File(tnAttachFile.getFilePath());
|
|
||||||
|
|
||||||
ClientUtils.setDisposition(tnAttachFile.getFileOldName(), request, response);
|
|
||||||
in = new BufferedInputStream(new FileInputStream(file));
|
|
||||||
out = new BufferedOutputStream(response.getOutputStream());
|
|
||||||
FileCopyUtils.copy(in, out);
|
|
||||||
out.flush();
|
|
||||||
if(out!=null) out.close();
|
|
||||||
if(in!=null )in.close();
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequestMapping(method = RequestMethod.GET, value = "/standardCode/download")
|
@RequestMapping(method = RequestMethod.GET, value = "/standardCode-download")
|
||||||
public void standardCodeDownload(HttpServletRequest request, HttpServletResponse response, TnAttachFile tnAttachFile) throws Exception{
|
public void standardCodeDownload(HttpServletRequest request, HttpServletResponse response, TnAttachFile tnAttachFile, String userId) throws Exception{
|
||||||
|
|
||||||
tnAttachFile = fileService.selectTnAttachFile(tnAttachFile);
|
tnAttachFile = fileService.selectTnAttachFile(tnAttachFile);
|
||||||
|
adminLogsService.insertFileLog(tnAttachFile, userId, ClientUtils.getRemoteIP(request));
|
||||||
|
fileDownload(request, response, tnAttachFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void fileDownload(HttpServletRequest request, HttpServletResponse response, TnAttachFile tnAttachFile){
|
||||||
if(tnAttachFile != null){
|
if(tnAttachFile != null){
|
||||||
BufferedInputStream in;
|
BufferedInputStream in;
|
||||||
BufferedOutputStream out;
|
BufferedOutputStream out;
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
package com.dbnt.kcscbackend.standardCode.entity;
|
package com.dbnt.kcscbackend.standardCode.entity;
|
||||||
|
|
||||||
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;
|
||||||
|
|
@ -22,9 +21,9 @@ public class TnDocumentInfo {
|
||||||
@Id
|
@Id
|
||||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||||
@Column(name = "doc_info_seq")
|
@Column(name = "doc_info_seq")
|
||||||
private int docInfoSeq;
|
private Integer docInfoSeq;
|
||||||
@Column(name = "group_seq", nullable = false)
|
@Column(name = "group_seq", nullable = false)
|
||||||
private int groupSeq;
|
private Integer groupSeq;
|
||||||
@Column(name = "kcsc_cd")
|
@Column(name = "kcsc_cd")
|
||||||
private String kcscCd;
|
private String kcscCd;
|
||||||
@Column(name = "old_kcsc_cd")
|
@Column(name = "old_kcsc_cd")
|
||||||
|
|
@ -34,7 +33,7 @@ public class TnDocumentInfo {
|
||||||
@Column(name = "doc_yr", nullable = false)
|
@Column(name = "doc_yr", nullable = false)
|
||||||
private String docYr;
|
private String docYr;
|
||||||
@Column(name = "doc_cycl", nullable = false)
|
@Column(name = "doc_cycl", nullable = false)
|
||||||
private int docCycl;
|
private Integer docCycl;
|
||||||
@Column(name = "doc_er", nullable = false)
|
@Column(name = "doc_er", nullable = false)
|
||||||
private String docEr;
|
private String docEr;
|
||||||
@Column(name = "estb_ymd")
|
@Column(name = "estb_ymd")
|
||||||
|
|
@ -44,7 +43,7 @@ public class TnDocumentInfo {
|
||||||
@Temporal(TemporalType.DATE)
|
@Temporal(TemporalType.DATE)
|
||||||
private Date rvsnYmd;
|
private Date rvsnYmd;
|
||||||
@Column(name = "doc_rev_hist_seq")
|
@Column(name = "doc_rev_hist_seq")
|
||||||
private int docRevHistSeq;
|
private Integer docRevHistSeq;
|
||||||
@Column(name = "doc_brief", length = 1000)
|
@Column(name = "doc_brief", length = 1000)
|
||||||
private String docBrief;
|
private String docBrief;
|
||||||
@Column(name = "doc_rvsn_remark", length = 1000)
|
@Column(name = "doc_rvsn_remark", length = 1000)
|
||||||
|
|
@ -66,7 +65,7 @@ public class TnDocumentInfo {
|
||||||
@Temporal(TemporalType.DATE)
|
@Temporal(TemporalType.DATE)
|
||||||
private Date aplcnEndYmd;
|
private Date aplcnEndYmd;
|
||||||
@Column(name = "doc_order", nullable = false)
|
@Column(name = "doc_order", nullable = false)
|
||||||
private int docOrder;
|
private Integer docOrder;
|
||||||
@Column(name = "last_yn", nullable = false)
|
@Column(name = "last_yn", nullable = false)
|
||||||
private char lastYn;
|
private char lastYn;
|
||||||
@Column(name = "doc_file_grp_id")
|
@Column(name = "doc_file_grp_id")
|
||||||
|
|
|
||||||
|
|
@ -6,8 +6,11 @@ import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
import org.springframework.data.jpa.repository.Query;
|
import org.springframework.data.jpa.repository.Query;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
public interface TnDocumentInfoRepository extends JpaRepository<TnDocumentInfo, Integer> {
|
public interface TnDocumentInfoRepository extends JpaRepository<TnDocumentInfo, Integer> {
|
||||||
@Query(value = "select * from sp_get_tn_document_info_by_group_cd(null, :docCode)", nativeQuery = true)
|
@Query(value = "select * from sp_get_tn_document_info_by_group_cd(null, :docCode)", nativeQuery = true)
|
||||||
List<TnDocumentInfoInterface> spGetTnDocumentInfoByGroupCd(String docCode);
|
List<TnDocumentInfoInterface> spGetTnDocumentInfoByGroupCd(String docCode);
|
||||||
|
|
||||||
|
Optional<TnDocumentInfo> findByDocFileGrpId(String fileSeq);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,2 @@
|
||||||
|
package com.dbnt.kcscbackend.util;public class NetworkUtil {
|
||||||
|
}
|
||||||
|
|
@ -17,7 +17,7 @@
|
||||||
inner join tc_code_item b on a.user_se = b.item_cd
|
inner join tc_code_item b on a.user_se = b.item_cd
|
||||||
inner join tc_code_item c on a.status = c.item_cd
|
inner join tc_code_item c on a.status = c.item_cd
|
||||||
<include refid="selectUserListWhere"></include>
|
<include refid="selectUserListWhere"></include>
|
||||||
order by user_seq asc
|
order by user_seq desc
|
||||||
limit #{rowCnt} offset #{firstIndex}
|
limit #{rowCnt} offset #{firstIndex}
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -78,6 +78,7 @@
|
||||||
</if>
|
</if>
|
||||||
and b.group_type = 'D'
|
and b.group_type = 'D'
|
||||||
</where>
|
</where>
|
||||||
|
order by doc_yr asc
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
<select id="selectStandardCodeGroupSeq" parameterType="String" resultType="Integer">
|
<select id="selectStandardCodeGroupSeq" parameterType="String" resultType="Integer">
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@
|
||||||
from tc_menu a
|
from tc_menu a
|
||||||
inner join tc_code_item b on a.menu_type_cd = b.item_cd
|
inner join tc_code_item b on a.menu_type_cd = b.item_cd
|
||||||
where a.use_yn = 'Y'
|
where a.use_yn = 'Y'
|
||||||
order by menu_id asc
|
order by menu_type_cd desc, menu_id asc
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
<select id="selectMenuAuthList" resultType="TcMenu">
|
<select id="selectMenuAuthList" resultType="TcMenu">
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue