diff --git a/egovframe-template-simple-react-contribution/public/assets/images/Icon_chk.png b/egovframe-template-simple-react-contribution/public/assets/images/Icon_chk.png new file mode 100644 index 0000000..432eb70 Binary files /dev/null and b/egovframe-template-simple-react-contribution/public/assets/images/Icon_chk.png differ diff --git a/egovframe-template-simple-react-contribution/public/assets/images/dropdown-menu.png b/egovframe-template-simple-react-contribution/public/assets/images/dropdown-menu.png new file mode 100644 index 0000000..60dae88 Binary files /dev/null and b/egovframe-template-simple-react-contribution/public/assets/images/dropdown-menu.png differ diff --git a/egovframe-template-simple-react-contribution/public/assets/images/file.png b/egovframe-template-simple-react-contribution/public/assets/images/file.png new file mode 100644 index 0000000..5d6c0ba Binary files /dev/null and b/egovframe-template-simple-react-contribution/public/assets/images/file.png differ diff --git a/egovframe-template-simple-react-contribution/public/assets/images/ico-landing1.png b/egovframe-template-simple-react-contribution/public/assets/images/ico-landing1.png new file mode 100644 index 0000000..051049e Binary files /dev/null and b/egovframe-template-simple-react-contribution/public/assets/images/ico-landing1.png differ diff --git a/egovframe-template-simple-react-contribution/public/assets/images/ico-landing10.png b/egovframe-template-simple-react-contribution/public/assets/images/ico-landing10.png new file mode 100644 index 0000000..dbf6b7f Binary files /dev/null and b/egovframe-template-simple-react-contribution/public/assets/images/ico-landing10.png differ diff --git a/egovframe-template-simple-react-contribution/public/assets/images/ico-landing11.png b/egovframe-template-simple-react-contribution/public/assets/images/ico-landing11.png new file mode 100644 index 0000000..223a1b9 Binary files /dev/null and b/egovframe-template-simple-react-contribution/public/assets/images/ico-landing11.png differ diff --git a/egovframe-template-simple-react-contribution/public/assets/images/ico-landing2.png b/egovframe-template-simple-react-contribution/public/assets/images/ico-landing2.png new file mode 100644 index 0000000..4a9fa1c Binary files /dev/null and b/egovframe-template-simple-react-contribution/public/assets/images/ico-landing2.png differ diff --git a/egovframe-template-simple-react-contribution/public/assets/images/ico-landing3.png b/egovframe-template-simple-react-contribution/public/assets/images/ico-landing3.png new file mode 100644 index 0000000..94de567 Binary files /dev/null and b/egovframe-template-simple-react-contribution/public/assets/images/ico-landing3.png differ diff --git a/egovframe-template-simple-react-contribution/public/assets/images/ico-landing4.png b/egovframe-template-simple-react-contribution/public/assets/images/ico-landing4.png new file mode 100644 index 0000000..fee4c3c Binary files /dev/null and b/egovframe-template-simple-react-contribution/public/assets/images/ico-landing4.png differ diff --git a/egovframe-template-simple-react-contribution/public/assets/images/ico-landing5.png b/egovframe-template-simple-react-contribution/public/assets/images/ico-landing5.png new file mode 100644 index 0000000..16973fc Binary files /dev/null and b/egovframe-template-simple-react-contribution/public/assets/images/ico-landing5.png differ diff --git a/egovframe-template-simple-react-contribution/public/assets/images/ico-landing6.png b/egovframe-template-simple-react-contribution/public/assets/images/ico-landing6.png new file mode 100644 index 0000000..c7b5bef Binary files /dev/null and b/egovframe-template-simple-react-contribution/public/assets/images/ico-landing6.png differ diff --git a/egovframe-template-simple-react-contribution/public/assets/images/ico-landing7.png b/egovframe-template-simple-react-contribution/public/assets/images/ico-landing7.png new file mode 100644 index 0000000..d3dd74a Binary files /dev/null and b/egovframe-template-simple-react-contribution/public/assets/images/ico-landing7.png differ diff --git a/egovframe-template-simple-react-contribution/public/assets/images/ico-landing8.png b/egovframe-template-simple-react-contribution/public/assets/images/ico-landing8.png new file mode 100644 index 0000000..cb7243d Binary files /dev/null and b/egovframe-template-simple-react-contribution/public/assets/images/ico-landing8.png differ diff --git a/egovframe-template-simple-react-contribution/public/assets/images/ico-landing9.png b/egovframe-template-simple-react-contribution/public/assets/images/ico-landing9.png new file mode 100644 index 0000000..e43c2c5 Binary files /dev/null and b/egovframe-template-simple-react-contribution/public/assets/images/ico-landing9.png differ diff --git a/egovframe-template-simple-react-contribution/public/assets/images/icon_answer.png b/egovframe-template-simple-react-contribution/public/assets/images/icon_answer.png new file mode 100644 index 0000000..f4d31ef Binary files /dev/null and b/egovframe-template-simple-react-contribution/public/assets/images/icon_answer.png differ diff --git a/egovframe-template-simple-react-contribution/public/assets/images/icon_answer0.png b/egovframe-template-simple-react-contribution/public/assets/images/icon_answer0.png new file mode 100644 index 0000000..ae29af3 Binary files /dev/null and b/egovframe-template-simple-react-contribution/public/assets/images/icon_answer0.png differ diff --git a/egovframe-template-simple-react-contribution/public/assets/images/icon_id.png b/egovframe-template-simple-react-contribution/public/assets/images/icon_id.png new file mode 100644 index 0000000..848563a Binary files /dev/null and b/egovframe-template-simple-react-contribution/public/assets/images/icon_id.png differ diff --git a/egovframe-template-simple-react-contribution/public/assets/images/icon_pw.png b/egovframe-template-simple-react-contribution/public/assets/images/icon_pw.png new file mode 100644 index 0000000..0512257 Binary files /dev/null and b/egovframe-template-simple-react-contribution/public/assets/images/icon_pw.png differ diff --git a/egovframe-template-simple-react-contribution/public/assets/images/icon_qna.png b/egovframe-template-simple-react-contribution/public/assets/images/icon_qna.png new file mode 100644 index 0000000..93dc5b3 Binary files /dev/null and b/egovframe-template-simple-react-contribution/public/assets/images/icon_qna.png differ diff --git a/egovframe-template-simple-react-contribution/public/assets/images/kcsc.ico b/egovframe-template-simple-react-contribution/public/assets/images/kcsc.ico new file mode 100644 index 0000000..d1d899c Binary files /dev/null and b/egovframe-template-simple-react-contribution/public/assets/images/kcsc.ico differ diff --git a/egovframe-template-simple-react-contribution/public/assets/images/lock.png b/egovframe-template-simple-react-contribution/public/assets/images/lock.png new file mode 100644 index 0000000..ee7ebaf Binary files /dev/null and b/egovframe-template-simple-react-contribution/public/assets/images/lock.png differ diff --git a/egovframe-template-simple-react-contribution/public/assets/images/mail.png b/egovframe-template-simple-react-contribution/public/assets/images/mail.png new file mode 100644 index 0000000..e75d5f9 Binary files /dev/null and b/egovframe-template-simple-react-contribution/public/assets/images/mail.png differ diff --git a/egovframe-template-simple-react-contribution/public/assets/images/nanae-1.png b/egovframe-template-simple-react-contribution/public/assets/images/nanae-1.png new file mode 100644 index 0000000..75ca5cc Binary files /dev/null and b/egovframe-template-simple-react-contribution/public/assets/images/nanae-1.png differ diff --git a/egovframe-template-simple-react-contribution/public/assets/images/narae.jpg b/egovframe-template-simple-react-contribution/public/assets/images/narae.jpg new file mode 100644 index 0000000..9c1d3e8 Binary files /dev/null and b/egovframe-template-simple-react-contribution/public/assets/images/narae.jpg differ diff --git a/egovframe-template-simple-react-contribution/public/assets/images/new.png b/egovframe-template-simple-react-contribution/public/assets/images/new.png new file mode 100644 index 0000000..6cff67d Binary files /dev/null and b/egovframe-template-simple-react-contribution/public/assets/images/new.png differ diff --git a/egovframe-template-simple-react-contribution/public/assets/images/pdf.png b/egovframe-template-simple-react-contribution/public/assets/images/pdf.png new file mode 100644 index 0000000..4c95d69 Binary files /dev/null and b/egovframe-template-simple-react-contribution/public/assets/images/pdf.png differ diff --git a/egovframe-template-simple-react-contribution/public/assets/images/pdf1.png b/egovframe-template-simple-react-contribution/public/assets/images/pdf1.png new file mode 100644 index 0000000..80ebacb Binary files /dev/null and b/egovframe-template-simple-react-contribution/public/assets/images/pdf1.png differ diff --git a/egovframe-template-simple-react-contribution/public/assets/images/re.png b/egovframe-template-simple-react-contribution/public/assets/images/re.png new file mode 100644 index 0000000..dbea731 Binary files /dev/null and b/egovframe-template-simple-react-contribution/public/assets/images/re.png differ diff --git a/egovframe-template-simple-react-contribution/public/assets/images/t_count.png b/egovframe-template-simple-react-contribution/public/assets/images/t_count.png new file mode 100644 index 0000000..3780b79 Binary files /dev/null and b/egovframe-template-simple-react-contribution/public/assets/images/t_count.png differ diff --git a/egovframe-template-simple-react-contribution/public/assets/images/예시.png b/egovframe-template-simple-react-contribution/public/assets/images/예시.png new file mode 100644 index 0000000..4d335c4 Binary files /dev/null and b/egovframe-template-simple-react-contribution/public/assets/images/예시.png differ diff --git a/egovframe-template-simple-react-contribution/public/index.html b/egovframe-template-simple-react-contribution/public/index.html index 553dcd6..dc1a4d8 100644 --- a/egovframe-template-simple-react-contribution/public/index.html +++ b/egovframe-template-simple-react-contribution/public/index.html @@ -1,9 +1,12 @@ - React App - - + 국가건설기준센터(KCSC) + + + + +
diff --git a/egovframe-template-simple-react-contribution/src/api/egovFetch.js b/egovframe-template-simple-react-contribution/src/api/egovFetch.js index 4ed6da9..37bfddb 100644 --- a/egovframe-template-simple-react-contribution/src/api/egovFetch.js +++ b/egovframe-template-simple-react-contribution/src/api/egovFetch.js @@ -56,8 +56,12 @@ export function requestFetch(url, requestOptions, handler, errorHandler) { }) .then((resp) => { if (Number(resp.resultCode) === Number(CODE.RCV_ERROR_AUTH)) { - alert("로그인이 해제되었습니다.") - window.location.href = "/login" + if(url === "/auth/login"){ + alert("로그인을 실패하였습니다.") + }else{ + alert("로그인이 해제되었습니다.") + window.location.href = "/login" + } }else{ return resp; } diff --git a/egovframe-template-simple-react-contribution/src/components/EgovFooter.jsx b/egovframe-template-simple-react-contribution/src/components/EgovFooter.jsx index cc5dd62..16ef788 100644 --- a/egovframe-template-simple-react-contribution/src/components/EgovFooter.jsx +++ b/egovframe-template-simple-react-contribution/src/components/EgovFooter.jsx @@ -1,7 +1,13 @@ -import React from 'react'; -import { Link } from 'react-router-dom'; +import React, { useState, useCallback } from 'react'; +import {Link, NavLink} from 'react-router-dom'; +import URL from "../constants/url"; + +import Collapse from 'react-bootstrap/Collapse' function EgovFooter() { + const [toggle, setToggle] = useState(false); + const toggleFunc = useCallback(() => setToggle(!toggle), [toggle]); + if(window.location.pathname.includes("/standardCode/viewer")){ return null; }else{ @@ -9,34 +15,52 @@ function EgovFooter() {
-
건설기준코드
건설기준위원회
정보제공
센터소개
-
건설기준코드 안내 | 건설기준코드 검색 | (구)건설기준 검색
- 진행현황 | 위원회 일정
- 공지사항 | Q&A | 수요조사 | 주요행사 | 건설교육안내 | 기술자료 | 보도자료 | 관련사이트 | API서비스 | 영문기준 제공 | 건설기준용어 | 건설기준 연구
- 인사말 | 연혁 | 홍보자료 | 주요업무 | 찾아오시는길 +
건설기준코드
건설기준위원회
정보제공
센터소개
+
+ + + 건설기준코드 안내 + 건설기준코드 검색 + (구)건설기준 검색 + 건설기준고시 + 영문건설기준 + 건설기준용어
+ 진행현황 + 위원회 일정
+ 공지사항 + Q&A + 수요조사 + 주요행사 + {/*건설교육안내*/} + 기술자료 + 보도자료 + 건설기준 연구 + 관련사이트 + API서비스 + 설문조사
+
+
+ 인사말 + 연혁 + 홍보자료 + 주요업무 + 찾아오시는길 + SITEMAP
+
-
-

- -

-
+
+

상호명 : 한국건설기술연구원 | 대표자 : 김병석 | 대표메일 : kcsc@kict.re.kr
사업자등록번호 : 229-82-01135 | 주소 : 경기도 고양시 일산서구 고양대로 283(대화동)

Copyright © 2011 KOREA INSTITUTE of CIVIL ENGINEERING and BUILDING TECHNOLOGY. All Rights Reserved.

-
- {/**/} - {/* */} - {/* */} - {/**/} - {/**/} - {/* */} - {/* */} - {/**/} +
+ 개인정보처리방침 + 이메일 무단수집거부
diff --git a/egovframe-template-simple-react-contribution/src/components/EgovHeader.jsx b/egovframe-template-simple-react-contribution/src/components/EgovHeader.jsx index 4937059..b1d2d43 100644 --- a/egovframe-template-simple-react-contribution/src/components/EgovHeader.jsx +++ b/egovframe-template-simple-react-contribution/src/components/EgovHeader.jsx @@ -8,6 +8,8 @@ import CODE from 'constants/code'; import { getSessionItem, setSessionItem } from 'utils/storage'; import { getLocalItem, setLocalItem } from 'utils/storage'; import {parseJwt} from "../utils/parseJwt"; +import Col from "react-bootstrap/Col"; +import Row from "react-bootstrap/Row"; function EgovHeader({ loginUser, onChangeLogin }) { console.group("EgovHeader"); @@ -18,9 +20,15 @@ function EgovHeader({ loginUser, onChangeLogin }) { const userInfo = parseJwt(accessToken); const sessionUserId = userInfo?.id; const sessionUserSe = userInfo?.userSe; + const sessionUserRole = userInfo?.userRole; const navigate = useNavigate(); + const [showMore, setShowMore] = useState(false); + const toggleShowMore = () => { + setShowMore(!showMore); + }; + const logInHandler = () => { // 로그인 정보 없을 시 navigate(URL.LOGIN); // PC와 Mobile 열린메뉴 닫기: 2023.04.13(목) 김일국 추가 @@ -57,6 +65,13 @@ function EgovHeader({ loginUser, onChangeLogin }) { ); } + const myHandler = () => { // 로그인 정보 없을 시 + if (sessionUserId) + navigate(URL.MY); + else + navigate(URL.JOIN); + } + function allMenuControl(){ setMenuDiv(!menuDiv); } @@ -73,27 +88,90 @@ function EgovHeader({ loginUser, onChangeLogin }) { //
-

- -
국가건설기준센터
국가건설기준센터 - 국가건설기준센터{/*국가건설기준센터*/} -

- -
-

주메뉴

- */} + {/*
*/} {/* */} -
- {/* 로그아웃 : 로그인 정보 있을때 */} - {sessionUserId && - <> - {sessionUserId} 님이, {sessionUserSe==='ACC_TP01'?'관리자':'사용자'}로 로그인하셨습니다. - - - } - {/* 로그인 : 로그인 정보 없을 때 */} - {!sessionUserId && - - } -
+ {/*
*/} + {/* /!* 로그아웃 : 로그인 정보 있을때 *!/*/} + {/* {sessionUserId &&*/} + {/* <>*/} + {/* {sessionUserId} {sessionUserRole==='ROLE_001' && '[최고관리]'}{sessionUserRole==='ROLE_002' && '[관리자]'}  */} + {/* */} + {/* */} + {/* */} + {/* }*/} + {/* /!* 로그인 : 로그인 정보 없을 때 *!/*/} + {/* {!sessionUserId &&*/} + {/* */} + {/* }*/} + {/*
*/} {/* */} {/* */} -
- - -
+ {/*
*/} + {/* */} + {/* */} + {/*
*/}
{/* */}

전체메뉴

-
+

건설기준코드

  • (isActive ? "cur" : "")}>건설기준코드 안내
  • (isActive ? "cur" : "")}>건설기준코드 검색
  • +
  • (isActive ? "cur" : "")}>(구)건설기준검색
  • +
  • (isActive ? "cur" : "")}>건설기준고시
  • +
  • (isActive ? "cur" : "")}>영문건설기준
  • +
  • (isActive ? "cur" : "")}>건설기준용어
- {/*
-

사이트소개

+
+

건설기준위원회

    -
  • (isActive ? "cur" : "")}>소개
  • -
  • (isActive ? "cur" : "")}>연혁
  • -
  • (isActive ? "cur" : "")}>조직소개
  • -
  • (isActive ? "cur" : "")}>찾아오시는 길
  • +
  • (isActive ? "cur" : "")}>진행현황
  • +
  • (isActive ? "cur" : "")}>위원회일정
-
*/} +
+
+

정보제공

+
    +
  • (isActive ? "cur" : "")}>공지사항
  • +
  • (isActive ? "cur" : "")}>Q&A
  • +
  • (isActive ? "cur" : "")}>수요조사
  • +
  • (isActive ? "cur" : "")}>주요행사
  • + {/*
  • (isActive ? "cur" : "")}>건설교육안내
  • */} +
  • (isActive ? "cur" : "")}>기술자료
  • +
  • (isActive ? "cur" : "")}>보도자료
  • +
  • (isActive ? "cur" : "")}>건설기준연구
  • +
  • (isActive ? "cur" : "")}>관련사이트
  • +
  • (isActive ? "cur" : "")}>API서비스
  • +
  • (isActive ? "cur" : "")}>설문조사
  • +
+
+
+

센터소개

+
    +
  • (isActive ? "cur" : "")}>인사말
  • +
  • (isActive ? "cur" : "")}>연혁
  • +
  • (isActive ? "cur" : "")}>홍보자료
  • +
  • (isActive ? "cur" : "")}>주요업무
  • +
  • (isActive ? "cur" : "")}>찾아오시는길
  • +
+
-
-

정보마당

-
    -
  • (isActive ? "cur" : "")}>주요사업 소개
  • -
  • (isActive ? "cur" : "")}>대표서비스 소개
  • -
-
-
-

고객지원

-
    -
  • (isActive ? "cur" : "")}>자료실
  • -
  • (isActive ? "cur" : "")}>묻고 답하기
  • -
  • (isActive ? "cur" : "")}>서비스 신청
  • -
-
-
-

알림마당

-
    -
  • 오늘의 행사
  • -
  • (isActive ? "cur" : "")}>금주의 행사
  • -
  • (isActive ? "cur" : "")}>공지사항
  • -
  • (isActive ? "cur" : "")}>사이트 갤러리
  • -
-
+ {/*
*/} + {/*

정보마당

*/} + {/*
    */} + {/*
  • (isActive ? "cur" : "")}>주요사업 소개
  • */} + {/*
  • (isActive ? "cur" : "")}>대표서비스 소개
  • */} + {/*
*/} + {/*
*/} + {/*
*/} + {/*

고객지원

*/} + {/*
    */} + {/*
  • (isActive ? "cur" : "")}>자료실
  • */} + {/*
  • (isActive ? "cur" : "")}>묻고 답하기
  • */} + {/*
  • (isActive ? "cur" : "")}>서비스 신청
  • */} + {/*
*/} + {/*
*/} + {/*
*/} + {/*

알림마당

*/} + {/*
    */} + {/*
  • 오늘의 행사
  • */} + {/*
  • (isActive ? "cur" : "")}>금주의 행사
  • */} + {/*
  • (isActive ? "cur" : "")}>공지사항
  • */} + {/*
  • (isActive ? "cur" : "")}>사이트 갤러리
  • */} + {/*
*/} + {/*
*/} {sessionUserSe ==='ACC_TP01' && -
+

사이트관리

    -
  • (isActive ? "cur" : "")}>일정관리
  • -
  • (isActive ? "cur" : "")}>게시판생성관리
  • +
  • (isActive ? "cur" : "")}>Dashboard
  • + {/*
  • (isActive ? "cur" : "")}>게시판생성관리
  • (isActive ? "cur" : "")}>게시판사용관리
  • (isActive ? "cur" : "")}>공지사항관리
  • (isActive ? "cur" : "")}>사이트갤러리관리
  • -
  • (isActive ? "cur" : "")}>사이트관리자 암호변경
  • +
  • (isActive ? "cur" : "")}>사이트관리자 암호변경
  • */}
} + {sessionUserId && +
+ +
+ } + {!sessionUserId && +
+ +
+ }
+ + + + {/* */}
@@ -209,9 +330,10 @@ function EgovHeader({ loginUser, onChangeLogin }) {

사이트소개

    -
  • (isActive ? "cur" : "")}>소개
  • +
  • (isActive ? "cur" : "")}>인사말
  • (isActive ? "cur" : "")}>연혁
  • -
  • (isActive ? "cur" : "")}>조직소개
  • +
  • (isActive ? "cur" : "")}>홍보자료
  • +
  • (isActive ? "cur" : "")}>주요업무
  • (isActive ? "cur" : "")}>찾아오시는 길
@@ -241,8 +363,8 @@ function EgovHeader({ loginUser, onChangeLogin }) {
{sessionUserSe ==='ACC_TP01' && <> -

사이트관리

-
+

사이트관리

+ {/*
  • (isActive ? "cur" : "")}>일정관리
  • (isActive ? "cur" : "")}>게시판생성관리
  • @@ -251,7 +373,7 @@ function EgovHeader({ loginUser, onChangeLogin }) {
  • (isActive ? "cur" : "")}>사이트갤러리관리
  • (isActive ? "cur" : "")}>사이트관리자 암호변경
-
+
*/} }
diff --git a/egovframe-template-simple-react-contribution/src/components/leftmenu/EgovLeftNavAbout.jsx b/egovframe-template-simple-react-contribution/src/components/leftmenu/EgovLeftNavAbout.jsx index 130e9eb..8f5d3c8 100644 --- a/egovframe-template-simple-react-contribution/src/components/leftmenu/EgovLeftNavAbout.jsx +++ b/egovframe-template-simple-react-contribution/src/components/leftmenu/EgovLeftNavAbout.jsx @@ -5,13 +5,14 @@ import URL from 'constants/url'; function EgovLeftNavAbout() { return ( -
-
-

사이트 소개

-
    -
  • (isActive ? "cur" : "")}>소개
  • +
    +
    +

    센터 소개

    +
      +
    • (isActive ? "cur" : "")}>인사말
    • (isActive ? "cur" : "")}>연혁
    • -
    • (isActive ? "cur" : "")}>조직소개
    • +
    • (isActive ? "cur" : "")}>홍보자료
    • +
    • (isActive ? "cur" : "")}>주요업무
    • (isActive ? "cur" : "")}>찾아오시는 길
    diff --git a/egovframe-template-simple-react-contribution/src/components/leftmenu/EgovLeftNavAdmin.jsx b/egovframe-template-simple-react-contribution/src/components/leftmenu/EgovLeftNavAdmin.jsx index 8b394bb..c9da0e3 100644 --- a/egovframe-template-simple-react-contribution/src/components/leftmenu/EgovLeftNavAdmin.jsx +++ b/egovframe-template-simple-react-contribution/src/components/leftmenu/EgovLeftNavAdmin.jsx @@ -18,19 +18,19 @@ function EgovLeftNavAdmin(props) { let activeKey; if (activeFolder === "config") { - activeKey = "0"; + activeKey = 0; } else if (activeFolder === "users") { - activeKey = "1"; + activeKey = 1; } else if (activeFolder === "boards") { - activeKey = "2"; + activeKey = 2; } else if (activeFolder === "standards") { - activeKey = "3"; + activeKey = 3; } else if (activeFolder === "contents") { - activeKey = "4"; + activeKey = 4; } else if (activeFolder === "committee") { - activeKey = "5"; + activeKey = 5; } else if (activeFolder === "logs") { - activeKey = "6"; + activeKey = 6; } // else { // activeKey = "7"; @@ -55,7 +55,7 @@ function EgovLeftNavAdmin(props) { {/*
*/} {/* */} {/**/} - + 환경설정
    @@ -69,7 +69,7 @@ function EgovLeftNavAdmin(props) { - + 사용자 관리
      @@ -78,7 +78,7 @@ function EgovLeftNavAdmin(props) { - + 게시판현황
        @@ -89,19 +89,19 @@ function EgovLeftNavAdmin(props) { - + 건설기준관리
          {/*
        • (isActive ? "cur" : "")}>참조코드 관리
        • */} -
        • (isActive ? "cur" : "")}>API KEY 관리
        • +
        • (isActive ? "cur" : "")}>API KEY 관리
        • (isActive ? "cur" : "")}>유사성 검사
        • (isActive ? "cur" : "")}>건설기준 내용 관리
        - + 컨텐츠관리
          @@ -113,7 +113,7 @@ function EgovLeftNavAdmin(props) { - + 위원회관리
            @@ -123,7 +123,7 @@ function EgovLeftNavAdmin(props) { - + 로그현황
              diff --git a/egovframe-template-simple-react-contribution/src/constants/url.js b/egovframe-template-simple-react-contribution/src/constants/url.js index 22f6ce3..543e22f 100644 --- a/egovframe-template-simple-react-contribution/src/constants/url.js +++ b/egovframe-template-simple-react-contribution/src/constants/url.js @@ -5,46 +5,82 @@ const URL = { LOGIN : "/login", //로그인 JOIN : "/join", //회원가입 + MY : "/myPage", //나의페이지 ERROR : "/error", //에러 - + PRIVATE : "/private", //개인정보처리방침 + EMAIL : "/email", //이메일 무단 수집 거부 + CHANGE_PW : "/PwChange", // 비밀번호 변경 + //ABOUT ABOUT : "/about", //사이트소개 ABOUT_SITE : "/about/site", // 사이트소개/소개 ABOUT_HISTORY : "/about/history", // 사이트소개/연혁 + ABOUT_PROMOTE : "/about/promote", // 사이트소개/홍보자료 ABOUT_ORGANIZATION : "/about/organization", // 사이트소개/조직소개 ABOUT_LOCATION : "/about/location", // 사이트소개/찾아오시는길 + ABOUT_SITEMAP : "/about/sitemap", // 사이트소개/사이트맵 //INTRO - INTRO : "/intro", //정보마당 - INTRO_WORKS : "/intro/works", // 정보마당/주요사업소개 - INTRO_SERVICE : "/intro/service", // 정보마당/주요서비스소개 - + // INTRO : "/intro", //정보마당 + // INTRO_WORKS : "/intro/works", // 정보마당/주요사업소개 + // INTRO_SERVICE : "/intro/service", // 정보마당/주요서비스소개 + + //COMMITTEE + COMMITTEE : "/committee", //위원회 + COMMITTEE_PROGRESS : "/committee/progress", // 위원회/진행현황 + COMMITTEE_SCHEDULE : "/committee/schedule", // 위원회/위원회일정 + //SUPPORT SUPPORT : "/support", // 고객지원 + SUPPORT_QNA : "/support/qna", // 게시판/QNA 소개 + SUPPORT_LIST : "/support/list/:BbsCode", // 게시판/리스트 + SUPPORT_DETAIL : "/support/detail/:BbsCode", // 게시판/상세보기 + SUPPORT_CREATE : "/support/create/:BbsCode", // 게시판/글쓰기 + SUPPORT_LIST_NOCODE : "/support/list", + SUPPORT_DETAIL_NOCODE : "/support/detail", // 게시판/상세보기 + SUPPORT_CREATE_NOCODE : "/support/create", // 게시판/글쓰기 + SUPPORT_SITE : "/support/site", // 관련사이트 + SUPPORT_API : "/support/api", // API 서비스 + SUPPORT_RESEARCH : "/support/research", // 건설기준 연구 + SUPPORT_POLL : "/support/poll", // 설문조사 SUPPORT_DOWNLOAD : "/support/download", // 고객지원/자료실 - SUPPORT_DOWNLOAD_DETAIL : "/support/download/detail", // 고객지원/자료실/상세 - SUPPORT_DOWNLOAD_CREATE : "/support/download/create", // 고객지원/자료실/등록 - SUPPORT_QNA : "/support/qna", // 고객지원/묻고답하기 - SUPPORT_QNA_DETAIL : "/support/qna/detail", // 고객지원/묻고답하기/상세 - SUPPORT_APPLY : "/support/apply", // 고객지원/서비스신청 + // SUPPORT_DOWNLOAD_DETAIL : "/support/download/detail", // 고객지원/자료실/상세 + // SUPPORT_DOWNLOAD_CREATE : "/support/download/create", // 고객지원/자료실/등록 + // SUPPORT_QNA : "/support/qna", // 고객지원/묻고답하기 + // SUPPORT_QNA_DETAIL : "/support/qna/detail", // 고객지원/묻고답하기/상세 + // SUPPORT_APPLY : "/support/apply", // 고객지원/서비스신청 + + //기준코드 + STANDARD_CODE_INFO : "/standardCode/info", //건설기준코드/건설기준코드 안내 + STANDARD_CODE_TERM : "/standardCode/term", //건설기준코드/건설기준코드 용어 + STANDARD_CODE_ENG : "/standardCode/eng", //건설기준코드/영문 건설기준코드 + STANDARD_CODE_OLD : "/standardCode/old", //건설기준코드/(구)건설기준코드 + STANDARD_CODE_LIST : "/standardCode/list", //건설기준코드/리스트 + STANDARD_CODE_LIST_LINK : "/standardCode/list/:listCode", //건설기준코드/리스트 + STANDARD_CODE_DETAIL : "/standardCode/detail", //건설기준코드/리스트 + STANDARD_CODE_VIEWER : "/standardCode/viewer", //건설기준코드/뷰어 + STANDARD_CODE_VIEWER_LINK : "/standardCode/viewer/:linkedDocCode", //건설기준코드/뷰어/새 창 링크 //INFORM - INFORM : "/inform", // 알림마당 - INFORM_DAILY : "/inform/daily", // 알림마당/오늘의행사 - INFORM_DAILY_DETAIL : "/inform/daily/detail", // 알림마당/오늘의행사상세 - INFORM_WEEKLY : "/inform/weekly", // 알림마당/금주의행사 - INFORM_WEEKLY_DETAIL : "/inform/weekly/detail", // 알림마당/금주의행사상세 - INFORM_NOTICE : "/inform/notice", // 알림마당/공지사항 - INFORM_NOTICE_DETAIL : "/inform/notice/detail", // 알림마당/공지사항상세 - INFORM_NOTICE_CREATE : "/inform/notice/create", // 알림마당/공지사항등록 - INFORM_NOTICE_MODIFY : "/inform/notice/modify", // 알림마당/공지사항수정 - INFORM_NOTICE_REPLY : "/inform/notice/reply", // 알림마당/공지사항답글 - INFORM_GALLERY : "/inform/gallery", // 알림마당/사이트갤러리 - INFORM_GALLERY_DETAIL : "/inform/gallery/detail", // 알림마당/사이트갤러리상세 - INFORM_GALLERY_CREATE : "/inform/gallery/create", // 알림마당/사이트갤러리등록 - INFORM_GALLERY_MODIFY : "/inform/gallery/modify", // 알림마당/사이트갤러리수정 - INFORM_GALLERY_REPLY : "/inform/gallery/reply", // 알림마당/사이트갤러리답글 - + // INFORM : "/inform", // 알림마당 + // INFORM_DAILY : "/inform/daily", // 알림마당/오늘의행사 + // INFORM_DAILY_DETAIL : "/inform/daily/detail", // 알림마당/오늘의행사상세 + // INFORM_WEEKLY : "/inform/weekly", // 알림마당/금주의행사 + // INFORM_WEEKLY_DETAIL : "/inform/weekly/detail", // 알림마당/금주의행사상세 + // INFORM_NOTICE : "/inform/notice", // 알림마당/공지사항 + // INFORM_NOTICE_DETAIL : "/inform/notice/detail", // 알림마당/공지사항상세 + // INFORM_NOTICE_CREATE : "/inform/notice/create", // 알림마당/공지사항등록 + // INFORM_NOTICE_MODIFY : "/inform/notice/modify", // 알림마당/공지사항수정 + // INFORM_NOTICE_REPLY : "/inform/notice/reply", // 알림마당/공지사항답글 + // INFORM_GALLERY : "/inform/gallery", // 알림마당/사이트갤러리 + // INFORM_GALLERY_DETAIL : "/inform/gallery/detail", // 알림마당/사이트갤러리상세 + // INFORM_GALLERY_CREATE : "/inform/gallery/create", // 알림마당/사이트갤러리등록 + // INFORM_GALLERY_MODIFY : "/inform/gallery/modify", // 알림마당/사이트갤러리수정 + // INFORM_GALLERY_REPLY : "/inform/gallery/reply", // 알림마당/사이트갤러리답글 + + + + //ADMIN ADMIN : "/admin", // 사이트관리 ADMIN_SCHEDULE : "/admin/schedule", // 사이트관리/일정관리 @@ -84,16 +120,15 @@ const URL = { ADMIN_ABOUT_SITE : "/admin/config/about-site-mgt", // 사이트관리/환경설정/관련사이트 관리 // 관리자 - 사용자 현황 - ADMIN__USERS__LIST : "/admin/users/list", // 사용자 현황 + ADMIN__USERS__LIST : "/admin/users/mgt", // 사용자 현황 // 관리자 - 게시판 현황 - ADMIN__BOARDS__LIST : "/admin/boards/list", // 게시판 현황/게시판 관리 + ADMIN__BOARDS__LIST : "/admin/boards/mgt", // 게시판 현황/게시판 관리 ADMIN__BOARDS__POSTS : "/admin/boards/posts", // 게시판 현황/게시물 관리 - ADMIN__BOARDS__KEYWORDS : "/admin/boards/keywords", // 게시판 현황/키워드 관리 // 관리자 - 건설기준 관리 ADMIN__STANDARDS__REFERENCE_CODES : "/admin/standards/reference-codes", // 건설기준 관리/참조코드 조회 - ADMIN__STANDARDS__API_KYES : "/admin/standards/api-kyes", // 건설기준 관리/API KEY 관리 + ADMIN__STANDARDS__API_KEYS : "/admin/standards/api-keys", // 건설기준 관리/API KEY 관리 ADMIN__STANDARDS__SIMILARITY_CHECK : "/admin/standards/standards/similarity-check", // 건설기준 관리/유사성 검사 ADMIN__STANDARDS__INFO_DISCLOSURE : "/admin/standards/info-disclosure", // 건설기준 관리/정보공개 관리 @@ -123,13 +158,6 @@ const URL = { ADMIN__LOGS__PRIVACY_LOGS : "/admin/logs/privacy-logs", // 위원회 관리/개인정보 로그 ADMIN__LOGS__FILE_DOWNLOAD_STATUS : "/admin/logs/file-download-status", // 위원회 관리/파일 다운현황 - //기준코드 - STANDARD_CODE_INFO : "/standardCode/info", - STANDARD_CODE_LIST : "/standardCode/list", //건설기준코드/리스트 - STANDARD_CODE_LIST_LINK : "/standardCode/list/:listCode", //건설기준코드/리스트 - STANDARD_CODE_DETAIL : "/standardCode/detail", //건설기준코드/리스트 - STANDARD_CODE_VIEWER : "/standardCode/viewer", //건설기준코드/뷰어 - STANDARD_CODE_VIEWER_LINK : "/standardCode/viewer/:linkedDocCode", //건설기준코드/뷰어/새 창 링크 diff --git a/egovframe-template-simple-react-contribution/src/css/base.css b/egovframe-template-simple-react-contribution/src/css/base.css index 761408a..03ab88f 100644 --- a/egovframe-template-simple-react-contribution/src/css/base.css +++ b/egovframe-template-simple-react-contribution/src/css/base.css @@ -1,32 +1,39 @@ @charset "utf-8"; /* Web Font */ -@font-face {font-family: 'Noto Sans KR';font-style: normal;font-weight: 300; - src: url(https://fonts.gstatic.com/ea/notosanskr/v2/NotoSansKR-Light.woff2) format('woff2'), - url(https://fonts.gstatic.com/ea/notosanskr/v2/NotoSansKR-Light.woff) format('woff'), - url(https://fonts.gstatic.com/ea/notosanskr/v2/NotoSansKR-Light.otf) format('opentype');} - -@font-face {font-family: 'Noto Sans KR';font-style: normal;font-weight: 400;src: - url(https://fonts.gstatic.com/ea/notosanskr/v2/NotoSansKR-Regular.woff2) format('woff2'), - url(https://fonts.gstatic.com/ea/notosanskr/v2/NotoSansKR-Regular.woff) format('woff'), - url(https://fonts.gstatic.com/ea/notosanskr/v2/NotoSansKR-Regular.otf) format('opentype');} - -@font-face {font-family: 'Noto Sans KR';font-style: normal;font-weight: 500; - src: url(https://fonts.gstatic.com/ea/notosanskr/v2/NotoSansKR-Medium.woff2) format('woff2'), - url(https://fonts.gstatic.com/ea/notosanskr/v2/NotoSansKR-Medium.woff) format('woff'), - url(https://fonts.gstatic.com/ea/notosanskr/v2/NotoSansKR-Medium.otf) format('opentype');} - -@font-face {font-family: 'Noto Sans KR';font-style: normal;font-weight: 700; - src: url(https://fonts.gstatic.com/ea/notosanskr/v2/NotoSansKR-Bold.woff2) format('woff2'), - url(https://fonts.gstatic.com/ea/notosanskr/v2/NotoSansKR-Bold.woff) format('woff'), - url(https://fonts.gstatic.com/ea/notosanskr/v2/NotoSansKR-Bold.otf) format('opentype');} +/*@font-face {font-family: 'Noto Sans KR';font-style: normal;font-weight: 300;*/ +/* src: url(https://fonts.gstatic.com/ea/notosanskr/v2/NotoSansKR-Light.woff2) format('woff2'),*/ +/* url(https://fonts.gstatic.com/ea/notosanskr/v2/NotoSansKR-Light.woff) format('woff'),*/ +/* url(https://fonts.gstatic.com/ea/notosanskr/v2/NotoSansKR-Light.otf) format('opentype');}*/ + +/*@font-face {font-family: 'Noto Sans KR';font-style: normal;font-weight: 400;src:*/ +/* url(https://fonts.gstatic.com/ea/notosanskr/v2/NotoSansKR-Regular.woff2) format('woff2'),*/ +/* url(https://fonts.gstatic.com/ea/notosanskr/v2/NotoSansKR-Regular.woff) format('woff'),*/ +/* url(https://fonts.gstatic.com/ea/notosanskr/v2/NotoSansKR-Regular.otf) format('opentype');}*/ + +/*@font-face {font-family: 'Noto Sans KR';font-style: normal;font-weight: 500;*/ +/* src: url(https://fonts.gstatic.com/ea/notosanskr/v2/NotoSansKR-Medium.woff2) format('woff2'),*/ +/* url(https://fonts.gstatic.com/ea/notosanskr/v2/NotoSansKR-Medium.woff) format('woff'),*/ +/* url(https://fonts.gstatic.com/ea/notosanskr/v2/NotoSansKR-Medium.otf) format('opentype');}*/ + +/*@font-face {font-family: 'Noto Sans KR';font-style: normal;font-weight: 700;*/ +/* src: url(https://fonts.gstatic.com/ea/notosanskr/v2/NotoSansKR-Bold.woff2) format('woff2'),*/ +/* url(https://fonts.gstatic.com/ea/notosanskr/v2/NotoSansKR-Bold.woff) format('woff'),*/ +/* url(https://fonts.gstatic.com/ea/notosanskr/v2/NotoSansKR-Bold.otf) format('opentype');}*/ + +@font-face { + font-family: 'Pretendard-Regular'; + src: url('font/Pretendard-Regular.otf'); + font-weight: normal; + font-style: normal; +} /* Reset style */ * {word-break: keep-all; word-wrap: break-word; box-sizing: border-box; -webkit-box-sizing: border-box;} html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, em, font, img, ins, q, s, small, strike, strong, sub, sup, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, thead, tbody, tfoot, tr, th, td, input { - margin: 0; padding: 0; + margin: 0; padding: 0; font-family: 'Pretendard-Regular'; } blockquote, button, fieldset, iframe {border: 0;} @@ -72,8 +79,22 @@ button {cursor: pointer;} .w_400 {width: 400px;} .w_500 {width: 500px;} +.mw_400 {max-width: 400px;} +.mw_450 {max-width: 450px;} + +.h_25 {height: 25px;} .h_30 {height: 30px;} +.h_50 {height: 50px;} .h_100 {height: 100px;} +.h-100 {height: 100%;} + +.f_11 {font-size: 11px;} +.f_12 {font-size: 12px;} +.f_13 {font-size: 13px;} +.f_14 {font-size: 14px;} +.f_15 {font-size: 15px;} +.f_16 {font-size: 16px;} +.f_17 {font-size: 17px;} /* 여백 */ @@ -83,5 +104,11 @@ button {cursor: pointer;} .ml10 {margin-left: 10px !important;} .pb10 {padding-bottom: 10px !important;} +.bg-fa {background: #FAFAFA !important;} -.clickable{cursor: pointer;} \ No newline at end of file +.text-4c6 {color: #4C6C84 !important;} +.text-224 {color: #22498E !important;} + +.clickable{cursor: pointer;} + +.MuiTab-root.Mui-selected { color: #22498E; } diff --git a/egovframe-template-simple-react-contribution/src/css/component.css b/egovframe-template-simple-react-contribution/src/css/component.css index 1dc342c..5301f5b 100644 --- a/egovframe-template-simple-react-contribution/src/css/component.css +++ b/egovframe-template-simple-react-contribution/src/css/component.css @@ -51,30 +51,35 @@ .board_list {border-top: 2px solid #222;} .board_list .head {display: table; table-layout: fixed; width: 100%;} /* changed by lim padding: 25px 0 27px 0; */ -.board_list .head > span {display: table-cell; padding: 10px 0 10px 0; border-bottom: 1px solid #888; font-size: 16px; font-weight: 500px; text-align: center;} +.board_list .head > span {display: table-cell; padding: 10px 0 10px 0; border-bottom: 1px solid #888; font-size: 16px; font-weight: 500; text-align: center;} .logs_list .result {max-height: 430px;} /* added by lim .logs_list .result {max-height: 430px;} */ .board_list .result .list_item {display: table; width: 100%; table-layout: fixed;} /* changed by lim padding: 18px 0 20px 0; */ .board_list .result .list_item > div {display: table-cell; padding: 7px 0 7px 0; border-bottom: 1px solid #dde2e5; color: #666; font-size: 14px; text-align: center; vertical-align: middle;} -.board_list .result .list_item > div.al {padding: 18px 30px 20px 30px; text-align: left;} +.board_list .result .list_item > .left_align {text-align: left;} +.board_list .result .list_item > div.al {padding: 10px 20px 12px 20px; text-align: left;} .board_list .result .list_item > div.reply {position: relative; padding: 18px 30px 20px 52px;} .board_list .result .list_item > div.reply::before {content: ""; display: block; position: absolute; left: 27px; top: 24px; width: 22px; height: 14px; background: url(css/images/ico_reply.png) no-repeat;} .board_list .no_data {height: 60px; border-bottom: 1px solid #dde2e5; color: #666; font-size: 16px; line-height: 60px; text-align: center;} +/* 영문건설기준 리스트 */ +.board_list .result .list_item1 {display: table; width: 100%; table-layout: fixed; margin-left: 0px;} +.board_list .result .list_item1 > div {display: table-cell; padding: 5px 0; border-bottom: 1px solid #dde2e5; color: #666; font-size: 14px; text-align: center; vertical-align: middle; } + .board_bot {margin-top: 40px;} .paging {text-align: center;} .paging .btn {margin-top: 0; padding: 5px;} /* added by lim padding: 5px; */ .paging .btn + .btn {margin-left: 5px;} -.paging .btn button {display: inline-block; width: 32px; height: 32px; border: 1px solid #dde2e5; border-radius: 5px; font-size: 0;} /* changed by lim width: 42px; height: 42px; */ -.paging .first {background: url(css/images/ico_prev.png) no-repeat center; vertical-align: top; } -.paging .prev {margin-right: 6px; background: url(css/images/ico_arrow_r_gray_9x15.png) no-repeat center; vertical-align: top; transform: rotate(180deg);} /* changed by lim margin-right: 26px; */ -.paging .next {margin-left: 6px; background: url(css/images/ico_arrow_r_gray_9x15.png) no-repeat center; vertical-align: top;} /* changed by lim margin-left: 26px; */ -.paging .last {background: url(css/images/ico_prev.png) no-repeat center; vertical-align: top; transform: rotate(180deg);} +.paging .btn button {display: inline-block; width: 32px; height: 32px; border: 1px solid #dde2e5; border-radius: 25px; font-size: 0;} /* changed by lim width: 42px; height: 42px; */ +.paging .first {background: url(css/images/ico_prev.png) no-repeat center; background-size: 30%; vertical-align: top; } +.paging .prev {margin-right: 6px; background: url(css/images/ico_arrow_r_gray_9x15.png) no-repeat center; background-size: 20%; vertical-align: top; transform: rotate(180deg);} /* changed by lim margin-right: 26px; */ +.paging .next {margin-left: 6px; background: url(css/images/ico_arrow_r_gray_9x15.png) no-repeat center; background-size: 20%; vertical-align: top;} /* changed by lim margin-left: 26px; */ +.paging .last {background: url(css/images/ico_prev.png) no-repeat center; background-size: 30%; vertical-align: top; transform: rotate(180deg);} .paging ul {display: inline-block; vertical-align: top;} .paging ul li {display: inline-block; margin-top: 4px; vertical-align: top;} .paging ul li button {display: block; width: 34px; height: 34px; color: #888; font-size: 16px; line-height: 34px; text-align: center; background: white;} -.paging ul li button.cur {border-radius: 50%; color: #fff; background: #222;} +.paging ul li button.cur {border-radius: 50%; color: #fff; background: #004994;} .board_view {border-top: 2px solid #222;} .board_view_top {border-bottom: 1px solid #dde2e5;} @@ -107,13 +112,13 @@ .board_btn_area {position: relative; min-height: 46px;} .board_btn_area .left_col {font-size: 0;} .board_btn_area .left_col .btn + .btn {margin-left: 10px;} -.board_btn_area .right_col {position: absolute; right: 0; top: 0; font-size: 0;} +/*.board_btn_area .right_col {position: absolute; right: 0; top: 0; font-size: 0;}*/ .board_btn_area .right_col .btn + .btn {margin-left: 10px;} .board_view2 {border-top: 2px solid #222;} .board_view2 dl {display: table; width: 100%; table-layout: fixed; border-bottom: 1px solid #dde2e5;} .board_view2 dl > * {display: table-cell; table-layout: fixed; vertical-align: middle;} -.board_view2 dl dt {width: 176px; padding: 12px 25px; color: #000; font-size: 15px; letter-spacing: -2px; background: #f5f6f7; word-break: break-all;} /* changed by lim font-size: 18px;*/ +.board_view2 dl dt {width: 176px; padding: 12px 25px; color: #000; font-size: 15px; letter-spacing: -2px; background: #FAFAFA; word-break: break-all; border-right: 1px solid #B4B3B3;} /* changed by lim font-size: 18px;*/ .board_view2 dl dt .req {display: inline-block; width: 7px; height: 7px; margin-left: 2px; font-size: 0; background: url(css/images/ico_req.png) no-repeat; vertical-align: 17px;} .board_view2 dl dd {padding: 12px 15px; color: #222; font-size: 16px; font-weight: 300;} .board_view2 .file_add {margin-top: 5px;} @@ -154,20 +159,20 @@ .qna_a {position: relative; padding: 8px 30px 3px 75px; border-bottom: 1px solid #dde2e5; color: #666; font-size: 16px; font-weight: 300; line-height: 30px;} .qna_a > span {display: block; position: absolute; left: 30px; top: 30px; width: 32px; height: 32px; border-radius: 50%; color: #fff; font-size: 20px; line-height: 32px; text-align: center; background: #fc8175;} -.qna_a ul li {position: relative; padding: 21px 0 30px 0; border-bottom: 1px dashed #dde2e5;} +.qna_a ul li {position: relative; padding: 10px 0 15px 0; border-bottom: 1px dashed #dde2e5;} .qna_a ul li:last-child {border-bottom: 0;} .qna_a ul li span {display: block;} .qna_a ul li .delete {position: absolute; right: 20px; bottom: 11px; color: #222; font-size: 16px; font-weight: 300;} .qna_a ul li .delete::before {content: ""; display: inline-block; width: 18px; height: 18px; margin-right: 5px; background: url(css/images/ico_delete.png) no-repeat; background-size: contain; vertical-align: -2px;} -.replay {display: table; table-layout: fixed; width: 100%; padding: 18px 0; border: 2px solid #dde2e5; border-radius: 10px;} +.replay {padding: 18px 0; border: 2px solid #dde2e5; border-radius: 10px;} .replay > * {display: table-cell; vertical-align: top;} -.replay .left_col {width: 850px; font-size: 0;} -.replay .left_col label {display: inline-block; width: 108px; height: 80px; padding-left: 28px; color: #000; font-size: 16px; line-height: 80px; vertical-align: top;} -.replay .left_col div {display: inline-block; width: 740px; vertical-align: top;} -.replay .left_col div textarea {height: 80px;} -.replay .right_col {padding: 0 18px;} -.replay .right_col .btn {width: 100%; height: 80px; border-radius: 5px; color: #005b82; font-size: 16px; text-align: center; line-height: 80px; background: #daedf5;} +/*.replay .left_col {width: 850px; font-size: 0;}*/ +/*.replay .left_col label {display: inline-block; width: 108px; height: 80px; padding-left: 28px; color: #000; font-size: 16px; line-height: 80px; vertical-align: top;}*/ +/*.replay .left_col div {display: inline-block; width: 740px; vertical-align: top;}*/ +/*.replay .left_col div textarea {height: 80px;}*/ +/*.replay .right_col {padding: 0 18px;}*/ +/*.replay .right_col .btn {width: 100%; height: 80px; border-radius: 5px; color: #005b82; font-size: 16px; text-align: center; line-height: 80px; background: #daedf5;}*/ .bottom_navi {border-top: 1px solid #dde2e5;} @@ -198,7 +203,11 @@ .condition > ul li .prev + span {display: inline-block; height: 32px; margin: 0 10px; padding: 0 30px; border-radius: 5px; font-size: 16px; line-height: 32px; background: #f7f7f7; vertical-align: top;} .condition .lb {display: inline-block; height: 32px; margin-right: 20px; color: #222; font-size: 16px; font-weight: 300; line-height: 32px; vertical-align: top;} /* changed by lim height: 46px;*/ +.condition1 {padding: 10px; border: 1px solid #dde2e5; border-radius: 10px; text-align: right; background: #FAFAFA; margin-bottom: 20px;} +.condition1 > ul, +.condition1 > ul li {display: inline-block; vertical-align: top; padding-left: 20px;} +.condition2 {padding: 20px; border: 1px solid #000; background: #FFF; margin-bottom: 20px; line-height: 25px; box-shadow: 3px 4px 5px #ccc;} /* Icon */ .ico {display: inline-block; font-size: 0; vertical-align: top;} @@ -275,7 +284,7 @@ select::-ms-expand {display:none;} .tit_2 {font-size: 30px; font-weight: 700;} -.tit_3 {color: #222; font-size: 48px; font-weight: 500; line-height: 44px; letter-spacing: -2px;} +.tit_3 {color: #004994; font-size: 30px; font-weight: 700; line-height: 80px; letter-spacing: -2px;} .tit_4 {position: relative; padding-top: 12px; font-size: 30px; font-weight: 700;} .tit_4::before {content: ""; display: block; position: absolute; left: 0; top: 0; width: 30px; height: 2px; background: #0465be;} @@ -332,4 +341,79 @@ select::-ms-expand {display:none;} .recharts-legend-item-text { font-size: 11px; +} + +.uploadIcon { + width: 100px; + height: 100px; + pointer-events: none; +} + +.file { + display: none; +} + +.file::file-selector-button { + font-size: 14px; + background: #fff; + border: 1px solid #111; + border-radius: 12px; + padding: 4px 32px; + cursor: pointer; +} + +.preview { + width: 400px; + height: 350px; + margin: auto; + background-color: #fff; + border-radius: 5px; + border: 3px dashed #eee; + padding: 70px; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + cursor: pointer; +} + +.preview_image { + max-width: 100%; + max-height: 100%; + object-fit: contain; +} + +.preview:hover { + border-color: #111; +} + +.preview_msg { + font-weight: 500; + font-size: 18px; + margin: 20px 0 10px; +} + +.preview_desc { + margin: 0; + font-size: 14px; +} + +.preview_info { + width: 100%; + list-style: none; + padding: 0; + gap: 16px; + display: flex; + flex-direction: column; +} + +.preview_info .info_key { + display: block; + font-weight: 500; + font-size: 12px; + margin-bottom: 4px; +} + +.preview_info .info_value { + font-size: 14px; } \ No newline at end of file diff --git a/egovframe-template-simple-react-contribution/src/css/images/ico_user.png b/egovframe-template-simple-react-contribution/src/css/images/ico_user.png new file mode 100644 index 0000000..0bec35d Binary files /dev/null and b/egovframe-template-simple-react-contribution/src/css/images/ico_user.png differ diff --git a/egovframe-template-simple-react-contribution/src/css/layout.css b/egovframe-template-simple-react-contribution/src/css/layout.css index e669895..6f1157b 100644 --- a/egovframe-template-simple-react-contribution/src/css/layout.css +++ b/egovframe-template-simple-react-contribution/src/css/layout.css @@ -2,71 +2,111 @@ body {min-width: 1400px;} -.header {position: relative;} -.header::after {content: ""; display: block; position: absolute; left: 0; bottom: 0; width: 100%; height: 1px; background: #dedede;} -.header > .inner {position: relative; width: 1400px; height: 150px; margin: 0 auto; padding: 0 50px;} +/*.header {position: relative;}*/ +.header::after {content: ""; display: block; left: 0; bottom: 0; width: 100%; height: 1px; background: #dedede;} +.header > .inner {max-width: 1400px; height: 210px; margin: 0 auto; } /* position: relative; padding: 0 50px; */ .header h1 {display: inline-block; margin-top: 32px;} .header h1 a, .header h1 img {display: block;} .header .logo .m {display: none;} .header .logo .logotop {display: flex; width: 220px; justify-content: flex-end;} .header .user_info {position: absolute; right: 50px; top: 10px; line-height: 30px;} -.header .user_info .person {display: inline-block; color: #169bd5; font-weight: 500;} -.header .user_info .person::before {content: ""; display: inline-block; width: 22px; height: 22px; margin-right: 7px; background: url(css/images/ico_person.png) no-repeat; background-size: contain; vertical-align: -4px;} +.header .person {width: 30px; height: 30px; margin-right:20px; cursor: pointer;} +.header .person::before {content: ""; display: inline-block; width: 30px; height: 30px; background: url(css/images/ico_user.png) no-repeat center bottom; background-size: 30px 30px; } .header .user_info .btn {margin-left: 14px; padding: 0 20px; border-radius: 15px; color: #fff; font-size: 14px; line-height: 30px; background: #169bd5;} -.header .gnb {position: absolute; left: 430px; top: 50px; width: 920px;} -.header .gnb ul {font-size: 0; text-align: center;} -.header .gnb ul::after {content: ""; display: block; clear: both;} -.header .gnb ul li {float: left;} -.header .gnb ul li + li {margin-left: 98px;} -.header .gnb ul li a {color: #666; font-size: 20px; font-weight: 700; letter-spacing: -0.25px;} -.header .gnb ul li a.cur {color: #222;} +/*.header .gnb {position: absolute; left: 430px; top: 50px; width: 920px;}*/ +/*.header .gnb ul {font-size: 0; text-align: center;}*/ +/*.header .gnb ul::after {content: ""; display: block; clear: both;}*/ +/*.header .gnb ul li {float: left;}*/ +/*.header .gnb ul li + li {margin-left: 98px;}*/ +/*.header .gnb ul li a {color: #666; font-size: 20px; font-weight: 700; letter-spacing: -0.25px;}*/ +/*.header .gnb ul li a.cur {color: #222;}*/ -.header .right_a {position: absolute; right: 50px; top: 65px;} -.header .right_a .btn {width: 30px; height: 30px; font-size: 0; background: url(css/images/ico_allmenu.png) no-repeat right; background-size: 22px 18px;} -.header .right_a .btn.active {background: url(css/images/ico_allmenu_close.png) no-repeat right; background-size: 22px 18px;} +/*.header .right_a {position: absolute; right: 50px; top: 65px;}*/ +.header .right_a .btn {width: 30px; height: 30px; font-size: 0; background: url(css/images/ico_allmenu.png) no-repeat center; background-size: 22px 18px;} +.header .right_a .btn.active {background: url(css/images/ico_allmenu_close.png) no-repeat center; background-size: 22px 18px;} .header .right_a .btn.mobile {display: none;} -.header .topsearch {width: 25px; height: 27px; background: url(css/images/ico_search_b.png) no-repeat; margin: 5px;} +.header .search {height:96px; padding:24px 0px 10px; margin: 0 auto; } +.header .search .search_input {max-width: 734px; width: calc(100% - 40px); height:62px; margin: 0 auto; border: 2px solid #004994; border-radius: 20px; padding: 10px} +.header .search .search_input select {border: none;} +.header .search .search_input input {ime-mode:active; border: none;} +.header .search .topsearch {width: 40px; height: 40px; background: url(css/images/ico_search_b.png) no-repeat center center; background-size: 22px 22px; filter: brightness(1) sepia(1) saturate(3) hue-rotate(175deg);} -/* All menu */ -.all_menu {transition: transform .2s ease-in-out, opacity .2s ease-in-out; transform-origin: top; z-index: 10;} +.header .topcode {position: relative; width: 100%; top: -8px;} +.header .topcode .topcode_c {max-width: 1020px; margin:0 auto; border: 1px solid #ccc; z-index: 100; border-radius: 10px; box-shadow: 1px 1px 5px rgba(0, 0, 0, 0.2); background-color: #fff; padding: 0 20px; } +.header .topcode .topcode_n {max-width: 1020px; margin:0 auto; border: 1px solid #fff; z-index: 100; background-color: #fff; padding: 0 20px; } +.header .topcode .row {flex-wrap: wrap; padding: 8px 0; } +.header .topcode .topcodebnt { + min-width: 45px; + height: 40px; + line-height: 40px; + display: block; + background-color: #fff; + text-align: center; + border-radius: 20px; + color: #909090; + text-decoration: none; + /*margin: 5px;*/ + padding: 0 12px 0 12px; + box-shadow: 3px 3px 5px rgba(0, 0, 0, 0.2); +} + +.header .topcode .topcodebnt:hover{ + background-color: #8F8F8F; + color: #fff; + box-shadow: 3px 3px 5px rgba(0, 0, 0, 0.4); +} + + /* All menu */ +.all_menu {transition: transform .2s ease-in-out, opacity .2s ease-in-out; transform-origin: top; z-index: 10; padding: 50px 20px;} .all_menu.Mobile {display: none;} .all_menu.WEB.closed {transform: scaleY(0); opacity: 0;} -.all_menu.WEB {position: absolute; left: 0; top: 150px; width: 100%; background: #fff;} -.all_menu.WEB::after {content: ""; display: block; position: absolute; left: 0; bottom: 0; width: 100%; height: 1px; background: #ddd;} -.all_menu.WEB .inner {width: 1400px; margin: 0 auto; padding: 41px 50px 47px 50px;} -.all_menu.WEB .inner::after {content: ""; display: block; clear: both;} -.all_menu.WEB .inner .col {float: left; width: 280px;} -.all_menu.WEB .inner .col:last-child {width: auto;} -.all_menu.WEB .inner .col h3 {color: #222; font-size: 24px; font-weight: 700; pointer-events: none;} -.all_menu.WEB .inner .col ul {padding-top: 36px;} -.all_menu.WEB .inner .col ul li + li {margin-top: 17px;} -.all_menu.WEB .inner .col ul li a {color: #777; font-size: 18px;} -.all_menu.WEB .inner .col ul li a:hover {color: #222; text-decoration: underline;} +.all_menu.WEB {position: absolute; right: calc((100% - 1400px) / 2); top: 70px; width: 340px; background: #fff; border-radius: 20px; box-shadow: 0px 2px 5px rgba(0, 0, 0, 0.2); z-index: 200;} +/*.all_menu.WEB::after {content: ""; display: block; position: absolute; left: 0; bottom: 0; width: 100%; height: 1px; background: #ddd;}*/ +/*.all_menu.WEB .inner {width: 1400px; margin: 0 auto; } !* padding: 41px 50px 47px 50px; *!*/ +/*.all_menu.WEB .inner::after {content: ""; display: block; clear: both;}*/ +/*.all_menu.WEB .inner .col {float: left; width: 280px;}*/ +/*.all_menu.WEB .inner .col:last-child {width: auto;}*/ +.all_menu.WEB .inner h3 {color: #222; font-size: 20px; font-weight: 700; pointer-events: none;} +.all_menu.WEB .inner ul {display: flex; flex-wrap: wrap; padding: 16px 0 16px;} +.all_menu.WEB .inner ul li {padding: 0 15px 0 0;} +.all_menu.WEB .inner ul li a {color: #777; font-size: 12px;} +.all_menu.WEB .inner ul li a:hover {color: #333; border-bottom: 1px solid transparent; transition: border-color 0.3s; border-color: #36588B; } +/*.inner img {height: 35px !important;}*/ .user_info_m {display: none;} -.container {min-height: calc(100vh - 300px);} -.c_wrap { margin: 0 auto;} /* removed by lim width: 1400px; padding: 0 50px; */ +.container {min-width: 1400px; min-height: calc(100vh - 400px); padding: 0; } +.c_wrap { margin: auto 0; } /* removed by lim width: 1400px; padding: 0 50px; */ .c_wrap .layout {display: table; width: 100%; table-layout: fixed; padding-bottom: 20px;} /* added by lim padding-bottom: 20px; */ /* sub navigation */ .c_wrap .layout .nav:not(.tabs) {display: table-cell; width: 220px; vertical-align: top;} /* changed by lim width: 260px; */ -.c_wrap .layout .nav .inner {border: 1px solid #dde2e5; border-radius: 10px;} -.nav_title{padding: 35px 30px 26px 30px;} /* changed by lim border-bottom: 4px solid #dde2e5; */ -.c_wrap .layout .nav h2 {color: #222; font-size: 24px;} -.c_wrap .layout .nav ul {padding: 0 10px} /* changed by lim padding: 26px 30px 27px 30px;*/ -.c_wrap .layout .nav ul li + li {margin-top: 18px;} /* changed by lim margin-top: 27px; */ +/*.c_wrap .layout .nav .inner {border: 1px solid #dde2e5; border-radius: 10px;}*/ +.nav_title{padding: 35px 30px 26px 20px;} /* changed by lim border-bottom: 4px solid #dde2e5; */ +.c_wrap .layout .nav h2 {color: #222; font-size: 24px; font-weight: 700;} +.c_wrap .layout .nav button {font-size: 14px; font-weight: 600;} +.c_wrap .layout .nav ul {padding: 0 10px; } /* changed by lim padding: 26px 30px 27px 30px;*/ +.c_wrap .layout .nav ul li + li {margin-top: 18px; } /* changed by lim margin-top: 27px; */ .c_wrap .layout .nav ul li a {display: block; position: relative; color: #666; font-size: 14px;} /* changed by lim font-size: 18px; */ .c_wrap .layout .nav ul li a:hover::after {content: ""; display: block; position: absolute; right: 0px; top: 50%; transform: translateY(-50%); width: 9px; height: 15px; background: url(css/images/ico_arrow_r_gray_9x15.png) no-repeat;} .c_wrap .layout .nav ul li a.cur {color: #222; font-weight: 700;} -.c_wrap .layout .contents {display: table-cell; width: auto; padding: 0 0 50px 30px; vertical-align: top;} /* changed by lim padding: 0 0 120px 70px; */ +.c_wrap .layout .contents {display: table-cell; width: auto; vertical-align: top; padding-left: 30px;} /* changed by lim padding: 0 0 120px 70px; */ - -/* location */ +/* 센터소개 */ +.c_wrap .layout .nav1:not(.tabs) {display: table-cell; width: 220px; vertical-align: top;} +.c_wrap .layout .nav1 h2 {color: #222; font-size: 24px; font-weight: 700;} +.c_wrap .layout .nav1 .menu10 {mnargin: 0; border: 1px solid #dde2e5;} +/*.c_wrap .layout .nav1 li {margin: 10px;}*/ +.c_wrap .layout .nav1 .menu10 li + li {border-top: 1px solid #dde2e5; } +.c_wrap .layout .nav1 ul li a {display: block; position: relative; color: #666; font-size: 14px; padding: 10px;} /* changed by lim font-size: 18px; */ +/*.c_wrap .layout .nav1 ul li a:hover {}*/ +.c_wrap .layout .nav1 ul li a:hover::after {content: ""; display: block; position: absolute; right: 10px; top: 50%; transform: translateY(-50%); width: 9px; height: 15px; background: url(css/images/ico_arrow_r_gray_9x15.png) no-repeat; } +.c_wrap .layout .nav1 ul li a.cur {color: #fff; font-weight: 700; background-color: #004994; } + /* location */ .location {height: 30px; padding-top: 23px; text-align: right;} /* chagned by lim height: 70px; padding-top: 43px; */ .location ul, .location ul li {display: inline-block; vertical-align: top;} .location ul li {position: relative; color: #666; font-size: 14px;} @@ -79,22 +119,27 @@ body {min-width: 1400px;} .footer {position: relative; background-color: #2c394b; } -.footer .upper {width: 100%; background-color: #384556; font-size: 12px;} -.footer .upper .up {width: 1400px; margin: 0 auto; padding: 10px 50px; } -.footer .upper .up .left {text-align: right; color: #B4B5B7; font-weight: 700;} -.footer .upper .up .right {color: #96A1AE; } -.footer::before {content: ""; display: block; position: absolute; left: 0; top: 0; width: 100%; height: 1px; background: #ccc;} -.footer .inner {position: relative; width: 1400px; margin: 0 auto; padding: 0 50px;} +.footer .upper {width: 100%; background-color: #384556; font-size: 12px; border-bottom: 1px solid #56626F;} +.footer .upper .up {width: 1400px; margin: 0 auto; padding: 20px 0; } +.footer .upper .up .left {width: 100px; color: #D9DADB; font-weight: 700; line-height: 30px;} +.footer .upper .up .right {color: #96A1AE; line-height: 30px;} +.footer .upper .up .right a {color: #96A1AE; margin-right: 15px;} +.footer .upper .open {width: 100px; text-align: right; } +.footer .upper button {color: #fff; border: 1px solid #A2A2A2; padding: 3px 30px;} +.footer::before {content: ""; display: block; width: 100%; height: 1px; background: #ccc;} +.footer .inner {width: 1400px; margin: 0 auto; } .footer .inner::after {content: ""; display: block; clear: both;} .footer h1 {float: left; width: 220px; padding-top: 20px;} .footer h1 .m {display: none;} -.footer .info {float: left; padding: 14px 10px; color: #888; font-size: 13px; } +.footer .info {padding: 20px 0; color: #A4A4A4; font-size: 12px; } .footer .info .copy {padding-top: 5px;} .footer .info .m_show {display: none;} -.footer .right_col {position: absolute; right: 0; top: 73px; font-size: 0;} -.footer .right_col a {display: inline-block; margin-right: 60px; vertical-align: top;} -.footer .right_col a .m {display: none;} -.footer .right_col img {display: block;} +.footer .right_col {width: 220px; text-align: right;} +.footer .right_col a {color: #A4A4A4; font-size: 12px;} + /*.footer .right_col {position: absolute; right: 0; top: 73px; font-size: 0;}*/ +/*.footer .right_col a {display: inline-block; margin-right: 60px; vertical-align: top;}*/ +/*.footer .right_col a .m {display: none;}*/ +/*.footer .right_col img {display: block;}*/ /* popup */ @@ -138,4 +183,40 @@ body {min-width: 1400px;} .msg_1 + .tit_5 {margin-top: 42px;} -.qna_a + .replay {margin-top: 30px;} \ No newline at end of file +.qna_a + .replay {margin-top: 30px;} + + + +.btn-22498E { + --bs-btn-color: #fff; + --bs-btn-bg: #22498E; + --bs-btn-border-color: #22498E; + --bs-btn-hover-color: #fff; + --bs-btn-hover-bg: #2B5AB3; + --bs-btn-hover-border-color: #2B5AB3; + --bs-btn-focus-shadow-rgb: 130, 138, 145; + --bs-btn-active-color: #fff; + --bs-btn-active-bg: #2B5AB3; + --bs-btn-active-border-color: #51585e; + --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); + --bs-btn-disabled-color: #1B376D; + --bs-btn-disabled-bg: #2a4702; + --bs-btn-disabled-border-color: #1B376D; +} + +.btn-outline-22498E { + --bs-btn-color: #22498E; + --bs-btn-border-color: #2B5AB3; + --bs-btn-hover-color: #fff; + --bs-btn-hover-bg: #22498E; + --bs-btn-hover-border-color: #2B5AB3; + --bs-btn-focus-shadow-rgb: 108, 117, 125; + --bs-btn-active-color: #fff; + --bs-btn-active-bg: #2B5AB3; + --bs-btn-active-border-color: #2B5AB3; + --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); + --bs-btn-disabled-color: #2B5AB3; + --bs-btn-disabled-bg: transparent; + --bs-btn-disabled-border-color: #2B5AB3; + --bs-gradient: none; +} \ No newline at end of file diff --git a/egovframe-template-simple-react-contribution/src/css/page.css b/egovframe-template-simple-react-contribution/src/css/page.css index 29a13cb..5da9b40 100644 --- a/egovframe-template-simple-react-contribution/src/css/page.css +++ b/egovframe-template-simple-react-contribution/src/css/page.css @@ -1,92 +1,146 @@ @charset "utf-8"; .Plogin {padding-bottom: 100px;} -.Plogin h1 {color: #222; font-size: 48px; font-weight: 500; letter-spacing: -2px; line-height: 48px; text-align: center;} +.Plogin h1 {color: #222; font-size: 30px; font-weight: 600; text-align: center; padding-top: 30px;} .Plogin .txt {margin-top: 43px; color: #666; font-size: 20px; line-height: 30px; text-align: center;} -.Plogin .login_box {position: relative; width: 690px; margin: 54px auto 0; padding: 70px 95px ; border: 1px solid #dde2e5; border-radius: 25px; box-shadow: 3px 4px 5px #ccc;} +.Plogin .login_box {position: relative; width: 690px; margin: 54px auto 0; padding: 30px 50px ; border: 1px solid #dde2e5; border-radius: 25px; box-shadow: 3px 4px 5px #ccc;} .Plogin .login_box .group {display: block; width: 320px;} .Plogin .login_box input[type=text], -.Plogin .login_box input[type=password] {width: 100%; height: 46px; padding: 0 20px; border: 0; border-radius: 8px; color: #666; font-size: 16px; background: #f5f5f5;} +.Plogin .login_box input[type=password] {height: 50px; border-top-right-radius: 10px; border-bottom-right-radius: 10px;} +/*.Plogin .login_box input[type=text],*/ +/*.Plogin .login_box input[type=password] {width: 100%; height: 46px; padding: 0 20px; border: 0; border-radius: 8px; color: #666; font-size: 16px; background: #f5f5f5;}*/ .Plogin .login_box .group input + input {margin-top: 18px;} .Plogin .login_box input[type=text]:-ms-input-placeholder, .Plogin .login_box input[type=password]:-ms-input-placeholder {color: #aaa; opacity: 1;} -.Plogin .login_box button {display: block; position: absolute; left: 435px; top: 70px; width: 160px; height: 110px; border-radius: 8px; color: #fff; font-size: 20px; font-weight: 500; text-align: center; line-height: 110px; background: #169bd5;} -.Plogin .login_box button span {display: block; position: relative; height: 100%;} +.Plogin .login_box button {width: 100%; height: 50px; font-size: 15px;} +.Plogin .login_box a {font-size: 15px;} +/*.Plogin .login_box button {display: block; width: 160px; height: 110px; border-radius: 8px; color: #fff; font-size: 20px; font-weight: 500; text-align: center; line-height: 110px; background: #169bd5;}*/ +/*.Plogin .login_box button span {display: block; position: relative; height: 100%;}*/ +.line_t {height: 15px; border-bottom: 1px solid #D6D6D6; } +.line_b {height: 15px; border-top: 1px solid #C2C2C2; } .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 label {display: inline-block; height: 30px; color: #666; font-size: 16px;} +.Plogin .login_box .chk em {display: inline-block; height: 30px; color: #666; font-size: 15px;} +.Plogin .login_box .chk em:nth-child(2) {padding: 0 10px;} +.Plogin .login_box .chk label {display: inline-block; height: 30px; color: #666; font-size: 15px;} .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::before {content: ""; display: block; position: absolute; left: 0; top: 12px; width: 4px; height: 4px; background: #666;} .Plogin .list li + li {margin-top: 5px;} -.Pjoin h1 {color: #222; font-size: 48px; font-weight: 500; letter-spacing: -2px; line-height: 48px; text-align: center;} -.Pjoin .join_box {position: relative; width: 690px; margin: 54px auto 0; padding: 70px 95px; border: 1px solid #dde2e5; border-radius: 25px; box-shadow: 3px 4px 5px #ccc;} +.Pjoin h1 {color: #222; font-size: 30px; font-weight: 600; text-align: center; padding-top: 30px;} +.Pjoin .join_box {width: 690px; margin: 40px auto 0; padding: 30px 50px; border: 1px solid #dde2e5; border-radius: 25px; box-shadow: 3px 4px 5px #ccc;} .Pjoin .join_box input[type=text], .Pjoin .join_box input[type=password] {width: 100%; height: 46px; padding: 0 20px; border: 0; border-radius: 8px; color: #666; font-size: 16px; background: #f5f5f5;} .Pjoin .join_box .group input + input {margin-top: 18px;} .Pjoin .join_box input[type=text]:-ms-input-placeholder, .Pjoin .join_box input[type=password]:-ms-input-placeholder {color: #aaa; opacity: 1;} +.Pjoin .join_box label {padding-top: 20px; font-weight: 700;} .Pjoin .join_box .chk {margin-top: 20px;} .Pjoin .join_box .chk em {display: inline-block; height: 30px; margin-left: 40px; color: #666; font-size: 16px;} -.Pjoin .join_box button {width: 500px;height: 50px;border-radius: 8px;color: #fff;font-size: 20px;font-weight: 500;text-align: center;line-height: 50px;background: #169bd5;} -.Pjoin .join_box button:disabled {background: rgba(22, 155, 213, 0.4); cursor: auto;} -.Pjoin .join_box button span {display: block; position: relative; height: 100%;} -.Pjoin .join_box .list li {position: relative; padding-left: 15px; color: #666; font-size: 16px; line-height: 26px;} +.Pjoin .join_box button {width: 50%; padding-top: 10px; } +/*.Pjoin .join_box button {width: 500px;height: 50px;border-radius: 8px;color: #fff;font-size: 20px;font-weight: 500;text-align: center;line-height: 50px;background: #169bd5;}*/ +/*.Pjoin .join_box button:disabled {background: rgba(22, 155, 213, 0.4); cursor: auto;}*/ +/*.Pjoin .join_box button span {display: block; position: relative; height: 100%;}*/ +.Pjoin .join_box .list li {padding-left: 15px; color: #666; font-size: 13px; line-height: 23px;} .Pjoin .join_box .list li + li {margin-top: 5px;} - +.radius_r {border-top-right-radius: 8px !important; border-bottom-right-radius: 8px !important;} /* Board */ /* 메인 */ - .P_MAIN {position: relative; background: #f5f5f5;} - .P_MAIN::before {content: ""; display: block; position: absolute; left: 0; top: 0; width: 100%; height: 360px; background: #fff;} - .P_MAIN .c_wrap {position: relative;} - .P_MAIN .colbox::after {content: ""; display: block; clear: both;} - .P_MAIN .colbox > * {float: left;} - .P_MAIN .colbox .left_col {width: 620px; margin-right: 60px; padding-top: 30px;} - .P_MAIN .colbox .left_col img {max-width: 100%; border-radius: 38px; box-shadow: 8px 8px 13px #ccc;} - .P_MAIN .colbox .right_col {width: 620px; padding-top: 25px;} + /*.P_MAIN {position: relative; background: #f5f5f5;}*/ + /*.P_MAIN::before {content: ""; display: block; position: absolute; left: 0; top: 0; width: 100%; height: 360px; background: #fff;}*/ + .P_MAIN .c_wrap .topbox {width: 100%; height:490px; background: #F8F8F8; margin: 0 auto;} + .P_MAIN .c_wrap .topbox .topbox_1 {width: 360px; height: 390px; border: 1px solid #dde2e5; border-radius: 25px; box-shadow: 0 4px 5px #ccc; background: #fff; padding: 30px;} + .P_MAIN .c_wrap .topbox .topbox_1 .topbox_11{font-size: 22px; font-weight: 700; padding-bottom: 20px;} + .P_MAIN .c_wrap .topbox .topbox_1 .topbox_12{font-size: 14px; } + .P_MAIN .c_wrap .topbox .topbox_1 .topbox_13{font-size: 12px; font-weight: 700; color: #22498E; padding-bottom: 30px;} + .P_MAIN .c_wrap .topbox .topbox_1 .topbox_14{font-size: 17px; font-weight: 600; line-height: 42px; white-space: nowrap;} + .P_MAIN .c_wrap .topbox .topbox_2 {width: 630px; height: 390px; border: 1px solid #dde2e5; border-radius: 25px; box-shadow: 0 4px 5px #ccc; background: #fff; margin: 0 25px; padding: 30px;} + .P_MAIN .c_wrap .topbox .topbox_2 .topbox_11{font-size: 22px; font-weight: 700; padding-bottom: 20px;} + .P_MAIN .c_wrap .topbox .topbox_2 .topbox_12{font-size: 19px; padding-bottom: 70px;} + .P_MAIN .c_wrap .topbox .topbox_2 .topbox_13 {width: 80px; height: 80px; border-radius: 50%; background: #E2E9F6; display: flex; justify-content: center; align-items: center; margin-left: 1.2rem;} + .P_MAIN .c_wrap .topbox .topbox_2 .topbox_14{font-size: 16px; font-weight: 600; text-align: center; line-height: 40px; color: #222; padding: 10px 0;} + .P_MAIN .c_wrap .topbox .topbox_2 .topbox_15{text-align: center; line-height: 40px;} + .P_MAIN .c_wrap .topbox .topbox_3 {width: 360px; height: 390px; border: 1px solid #dde2e5; border-radius: 25px; box-shadow: 0 4px 5px #ccc; background: #fff; padding: 30px;} + .P_MAIN .c_wrap .topbox .topbox_3 .topbox_11{font-size: 22px; font-weight: 700; padding-bottom: 20px;} + .P_MAIN .c_wrap .login_search {border: 1px solid #6F6F6F; border-radius: 10px; overflow: hidden;} + .P_MAIN .c_wrap .login_search_word {max-height: 125px; padding: 5px; overflow-x: auto; overflow-y: auto;} + .P_MAIN .c_wrap .menubox {width: 100%; height:200px;} + .P_MAIN .c_wrap .menubox .menubox_n {padding: 0 50px;} + .P_MAIN .c_wrap .menubox .menu_img {width: 100px; height: 100px; border-radius: 50%; background: #E2E9F6; display: flex; justify-content: center; align-items: center;} + .P_MAIN .c_wrap .menubox .menu_text {font-size: 16px; font-weight: 700; padding-top: 10px; justify-content: center; color: #222;} + .P_MAIN .c_wrap .qnabox {width: 100%; height:390px; background: #F8FAFC;} + .P_MAIN .c_wrap .qnabox .qnabox_1 {width: 1400px; height: 100px; margin:0 auto; padding: 0 10px; font-size: 35px; font-weight: 700; color: #004994;} + .P_MAIN .c_wrap .qnabox .qnabox_11 {width: 50%; font-size: 35px; font-weight: 700; color: #004994;} + .P_MAIN .c_wrap .qnabox .qnabox_12 {width: 50%; font-size: 20px; font-weight: 500; color: #6C6C6C;} + .P_MAIN .c_wrap .qnabox .qnabox_12 .rounded_circle_qna {width: 32px; height: 32px; border-radius: 50%; background: #FFF; box-shadow: 0 4px 5px #ccc; align-items: center; text-align: center; display: flex; } + .P_MAIN .c_wrap .qnabox .qnabox_2 {width: 1400px; margin:0 auto; } + .P_MAIN .c_wrap .qnabox .qnabox_n {width: 330px; height: 200px; border: 1px solid #dde2e5; border-radius: 10px; box-shadow: 0 4px 5px #ccc; background: #fff; margin: 20px 10px; padding: 30px;} + .P_MAIN .c_wrap .qnabox .qnabox_n .qnabox_n_file {background: #EBF1FF; border-radius: 10px; color: #22498E; font-size: 12px;} + .P_MAIN .c_wrap .qnabox .qnabox_n .qnabox_n_title {height: 100px; font-size: 18px; overflow: hidden; text-overflow: ellipsis; font-weight: 600;} + .P_MAIN .c_wrap .qnabox .qnabox_n .qnabox_n_date {font-size: 13px; } + .P_MAIN .c_wrap .numbox {width: 100%; height:200px; background: #4C6C84;} + .P_MAIN .c_wrap .numbox .numbox_n {width: 300px; color: #fff; text-align: center;} + .P_MAIN .c_wrap .numbox .num_text {font-size: 22px; font-weight: 700;} + .P_MAIN .c_wrap .numbox .num_count {font-size: 40px; font-weight: 700; padding-top: 10px;} + .P_MAIN .c_wrap .numbox .num_count span.unit {font-size: 22px;} + .P_MAIN .c_wrap .bbsbox {width: 100%; height:430px; border-bottom: 1px solid #E6E6E6; margin: 0 auto; padding-top: 85px;} + .P_MAIN .c_wrap .bbsbox .bbsbox_1 {width: 980px; } + .P_MAIN .c_wrap .bbsbox .bbsbox_2 {width: 370px; margin-left: 50px;} + .P_MAIN .c_wrap .bbsbox .bbsbox_2 img {max-width: 370px; border-radius: 20px; } - .P_MAIN .mini_board {position: relative;} - .P_MAIN .mini_board .tab::after {content: ""; display: block; clear: both;} - .P_MAIN .mini_board .tab li {float: left;} - .P_MAIN .mini_board .tab li + li {margin-left: 40px;} - .P_MAIN .mini_board .tab li a {display: block; position: relative; padding-bottom: 12px; color: #ccc; font-size: 30px; font-weight: 700;} - .P_MAIN .mini_board .tab li a.on {color: #222;} - .P_MAIN .mini_board .tab li a.on::after {content: ""; display: block; position: absolute; left: 0; bottom: 0; width: 100%; height: 4px; background: #0465be;} - .P_MAIN .mini_board .more {display: block; position: absolute; right: 0; top: 16px; height: 16px; padding-left: 27px; color: #444; font-size: 18px; line-height: 16px; background: url(css/images/ico_plus.png) no-repeat;} - .P_MAIN .mini_board .list ul {margin-top: 33px;} - .P_MAIN .mini_board .list ul > li {position: relative;} - .P_MAIN .mini_board .list ul > li + li {margin-top: 10px;} - .P_MAIN .mini_board .list ul > li a {display: block; width: calc(100% - 100px); color: #666; font-size: 20px; text-overflow: ellipsis; white-space: nowrap; overflow: hidden;} - .P_MAIN .mini_board .list ul > li a:hover {color: #222; text-decoration: underline;} - .P_MAIN .mini_board .list ul > li span {position: absolute; right: 0; top: 4px; color: #aaa; font-size: 16px;} - .P_MAIN .mini_board .gallary {display: none;} + .P_MAIN .c_wrap .bannerbox {width: 1400px; height:80px; margin: 0 auto;} + /*.P_MAIN .c_wrap .bannerbox .slick-list {width: 1400px; margin: 0 auto;}*/ + .P_MAIN .c_wrap .bannerbox .banner_slide {max-width: 210px; max-height: 60px; border: 1px solid #dde2e5; border-radius: 15px; text-align: center; padding: 10px; margin: 10px;} + .P_MAIN .c_wrap .bannerbox .slick-slide img {max-width: 180px; max-height: 60px;} - .P_MAIN .banner {margin-top: 100px;} - .P_MAIN .banner::after {content: ""; display: block; clear: both;} - .P_MAIN .banner > a {display: block; position: relative; float: left; width: calc(50% - 10px); height: 160px; padding: 38px 0 0 39px; border-radius: 25px; background: #fff; overflow: hidden;} - .P_MAIN .banner > a.bn1::before {content: ""; display: block; position: absolute; right: 30px; top: -70px; width: 130px; height: 130px; border-radius: 50%; background: #bfe6e1;} - .P_MAIN .banner > a.bn2::before {content: ""; display: block; position: absolute; right: 30px; top: -70px; width: 130px; height: 130px; border-radius: 50%; background: #fad6d7;} - .P_MAIN .banner > a strong {display: block; padding-bottom: 8px; position: relative; color: #000; font-size: 26px; font-weight: 700;} - .P_MAIN .banner > a span {display: block; color: #666; font-size: 18px; font-weight: 300; line-height: 24px;} - .P_MAIN .banner > a:nth-child(1) {margin-right: 10px;} - .P_MAIN .banner > a:nth-child(2) {margin-left: 10px;} + /*.P_MAIN .c_wrap {position: relative;}*/ + /*.P_MAIN .colbox::after {content: ""; display: block; clear: both;}*/ + /*.P_MAIN .colbox > * {float: left;}*/ + /*.P_MAIN .colbox .left_col {width: 620px; margin-right: 60px; padding-top: 30px;}*/ + /*.P_MAIN .colbox .left_col img {max-width: 100%; border-radius: 38px; box-shadow: 8px 8px 13px #ccc;}*/ + /*.P_MAIN .colbox .right_col {width: 620px; padding-top: 25px;}*/ + + /*.P_MAIN .mini_board {position: relative;}*/ + /*.P_MAIN .mini_board .tab::after {content: ""; display: block; clear: both;}*/ + /*.P_MAIN .mini_board .tab li {float: left;}*/ + /*.P_MAIN .mini_board .tab li + li {margin-left: 40px;}*/ + /*.P_MAIN .mini_board .tab li a {display: block; position: relative; padding-bottom: 12px; color: #ccc; font-size: 30px; font-weight: 700;}*/ + /*.P_MAIN .mini_board .tab li a.on {color: #222;}*/ + /*.P_MAIN .mini_board .tab li a.on::after {content: ""; display: block; position: absolute; left: 0; bottom: 0; width: 100%; height: 4px; background: #0465be;}*/ + /*.P_MAIN .mini_board .more {display: block; position: absolute; right: 0; top: 16px; height: 16px; padding-left: 27px; color: #444; font-size: 18px; line-height: 16px; background: url(css/images/ico_plus.png) no-repeat;}*/ + /*.P_MAIN .mini_board .list ul {margin-top: 33px;}*/ + /*.P_MAIN .mini_board .list ul > li {position: relative;}*/ + /*.P_MAIN .mini_board .list ul > li + li {margin-top: 10px;}*/ + /*.P_MAIN .mini_board .list ul > li a {display: block; width: calc(100% - 100px); color: #666; font-size: 20px; text-overflow: ellipsis; white-space: nowrap; overflow: hidden;}*/ + /*.P_MAIN .mini_board .list ul > li a:hover {color: #222; text-decoration: underline;}*/ + /*.P_MAIN .mini_board .list ul > li span {position: absolute; right: 0; top: 4px; color: #aaa; font-size: 16px;}*/ + /*.P_MAIN .mini_board .gallary {display: none;}*/ + + /*.P_MAIN .banner {margin-top: 100px;}*/ + /*.P_MAIN .banner::after {content: ""; display: block; clear: both;}*/ + /*.P_MAIN .banner > a {display: block; position: relative; float: left; width: calc(50% - 10px); height: 160px; padding: 38px 0 0 39px; border-radius: 25px; background: #fff; overflow: hidden;}*/ + /*.P_MAIN .banner > a.bn1::before {content: ""; display: block; position: absolute; right: 30px; top: -70px; width: 130px; height: 130px; border-radius: 50%; background: #bfe6e1;}*/ + /*.P_MAIN .banner > a.bn2::before {content: ""; display: block; position: absolute; right: 30px; top: -70px; width: 130px; height: 130px; border-radius: 50%; background: #fad6d7;}*/ + /*.P_MAIN .banner > a strong {display: block; padding-bottom: 8px; position: relative; color: #000; font-size: 26px; font-weight: 700;}*/ + /*.P_MAIN .banner > a span {display: block; color: #666; font-size: 18px; font-weight: 300; line-height: 24px;}*/ + /*.P_MAIN .banner > a:nth-child(1) {margin-right: 10px;}*/ + /*.P_MAIN .banner > a:nth-child(2) {margin-left: 10px;}*/ + + /*.P_MAIN .banner_bot {padding: 60px 0 70px 0;}*/ + /*.P_MAIN .banner_bot::after {content: ""; display: block; clear: both;}*/ + /*.P_MAIN .banner_bot > div {float: left; width: 310px; height: 480px; padding: 0 30px; border-radius: 30px; text-align: center; background: #fff;}*/ + /*.P_MAIN .banner_bot > div + div {margin-left: 20px;}*/ + /*.P_MAIN .banner_bot > div > div {height: 410px; padding-top: 232px; border-bottom: 1px solid #e8e8e8;}*/ + /*.P_MAIN .banner_bot > div h2 {color: #000; font-size: 26px; font-weight: 700;}*/ + /*.P_MAIN .banner_bot > div p {margin-top: 23px; color: #666; font-size: 20px; line-height: 30px;}*/ + /*.P_MAIN .banner_bot > div a {display: inline-block; height: 70px; color: #666; font-size: 20px; line-height: 70px;}*/ + /*.P_MAIN .banner_bot > div a::before {content: ""; display: inline-block; width: 20px; height: 20px; margin-right: 9px; background: url(css/images/ico_more.png) no-repeat; vertical-align: -2px;}*/ + /*.P_MAIN .banner_bot > div.b1 > div {background: url(css/images/ico_bn01.png) no-repeat center 60px;}*/ + /*.P_MAIN .banner_bot > div.b2 > div {background: url(css/images/ico_bn02.png) no-repeat center 60px;}*/ + /*.P_MAIN .banner_bot > div.b3 > div {background: url(css/images/ico_bn03.png) no-repeat center 60px;}*/ + /*.P_MAIN .banner_bot > div.b4 > div {background: url(css/images/ico_bn04.png) no-repeat center 60px;}*/ - .P_MAIN .banner_bot {padding: 60px 0 70px 0;} - .P_MAIN .banner_bot::after {content: ""; display: block; clear: both;} - .P_MAIN .banner_bot > div {float: left; width: 310px; height: 480px; padding: 0 30px; border-radius: 30px; text-align: center; background: #fff;} - .P_MAIN .banner_bot > div + div {margin-left: 20px;} - .P_MAIN .banner_bot > div > div {height: 410px; padding-top: 232px; border-bottom: 1px solid #e8e8e8;} - .P_MAIN .banner_bot > div h2 {color: #000; font-size: 26px; font-weight: 700;} - .P_MAIN .banner_bot > div p {margin-top: 23px; color: #666; font-size: 20px; line-height: 30px;} - .P_MAIN .banner_bot > div a {display: inline-block; height: 70px; color: #666; font-size: 20px; line-height: 70px;} - .P_MAIN .banner_bot > div a::before {content: ""; display: inline-block; width: 20px; height: 20px; margin-right: 9px; background: url(css/images/ico_more.png) no-repeat; vertical-align: -2px;} - .P_MAIN .banner_bot > div.b1 > div {background: url(css/images/ico_bn01.png) no-repeat center 60px;} - .P_MAIN .banner_bot > div.b2 > div {background: url(css/images/ico_bn02.png) no-repeat center 60px;} - .P_MAIN .banner_bot > div.b3 > div {background: url(css/images/ico_bn03.png) no-repeat center 60px;} - .P_MAIN .banner_bot > div.b4 > div {background: url(css/images/ico_bn04.png) no-repeat center 60px;} - /* 오늘의 행사 */ .BRD001 .head > span:nth-child(1) {width: 150px;} @@ -141,17 +195,17 @@ .BRD005 .result .list_item > div:nth-child(4) {width: 120px;} .BRD005 .result .list_item > div:nth-child(5) {width: 100px;} - /* 게시판생성 관리 */ - .BRD006 .head > span:nth-child(1) {width: 70px;} + /* 게시판 관리 */ + .BRD006 .head > span:nth-child(1) {width: 160px; text-align: left;} .BRD006 .head > span:nth-child(3) {width: 160px;} - .BRD006 .head > span:nth-child(4) {width: 168px;} - .BRD006 .head > span:nth-child(5) {width: 140px;} - .BRD006 .head > span:nth-child(6) {width: 140px;} - .BRD006 .result .list_item > div:nth-child(1) {width: 70px;} + .BRD006 .head > span:nth-child(4) {width: 70px;} + .BRD006 .head > span:nth-child(5) {width: 70px;} + .BRD006 .head > span:nth-child(6) {width: 120px;} + .BRD006 .result .list_item > div:nth-child(1) {width: 160px; text-align: left;} .BRD006 .result .list_item > div:nth-child(3) {width: 160px;} - .BRD006 .result .list_item > div:nth-child(4) {width: 168px;} - .BRD006 .result .list_item > div:nth-child(5) {width: 140px;} - .BRD006 .result .list_item > div:nth-child(6) {width: 140px;} + .BRD006 .result .list_item > div:nth-child(4) {width: 70px;} + .BRD006 .result .list_item > div:nth-child(5) {width: 70px;} + .BRD006 .result .list_item > div:nth-child(6) {width: 120px;} /* 사이트관리 > 사용자관리 > 사용자목록 */ .userList .head > span:nth-child(1) {width: 60px;} @@ -229,16 +283,20 @@ .SITE_INTRO .ds_1 .bot + .tit_5 {margin-top: 46px;} .SITE_INTRO .ds_1 .msg_1 + .tit_5 {margin-top: 42px;} - .PDS_LIST .pdslist {margin-top: 24px; border-top: 2px solid #dde2e5; background: #f7f7f7;} - .PDS_LIST .pdslist ul {padding-top: 40px;} + + /* 홍보자료 */ + .PDS_LIST .pdslist {margin-top: 10px; } /* changed by lim margin-top: 24px; border-top: 2px solid #dde2e5; background: #f7f7f7; */ + /*.PDS_LIST .pdslist ul {padding-top: 40px; }*/ + .PDS_LIST .pdslist ul {display: flex; flex-wrap: wrap; gap: 22px;} .PDS_LIST .pdslist ul::after {content: ""; display: block; clear: both;} - .PDS_LIST .pdslist ul li {float: left; width: 50%; padding: 0 0 40px 40px;} - .PDS_LIST .pdslist ul li > a {display: block;} + .PDS_LIST .pdslist ul li:last-child {margin-right: 0;} + .PDS_LIST .pdslist ul li {border: 1px solid #B7B7B7; padding: 10px; width: auto;} /* changed by lim float: left; width: 50%; padding: 0 0 40px 40px; */ + .PDS_LIST .pdslist ul li > a {display: block; color: #383838;} .PDS_LIST .pdslist ul li > a::after {content: ""; display: block; clear: both;} - .PDS_LIST .pdslist ul li > a img {display: block; float: left; width: 160px; margin-right: 20px;} - .PDS_LIST .pdslist ul li > a > span {display: block; float: left; width: calc(100% - 180px); padding-right: 10px;} - .PDS_LIST .pdslist ul li > a > span strong {display: block; padding-bottom: 8px; color: #222; font-size: 18px; font-weight: 400;} - .PDS_LIST .pdslist ul li > a > span span {color: #666; font-size: 16px; font-weight: 300; line-height: 26px;} + .PDS_LIST .pdslist ul li > img.promotion {width: 249px; margin-bottom:10px; border: 1px solid #CACACA; border-radius: 10px; cursor: pointer;} /* changed by lim display: block; float: left; margin-right: 20px; */ + /*.PDS_LIST .pdslist ul li > a > span {display: block; float: left; width: calc(100% - 180px); padding-right: 10px;}*/ + /*.PDS_LIST .pdslist ul li > a > span strong {display: block; padding-bottom: 8px; color: #222; font-size: 18px; font-weight: 400;}*/ + /*.PDS_LIST .pdslist ul li > a > span span {font-size: 16px; font-weight: 300; line-height: 26px;}*/ .PDS_LIST .recent {height: 290px; margin-top: 24px; border: 2px solid #dde2e5;} .PDS_LIST .recent::after {content: ""; display: block; clear: both;} @@ -253,14 +311,22 @@ .PDS_LIST .recent > ul li .ymd {display: block; position: absolute; right: 0; top: 0; height: 30px; color: #666; font-size: 16px; line-height: 30px;} .PDS_LIST .tit_5 {margin-top: 42px;} .PDS_LIST .board_list {margin-top: 50px;} + + + + /* 사이트관리 > 게시판현황 > 게시물관리 */ .BRD007 .head > span:nth-child(1) {width: 70px;} - .BRD007 .head > span:nth-child(3) {width: 90px;} - .BRD007 .head > span:nth-child(4) {width: 90px;} - .BRD007 .head > span:nth-child(5) {width: 120px;} + .BRD007 .head > span:nth-child(3) {width: 70px;} + .BRD007 .head > span:nth-child(4) {width: 120px;} + .BRD007 .head > span:nth-child(5) {width: 160px;} + .BRD007 .head > span:nth-child(6) {width: 120px;} + .BRD007 .head > span:nth-child(7) {width: 140px;} .BRD007 .result .list_item > div:nth-child(1) {width: 70px;} - .BRD007 .result .list_item > div:nth-child(3) {width: 90px;} - .BRD007 .result .list_item > div:nth-child(4) {width: 90px;} - .BRD007 .result .list_item > div:nth-child(5) {width: 120px;} + .BRD007 .result .list_item > div:nth-child(3) {width: 70px;} + .BRD007 .result .list_item > div:nth-child(4) {width: 120px;} + .BRD007 .result .list_item > div:nth-child(5) {width: 160px;} + .BRD007 .result .list_item > div:nth-child(6) {width: 120px;} + .BRD007 .result .list_item > div:nth-child(7) {width: 140px;} .PDS_REG .pds_desc_edit {margin: 14px 0 30px 0;} @@ -340,6 +406,31 @@ .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;} + + /* 사용자 게시판 */ + .BRD013 .head > span:nth-child(1) {position: relative; width: 60px;} + .BRD013 .head > span:nth-child(2) {position: relative;} + .BRD013 .head > span:nth-child(3) {position: relative; width: 100px;} + .BRD013 .head > span:nth-child(4) {position: relative; width: 100px;} + .BRD013 .head > span:nth-child(5) {position: relative; width: 120px;} + .BRD013 .head > span:nth-child(6) {width: 80px;} + .BRD013 .head > span:nth-child(-n+5)::after {position: absolute; content: ''; right: 0; bottom: 0; height: 50%; border-right: 1px solid #B5B5B5;} + .BRD013 .result .list_item > div:nth-child(1) {width: 60px;} + .BRD013 .result .list_item > div:nth-child(2) {text-overflow: ellipsis; white-space: nowrap; overflow: hidden;} + .BRD013 .result .list_item > div:nth-child(3) {width: 100px;} + .BRD013 .result .list_item > div:nth-child(4) {width: 100px;} + .BRD013 .result .list_item > div:nth-child(5) {width: 120px;} + .BRD013 .result .list_item > div:nth-child(6) {width: 80px;} + + /* 사용자 영문건설기준 */ + .BRD014 .head > span:nth-child(1) {position: relative; width: 30%; background: #22498E; color: #fff; border-right: 2px solid #657E9E;} + .BRD014 .head > span:nth-child(2) {position: relative; width: 35%; background: #22498E; color: #fff; border-right: 2px solid #657E9E;} + .BRD014 .head > span:nth-child(3) {position: relative; width: 35%; background: #22498E; color: #fff; border-right: 2px solid #657E9E;} + .BRD014 .result .list_item1 > div:nth-child(1) {width: 30%; border-right: 2px solid #657E9E;} + .BRD014 .result .list_item1 > div:nth-child(2) {width: 35%; border-right: 2px solid #657E9E;} + .BRD014 .result .list_item1 > div:nth-child(3) {width: 35%; } + + /* 찾아오시는길 */ .SITE_CONTACT_US .map {margin-top: 43px;} .SITE_CONTACT_US .map img {max-width: 100%;} @@ -431,20 +522,20 @@ .bookmark:hover{cursor: pointer} .errorText{color:white; background-color: red; font-size: x-small; vertical-align: bottom; padding: 0 10px;} -/*기준코드 뷰어*/ -.titleCheckBox ~ p {display: inline} -.errorCnt{display: inline; color:red;} -.errorText{display: inline; cursor: pointer} -.detailInfoDiv > div > input {margin-right: 5px;} -.docInfoTitle{white-space: nowrap;} -.yearInfo{font-size: 9px} -.yearInfoActive{color: #0d6efd} -.docInfoBtn{--bs-btn-padding-y: 0.1rem;--bs-btn-padding-x: 0.25rem;--bs-btn-font-size: 0.7rem; filter: grayscale(100%);} -.docInfoActive{filter: grayscale(0%);} -.modalYearInfo{font-size: 9px} -.modalYearInfoActive{color: #0d6efd} -.modalDocInfoBtn{--bs-btn-padding-y: 0.1rem;--bs-btn-padding-x: 0.25rem;--bs-btn-font-size: 0.7rem; filter: grayscale(100%);} -.modalDocInfoActive{filter: grayscale(0%);} -.docInfoRow > div{--bs-gutter-x: 0.5rem;} -.bookmarkModalHeader{--bs-modal-title-line-height:1;} -.optionBtn{--bs-btn-padding-y: 0.1rem;--bs-btn-padding-x: 0.25rem;--bs-btn-font-size: 0.7rem; margin-right: 7px;} \ No newline at end of file + /*기준코드 뷰어*/ + .titleCheckBox ~ p {display: inline} + .errorCnt{display: inline; color:red;} + .errorText{display: inline; cursor: pointer} + .detailInfoDiv > div > input {margin-right: 5px;} + .docInfoTitle{white-space: nowrap;} + .yearInfo{font-size: 9px} + .yearInfoActive{color: #0d6efd} + .docInfoBtn{--bs-btn-padding-y: 0.1rem;--bs-btn-padding-x: 0.25rem;--bs-btn-font-size: 0.7rem; filter: grayscale(100%);} + .docInfoActive{filter: grayscale(0%);} + .modalYearInfo{font-size: 9px} + .modalYearInfoActive{color: #0d6efd} + .modalDocInfoBtn{--bs-btn-padding-y: 0.1rem;--bs-btn-padding-x: 0.25rem;--bs-btn-font-size: 0.7rem; filter: grayscale(100%);} + .modalDocInfoActive{filter: grayscale(0%);} + .docInfoRow > div{--bs-gutter-x: 0.5rem;} + .bookmarkModalHeader{--bs-modal-title-line-height:1;} + .optionBtn{--bs-btn-padding-y: 0.1rem;--bs-btn-padding-x: 0.25rem;--bs-btn-font-size: 0.7rem; margin-right: 7px;} diff --git a/egovframe-template-simple-react-contribution/src/font/Pretendard-Regular.otf b/egovframe-template-simple-react-contribution/src/font/Pretendard-Regular.otf new file mode 100644 index 0000000..c940185 Binary files /dev/null and b/egovframe-template-simple-react-contribution/src/font/Pretendard-Regular.otf differ diff --git a/egovframe-template-simple-react-contribution/src/pages/about/EgovAboutHistory.jsx b/egovframe-template-simple-react-contribution/src/pages/about/EgovAboutHistory.jsx index d08f51e..d3a08b3 100644 --- a/egovframe-template-simple-react-contribution/src/pages/about/EgovAboutHistory.jsx +++ b/egovframe-template-simple-react-contribution/src/pages/about/EgovAboutHistory.jsx @@ -12,7 +12,7 @@ function EgovAboutHistory() {
              • Home
              • -
              • 사이트 소개
              • +
              • 센터 소개
              • 연혁
              @@ -26,17 +26,17 @@ function EgovAboutHistory() {
              {/* */} -

              사이트 소개

              +

              연혁

              -

              표준프레임워크 경량환경 포털사이트를 소개합니다.

              + {/*

              표준프레임워크 경량환경 포털사이트를 소개합니다.

              */} -

              전자정부표준프레임워크 연혁

              - -

              연혁

              - -

              표준프레임워크 활성화 전담조직으로 한국정보화진흥원(NIA)에 2010년 11월 4일 「표준프레임워크센터」가
              - 설립되었으며 정책지원, 글로벌 확산 등을 담당할 NIA 인력과 R&D, 기술지원 등을 담당할 외부 민간 전문가로
              - 구성되었습니다.

              + {/*

              전자정부표준프레임워크 연혁

              */} + + {/*

              연혁

              */} + + {/*

              표준프레임워크 활성화 전담조직으로 한국정보화진흥원(NIA)에 2010년 11월 4일 「표준프레임워크센터」가
              */} + {/* 설립되었으며 정책지원, 글로벌 확산 등을 담당할 NIA 인력과 R&D, 기술지원 등을 담당할 외부 민간 전문가로
              */} + {/* 구성되었습니다.

              */} {/* */}
              diff --git a/egovframe-template-simple-react-contribution/src/pages/about/EgovAboutLocation.jsx b/egovframe-template-simple-react-contribution/src/pages/about/EgovAboutLocation.jsx index d8401db..63e0830 100644 --- a/egovframe-template-simple-react-contribution/src/pages/about/EgovAboutLocation.jsx +++ b/egovframe-template-simple-react-contribution/src/pages/about/EgovAboutLocation.jsx @@ -12,8 +12,8 @@ function EgovAboutLocation() {
              • Home
              • -
              • 사이트 소개
              • -
              • 찾아오시는길
              • +
              • 센터 소개
              • +
              • 찾아오시는 길
              {/* */} @@ -26,64 +26,64 @@ function EgovAboutLocation() {
              {/* */} -

              사이트 소개

              +

              찾아오시는 길

              -

              표준프레임워크 경량환경 포털사이트를 소개합니다.

              + {/*

              표준프레임워크 경량환경 포털사이트를 소개합니다.

              */} -

              찾아오시는길

              + {/*

              찾아오시는길

              */} -
              - - - -
              + {/*
              */} + {/* */} + {/* */} + {/* */} + {/*
              */} -
              -
              -

              표준프레임워크센터 주소

              -
              -
              도로명주소
              -
              04513 서울특별시 중구 세종대로 39 대한서울상공회의소 7층
              -
              -
              -
              지번주소
              -
              04513 서울특별시 중구 남대문로4가 45 대한서울상공회의소 7층
              -
              -
              -
              -

              QR코드로 위치알아보기

              -

              스마트폰에서 QR코드
              - 리더를 이용해 사진·
              - 지도 등 다양한 정보를
              - 확인하세요.

              - qr code -
              -
              + {/*
              */} + {/*
              */} + {/*

              표준프레임워크센터 주소

              */} + {/*
              */} + {/*
              도로명주소
              */} + {/*
              04513 서울특별시 중구 세종대로 39 대한서울상공회의소 7층
              */} + {/*
              */} + {/*
              */} + {/*
              지번주소
              */} + {/*
              04513 서울특별시 중구 남대문로4가 45 대한서울상공회의소 7층
              */} + {/*
              */} + {/*
              */} + {/*
              */} + {/*

              QR코드로 위치알아보기

              */} + {/*

              스마트폰에서 QR코드
              */} + {/* 리더를 이용해 사진·
              */} + {/* 지도 등 다양한 정보를
              */} + {/* 확인하세요.

              */} + {/* qr code*/} + {/*
              */} + {/*
              */} -
              -
              -

              찾아오시는 길

              -
              -
              지하철 2호선
              -
              시청역 9번 출구 5분거리
              -
              -
              -
              지하철 1호선
              -
              서울역 3번 출구 5분거리
              -
              -
              -
              -

              연락처

              -
              -
              전화
              -
              0000-0000
              -
              -
              -
              이메일
              -
              egovframeexample@gmail.com
              -
              -
              -
              + {/*
              */} + {/*
              */} + {/*

              찾아오시는 길

              */} + {/*
              */} + {/*
              지하철 2호선
              */} + {/*
              시청역 9번 출구 5분거리
              */} + {/*
              */} + {/*
              */} + {/*
              지하철 1호선
              */} + {/*
              서울역 3번 출구 5분거리
              */} + {/*
              */} + {/*
              */} + {/*
              */} + {/*

              연락처

              */} + {/*
              */} + {/*
              전화
              */} + {/*
              0000-0000
              */} + {/*
              */} + {/*
              */} + {/*
              이메일
              */} + {/*
              egovframeexample@gmail.com
              */} + {/*
              */} + {/*
              */} + {/*
              */} {/* */}
              diff --git a/egovframe-template-simple-react-contribution/src/pages/about/EgovAboutOrganization.jsx b/egovframe-template-simple-react-contribution/src/pages/about/EgovAboutOrganization.jsx index 07a3b1d..b0ba209 100644 --- a/egovframe-template-simple-react-contribution/src/pages/about/EgovAboutOrganization.jsx +++ b/egovframe-template-simple-react-contribution/src/pages/about/EgovAboutOrganization.jsx @@ -12,8 +12,8 @@ function EgovAboutOrganization() {
              • Home
              • -
              • 사이트 소개
              • -
              • 조직소개
              • +
              • 센터 소개
              • +
              • 주요업무
              {/* */} @@ -26,17 +26,17 @@ function EgovAboutOrganization() {
              {/* */} -

              사이트 소개

              +

              홍보자료

              -

              표준프레임워크 경량환경 포털사이트를 소개합니다.

              + {/*

              표준프레임워크 경량환경 포털사이트를 소개합니다.

              */} -

              조직소개

              + {/*

              조직소개

              */} -

              조직

              + {/*

              조직

              */} -

              오픈커뮤니티의 초기 정착을 위해 표준프레임워크 개발 참여자와 국내 주요 오픈커뮤니티의 운영자·전문가를 리딩
              - 그룹(PMC, 커미터)으로 구성 오픈커뮤니티의 지속적인 확대·발전을 위해 프로젝트 활동에 적극적으로 참여하는
              - 커뮤니티 회원이 리딩그룹의 역할을 획득할 수 있도록 투명하고 공정한 의사결정 체계를 수립

              + {/*

              오픈커뮤니티의 초기 정착을 위해 표준프레임워크 개발 참여자와 국내 주요 오픈커뮤니티의 운영자·전문가를 리딩
              */} + {/* 그룹(PMC, 커미터)으로 구성 오픈커뮤니티의 지속적인 확대·발전을 위해 프로젝트 활동에 적극적으로 참여하는
              */} + {/* 커뮤니티 회원이 리딩그룹의 역할을 획득할 수 있도록 투명하고 공정한 의사결정 체계를 수립

              */} {/* */}
              diff --git a/egovframe-template-simple-react-contribution/src/pages/about/EgovAboutPromote.jsx b/egovframe-template-simple-react-contribution/src/pages/about/EgovAboutPromote.jsx new file mode 100644 index 0000000..f9457c5 --- /dev/null +++ b/egovframe-template-simple-react-contribution/src/pages/about/EgovAboutPromote.jsx @@ -0,0 +1,179 @@ +import React, { useEffect, useState, useRef } from 'react'; +import {Link, useLocation, useNavigate} from 'react-router-dom'; +import * as EgovNet from 'api/egovFetch'; + +import Row from 'react-bootstrap/Row'; +import Col from 'react-bootstrap/Col'; +import Modal from 'react-bootstrap/Modal'; + +import { default as EgovLeftNav } from 'components/leftmenu/EgovLeftNavAbout'; +import URL from "constants/url"; + +function Promote(){ + const [show, setShow] = useState(false); + const [modalContent, setModalContent] = useState({}); + const handleClose = () => setShow(false); + const handleShow = (content) => { + setModalContent(content); + setShow(true); + }; + + const items = [ + { + id: 1, + imgSrc: '/assets/images/nanae-1.png', + link: '/support-download-detail', + linkText: '2023년 12월 14호', + modalTitle: '2023년 12월 14호', + modalBody: ` + - 교량 건설기준 국제 통용성 분석 연구
              + - [기고문]건설산업 변화와 디지털 건설기준 도입
              + - [기고문]인공지능 기술을 활용한 건설기준 중복 상충부 검토
              + - 건설산업 디지털 전환 동향 파악을 위한 국외출장 결과
              + - 건설기준 주요 민원사례 소개
              + - 2023년 건설기준위원회 및 중앙건설기술심의위원회 개최 현황
              + - 2023년 건설기준 제·개정 고시 현황 + ` + }, + { + id: 2, + imgSrc: '/assets/images/nanae-1.png', + link: '/support-download-detail', + linkText: '2022년 12월 13호', + modalTitle: '2022년 12월 13호', + modalBody: ` + - 다른 내용1
              + - 다른 내용2
              + - 다른 내용3
              + - 다른 내용4
              + ` + }, + // 더 많은 항목을 추가 + ]; + + return ( +
              +
              + {/* */} +
              +
                +
              • Home
              • +
              • 센터소개
              • +
              • 홍보자료
              • +
              +
              + {/* */} + +
              + {/* */} + + {/* */} + +
              + {/* */} + +

              홍보자료

              + + + 전체: 14건 + PDF 파일을 보시려면 PC에 Adobe Reader Adobe Reader를 설치하셔야 합니다. + + +
              +
                + {items.map(item => ( + +
              • + handleShow({ title: item.modalTitle, body: item.modalBody })} /> + + {item.linkText} + +
              • +
                + ))} +
              • + + + 2022년 12월 13호 + +
              • +
              • + + + 2021년 12월 12호 + +
              • +
              • + + + 2020년 12월 11호 + +
              • +
              • + + + 2023년 12월 14호 + +
              • +
              • + + + 2022년 12월 13호 + +
              • +
              • + + + 2021년 12월 12호 + +
              • +
              +
              + + + + {/* */} + +
                +
              • +
              • +
              • +
              • +
              • +
              • +
              • +
              • +
              • +
              • +
              • +
              • +
              • +
              • +
              + + {/* */} + +
              + + + {/* */} +
              +
              +
              + + + + {modalContent.title} + + + {/**/} + {/* */} + {/**/} + +
              + ); +} + +export default Promote; \ No newline at end of file diff --git a/egovframe-template-simple-react-contribution/src/pages/about/EgovAboutSite.jsx b/egovframe-template-simple-react-contribution/src/pages/about/EgovAboutSite.jsx index ed5d40a..25744e8 100644 --- a/egovframe-template-simple-react-contribution/src/pages/about/EgovAboutSite.jsx +++ b/egovframe-template-simple-react-contribution/src/pages/about/EgovAboutSite.jsx @@ -11,8 +11,8 @@ function EgovAboutSite() {
              • Home
              • -
              • 사이트 소개
              • -
              • 소개
              • +
              • 센터 소개
              • +
              • 인사말
              {/* */} @@ -25,73 +25,73 @@ function EgovAboutSite() {
              {/* */} -

              사이트 소개

              +

              인사말

              -

              표준프레임워크 경량환경의 개요와 연혁, 조직소개,
              - 표준프레임워크센터의 약도 등의 정보를 제공하고 있습니다.

              + {/*

              표준프레임워크 경량환경의 개요와 연혁, 조직소개,
              */} + {/* 표준프레임워크센터의 약도 등의 정보를 제공하고 있습니다.

              */} -

              전자정부표준프레임워크 소개

              + {/*

              전자정부표준프레임워크 소개

              */} -

              개요

              + {/*

              개요

              */} -

              전자정부 표준 프레임워크는 응용SW의 구성기반이 되며 응용SW실행 시 필요한 기본 기능을 제공하는 환경이다.
              - 전자정부 표준 프레임워크는 ‘전자정부 서비스의 품질향상 및 정보화 투자 효율성 향상’을 위해 개발 프레임워크
              - 표준을 정립하고, 개발 프레임워크 표준 적용을 통한 응용 SW의 표준화 및 품질과 재사용성 향상을 목표로 한다.

              - -
              + {/*

              전자정부 표준 프레임워크는 응용SW의 구성기반이 되며 응용SW실행 시 필요한 기본 기능을 제공하는 환경이다.
              */} + {/* 전자정부 표준 프레임워크는 ‘전자정부 서비스의 품질향상 및 정보화 투자 효율성 향상’을 위해 개발 프레임워크
              */} + {/* 표준을 정립하고, 개발 프레임워크 표준 적용을 통한 응용 SW의 표준화 및 품질과 재사용성 향상을 목표로 한다.

              */} -

              전자정부 서비스 품질향상 및 정보화투자 효율성 향상

              - -
                -
              • 국가 정보화
                투자효율성 제고
              • -
              • 중소SI업체
                경쟁력 확보
              • -
              • 선진 국가정보화
                기반환경 제공
              • -
              - -

              전자정부표준프레임워크
              활용

              + {/*
              */} -
              -

              전자정부표준프레임워크 구축 및 적용 요구

              -
                -
              • 특정업체 종속성 발생으로
                - 인한 공정경쟁 저하 및 사업자
                - 변경 시 예산낭비
              • -
              • 기관별/사업별 개별적인
                - 정보화 사업추진으로 중복개발
              • -
              • 표준화된 공통 개발기반 부재로
                - 시스템간 상호 운용성 및
                - 재사용성 저하
              • -
              -

              전자정부표준프레임워크는 응용SW의 구성기반이 되며 응용SW실행 시 필요한 기본 기능을 제공하는 환경으로 - 정보시스템 구축 시 특정 대기업의 프레임워크로 구축·운영되어, 사업자 종속-비용증가 및 중소기업의 입찰제한 - 등의 폐단이 발생하는 것을 방지하기 위한 목적과 ‘전자정부 서비스의 품질향상 및 정보화 투자 효율성 향상’을 - 위해 개발 프레임워크 표준을 정립하고, 개발 프레임워크 표준 적용을 통한 응용 SW의 표준화 및 품질과 - 재사용성 향상을 목표로 한다.

              -
              + {/*

              전자정부 서비스 품질향상 및 정보화투자 효율성 향상

              */} + {/* */} + {/*
                */} + {/*
              • 국가 정보화
                투자효율성 제고
              • */} + {/*
              • 중소SI업체
                경쟁력 확보
              • */} + {/*
              • 선진 국가정보화
                기반환경 제공
              • */} + {/*
              */} + {/* */} + {/*

              전자정부표준프레임워크
              활용

              */} -

              배경

              -

              현재 전자정부는 유사한 기능을 가지는 다양한 종류 및 버전의 프레임워크를 개별 시스템 단위로 적용/관리하고 - 있으며, 이에 따라 다양한 문제점들이 발생하고 있다. 전자정부에 적용된 개발프레임워크는 Black Box 형태로 - 제공되어 사업자의 기술지원 없이는 응용 SW를 유지보수하기 어렵기 때문에 사업자에 대한 의존성이 발생한다. - - 복수개의 개발프레임워크가 적용된 사업의 경우, 프레임워크에 따라 개발표준 정의, 개발자수급, 교육시행 등 - 별도의 유지보수 체계를 갖추는 중복 투자가 발생하며, 개발프레임워크의 체계적인 관리절차의 미비로 동일 - 개발프레임워크라 하더라도 버전 관리에 어려움이 있다.전자정부의 프레임워크의 표준화는 사업자 고유 개발 - 프레임워크에 대한 기술 종속성을 배제하고 표준화를 통해 응용 SW의 표준화와 품질, 재사용성을 향상시키며, - 개발 프레임워크의 유지 보수 단일화를 통한 투자 효율성을 높인다.

              - -

              특징

              -

              현재 전자정부는 유사한 기능을 가지는 다양한 종류 및 버전의 프레임워크를 개별 시스템 단위로 적용/관리하고 - 있으며, 이에 따라 다양한 문제점들이 발생하고 있다. 전자정부에 적용된 개발프레임워크는 Black Box 형태로 - 제공되어 사업자의 기술지원 없이는 응용 SW를 유지보수하기 어렵기 때문에 사업자에 대한 의존성이 발생한다. - - 복수개의 개발프레임워크가 적용된 사업의 경우, 프레임워크에 따라 개발표준 정의, 개발자수급, 교육시행 등 - 별도의 유지보수 체계를 갖추는 중복 투자가 발생하며, 개발프레임워크의 체계적인 관리절차의 미비로 동일 - 개발프레임워크라 하더라도 버전 관리에 어려움이 있다.전자정부의 프레임워크의 표준화는 사업자 고유 개발 - 프레임워크에 대한 기술 종속성을 배제하고 표준화를 통해 응용 SW의 표준화와 품질, 재사용성을 향상시키며, - 개발 프레임워크의 유지 보수 단일화를 통한 투자 효율성을 높인다.

              + {/*
              */} + {/*

              전자정부표준프레임워크 구축 및 적용 요구

              */} + {/*
                */} + {/*
              • 특정업체 종속성 발생으로
                */} + {/* 인한 공정경쟁 저하 및 사업자
                */} + {/* 변경 시 예산낭비
              • */} + {/*
              • 기관별/사업별 개별적인
                */} + {/* 정보화 사업추진으로 중복개발
              • */} + {/*
              • 표준화된 공통 개발기반 부재로
                */} + {/* 시스템간 상호 운용성 및
                */} + {/* 재사용성 저하
              • */} + {/*
              */} + {/*

              전자정부표준프레임워크는 응용SW의 구성기반이 되며 응용SW실행 시 필요한 기본 기능을 제공하는 환경으로*/} + {/* 정보시스템 구축 시 특정 대기업의 프레임워크로 구축·운영되어, 사업자 종속-비용증가 및 중소기업의 입찰제한*/} + {/* 등의 폐단이 발생하는 것을 방지하기 위한 목적과 ‘전자정부 서비스의 품질향상 및 정보화 투자 효율성 향상’을 */} + {/* 위해 개발 프레임워크 표준을 정립하고, 개발 프레임워크 표준 적용을 통한 응용 SW의 표준화 및 품질과 */} + {/* 재사용성 향상을 목표로 한다.

              */} + {/*
              */} -
              + {/*

              배경

              */} + {/*

              현재 전자정부는 유사한 기능을 가지는 다양한 종류 및 버전의 프레임워크를 개별 시스템 단위로 적용/관리하고*/} + {/* 있으며, 이에 따라 다양한 문제점들이 발생하고 있다. 전자정부에 적용된 개발프레임워크는 Black Box 형태로*/} + {/* 제공되어 사업자의 기술지원 없이는 응용 SW를 유지보수하기 어렵기 때문에 사업자에 대한 의존성이 발생한다.*/} + {/* */} + {/* 복수개의 개발프레임워크가 적용된 사업의 경우, 프레임워크에 따라 개발표준 정의, 개발자수급, 교육시행 등*/} + {/* 별도의 유지보수 체계를 갖추는 중복 투자가 발생하며, 개발프레임워크의 체계적인 관리절차의 미비로 동일*/} + {/* 개발프레임워크라 하더라도 버전 관리에 어려움이 있다.전자정부의 프레임워크의 표준화는 사업자 고유 개발*/} + {/* 프레임워크에 대한 기술 종속성을 배제하고 표준화를 통해 응용 SW의 표준화와 품질, 재사용성을 향상시키며,*/} + {/* 개발 프레임워크의 유지 보수 단일화를 통한 투자 효율성을 높인다.

              */} + {/* */} + {/*

              특징

              */} + {/*

              현재 전자정부는 유사한 기능을 가지는 다양한 종류 및 버전의 프레임워크를 개별 시스템 단위로 적용/관리하고*/} + {/* 있으며, 이에 따라 다양한 문제점들이 발생하고 있다. 전자정부에 적용된 개발프레임워크는 Black Box 형태로*/} + {/* 제공되어 사업자의 기술지원 없이는 응용 SW를 유지보수하기 어렵기 때문에 사업자에 대한 의존성이 발생한다.*/} + {/* */} + {/* 복수개의 개발프레임워크가 적용된 사업의 경우, 프레임워크에 따라 개발표준 정의, 개발자수급, 교육시행 등*/} + {/* 별도의 유지보수 체계를 갖추는 중복 투자가 발생하며, 개발프레임워크의 체계적인 관리절차의 미비로 동일*/} + {/* 개발프레임워크라 하더라도 버전 관리에 어려움이 있다.전자정부의 프레임워크의 표준화는 사업자 고유 개발*/} + {/* 프레임워크에 대한 기술 종속성을 배제하고 표준화를 통해 응용 SW의 표준화와 품질, 재사용성을 향상시키며,*/} + {/* 개발 프레임워크의 유지 보수 단일화를 통한 투자 효율성을 높인다.

              */} + + {/*
              */} {/* */}
              diff --git a/egovframe-template-simple-react-contribution/src/pages/about/EgovAboutSitemap.jsx b/egovframe-template-simple-react-contribution/src/pages/about/EgovAboutSitemap.jsx new file mode 100644 index 0000000..349d697 --- /dev/null +++ b/egovframe-template-simple-react-contribution/src/pages/about/EgovAboutSitemap.jsx @@ -0,0 +1,14 @@ +import React, { useState } from 'react'; +import {Link, useLocation, useNavigate} from 'react-router-dom'; +import * as EgovNet from 'api/egovFetch'; + +function Sitemap(){ + + + + return ( +
              사이트맵
              + ); +} + +export default Sitemap; \ No newline at end of file diff --git a/egovframe-template-simple-react-contribution/src/pages/admin/board/AdminPostMgtEdit.jsx b/egovframe-template-simple-react-contribution/src/pages/admin/board/AdminPostMgtEdit.jsx index c12a9a8..49acd8f 100644 --- a/egovframe-template-simple-react-contribution/src/pages/admin/board/AdminPostMgtEdit.jsx +++ b/egovframe-template-simple-react-contribution/src/pages/admin/board/AdminPostMgtEdit.jsx @@ -13,7 +13,8 @@ import RichTextEditor from "../../../components/editor/RichTextEditor"; import AttachFile from "../../../components/file/AttachFile"; -function AdminPostMgtEdit({props, reloadFunction}) { +function AdminPostMgtEdit({props, reloadFunction, searchCondition}) { + console.log("@@@ searchCondition : " + JSON.stringify(searchCondition)); console.group("AdminPostMgtEdit"); console.log("[Start] AdminPostMgtEdit ------------------------------"); console.log("AdminPostMgtEdit [props] : ", props); @@ -28,14 +29,14 @@ function AdminPostMgtEdit({props, reloadFunction}) { item = props; console.log("@@@ item : " + JSON.stringify(item)); - const [modeInfo, setModeInfo] = useState(item != null ? {mode: props.mode} : {mode: CODE.MODE_CREATE}); + const [modeInfo, setModeInfo] = useState(props.selectedBbsSeq ? {mode: CODE.MODE_CREATE} : {mode: props.mode}); const [boardDetail, setBoardDetail] = useState({}); console.log("@@@ mode : " + modeInfo.mode); const [categoryList, setCategoryList] = useState([]); const retrieveList = useCallback(() => { - const retrieveListURL = '/admin/boards/get-category-and-file-list'; + const retrieveListURL = '/admin/boards/posts/get-category-and-file-list'; const requestOptions = { method: "POST", @@ -68,6 +69,7 @@ function AdminPostMgtEdit({props, reloadFunction}) { }, []); const initMode = () => { + console.log("@@@@@@@@@@"); if (modeInfo.mode === CODE.MODE_MODIFY) { setBoardDetail(item); setSelectedBbsSeq(props?.bbsSeq); @@ -82,7 +84,7 @@ function AdminPostMgtEdit({props, reloadFunction}) { formData.append('fixedYn', defaultFixedYn); formData.append('secretYn', defaultSecretYn); formData.append('bbsId', form.bbsId.value); - formData.append('bbsSeq', selectedBbsSeq); + formData.append('bbsSeq', selectedBbsSeq ? selectedBbsSeq : props.selectedBbsSeq); formData.append('bbsContTitle', form.bbsContTitle.value); formData.append('bbsContents', text); //첨부파일 @@ -100,7 +102,7 @@ function AdminPostMgtEdit({props, reloadFunction}) { formData.append('bbsContSeq', props.bbsContSeq); } EgovNet.requestFetch( - '/admin/boards/post-mgt', + '/admin/boards/posts/post-mgt', { method: "PUT", body: formData @@ -108,7 +110,7 @@ function AdminPostMgtEdit({props, reloadFunction}) { (resp) => { if (Number(resp.resultCode) === Number(CODE.RCV_SUCCESS)) { alert("저장되었습니다."); - reloadFunction(); + reloadFunction(searchCondition); } else if (Number(resp.resultCode) === Number(CODE.RCV_ERROR_AUTH)) { console.log("토큰 갱신중.") } else { @@ -121,7 +123,7 @@ function AdminPostMgtEdit({props, reloadFunction}) { function deletePost(post) { if (window.confirm("삭제하시겠습니까?")) { EgovNet.requestFetch( - '/admin/boards/post-mgt', + '/admin/boards/posts/post-mgt', { method: "DELETE", headers: { @@ -131,8 +133,7 @@ function AdminPostMgtEdit({props, reloadFunction}) { }, (resp) => { if (Number(resp.resultCode) === Number(CODE.RCV_SUCCESS)) { - alert("삭제되었습니다.") - reloadFunction(); + reloadFunction(searchCondition); } else if (Number(resp.resultCode) === Number(CODE.RCV_ERROR_AUTH)) { console.log("토큰 갱신중.") } else { @@ -149,12 +150,11 @@ function AdminPostMgtEdit({props, reloadFunction}) { const [defaultFixedYn, setDefaultFixedYn] = useState(props?.fixedYn || "N"); const [defaultSecretYn, setDefaultSecretYn] = useState(props?.secretYn || "N"); const [text, setText] = useState(props?.bbsContents); - const [selectedBbsSeq, setSelectedBbsSeq] = useState(null); + const [selectedBbsSeq, setSelectedBbsSeq] = useState(props?.selectedBbsSeq ? props?.selectedBbsSeq : props?.bbsSeq); const handleSelectChange = (e) => { - const selectedBbsId = e.target.value; - const selectedOption = categoryList.find((item) => item.bbsId === selectedBbsId); - setSelectedBbsSeq(selectedOption.bbsSeq); + const selectedBbsSeq = e.target.value; + setSelectedBbsSeq(selectedBbsSeq); } const fileTypes = ["JPG", "PNG", "GIF", "PDF", "HWP", "HWPX", "ZIP", "JPEG", "MP4", "TXT"]; @@ -201,37 +201,42 @@ function AdminPostMgtEdit({props, reloadFunction}) {
              { editPost(e) }} noValidate> -
              -
              필수
              -
              - setDefaultFixedYn(e.target.checked ? 'Y' : 'N')} - /> -
              -
              -
              -
              필수
              -
              - setDefaultSecretYn(e.target.checked ? 'Y' : 'N')} - /> -
              -
              + {selectedBbsSeq == '20' ? null : ( + <> +
              +
              필수
              +
              + setDefaultFixedYn(e.target.checked ? 'Y' : 'N')} + /> +
              +
              +
              +
              필수
              +
              + setDefaultSecretYn(e.target.checked ? 'Y' : 'N')} + /> +
              +
              + + )}
              필수
              {categoryList.map((item) => ( - + ))}
              @@ -249,30 +254,38 @@ function AdminPostMgtEdit({props, reloadFunction}) {
              -
              -
              필수
              -
              - -
              -
              + {selectedBbsSeq == '20' ? ( + <> +
              +
              +
              + 예시 이미지 +
              +
              + + ) : ( + <> +
              +
              필수
              +
              + +
              +
              + + )} {/* */}
              - {modeInfo.mode === CODE.MODE_MODIFY && - }
              - +
              {/* */} diff --git a/egovframe-template-simple-react-contribution/src/pages/admin/board/AdminPostMgtList.jsx b/egovframe-template-simple-react-contribution/src/pages/admin/board/AdminPostMgtList.jsx index 75cbf60..f19e52f 100644 --- a/egovframe-template-simple-react-contribution/src/pages/admin/board/AdminPostMgtList.jsx +++ b/egovframe-template-simple-react-contribution/src/pages/admin/board/AdminPostMgtList.jsx @@ -14,6 +14,7 @@ import AdminPostMgtEdit from "./AdminPostMgtEdit"; import Modal from "react-bootstrap/Modal"; import {format} from "date-fns"; import {Form} from "react-bootstrap"; +const fileIconPath = require('../../../css/images/ico_file.png'); function AdminPostMgtList(props) { console.group("EgovAdminPostList"); @@ -24,7 +25,7 @@ function AdminPostMgtList(props) { console.log("EgovAdminPostList [location] : ", location); // eslint-disable-next-line no-unused-vars - const [searchCondition, setSearchCondition] = useState(location.state?.searchCondition || { pageIndex: 1, searchCnd: '0', searchWrd: '' });// 기존 조회에서 접근 했을 시 || 신규로 접근 했을 시 + const [searchCondition, setSearchCondition] = useState(location.state?.searchCondition || { pageIndex: 1, searchCnd: '0', searchKeyword: '', bbsSeq:8 });// 기존 조회에서 접근 했을 시 || 신규로 접근 했을 시 const [paginationInfo, setPaginationInfo] = useState({}); const cndRef = useRef(); @@ -38,19 +39,19 @@ function AdminPostMgtList(props) { const handleClose = () => setShow(false); const handleShow = () => setShow(true); - const retrieveList = useCallback(() => { + const retrieveList = useCallback((searchCondition) => { handleClose(); + const params = EgovNet.convParams(searchCondition); console.groupCollapsed("EgovAdminPostList.retrieveList()"); - const retrieveListURL = '/admin/boards/post-list'; - + const retrieveListURL = '/admin/boards/posts/post-list' + params; + const requestOptions = { method: "GET", headers: { 'Content-type': 'application/json', - - }, - body: JSON.stringify() + + } } EgovNet.requestFetch(retrieveListURL, @@ -58,29 +59,42 @@ function AdminPostMgtList(props) { (resp) => { setPaginationInfo(resp.result.paginationInfo); setCategoryList(resp.result.categoryList); + console.log("@@@ resultCnt : " + resp.result.resultCnt); let mutListTag = []; - listTag.push(

              검색된 결과가 없습니다.

              ); // 게시판 목록 초기값 - - // 리스트 항목 구성 - resp.result.postList.forEach(function (item, index) { - if (index === 0) mutListTag = []; // 목록 초기화 - const finalModifiedDate = item.lastChgDt ? item.lastChgDt : item.frstCrtDt; + setListTag([]); + resp.result.fixedList.forEach(function (item) { + const finalModifiedDate = item?.lastChgDt ? item?.lastChgDt : item?.frstCrtDt; const formattedDate = finalModifiedDate ? format(finalModifiedDate, "yyyy-MM-dd HH:mm") : ""; - mutListTag.push(
              -
              -
              {item.bbsContTitle}
              -
              {item.frstCrtId}
              +
              공지
              +
              {item?.bbsContTitle}
              +
              {item?.bbsReadCnt}
              +
              {item?.fileGrpId && File Icon}
              +
              {item?.frstCrtId}
              {formattedDate}
              -
              {item.bbsReadCnt}
              -
              {item.fileGrpId}
              ); }); - + + resp.result.postList.forEach(function (item, index) { + const finalModifiedDate = item?.lastChgDt ? item?.lastChgDt : item?.frstCrtDt; + const formattedDate = finalModifiedDate ? format(finalModifiedDate, "yyyy-MM-dd HH:mm") : ""; + mutListTag.push( +
              +
              {resp.result.resultCnt - (resp.result.paginationInfo.pageIndex -1) * resp.result.paginationInfo.rowCnt - index}
              +
              {item?.bbsContTitle}
              +
              {item?.bbsReadCnt}
              +
              {item?.fileGrpId && File Icon}
              +
              {item?.frstCrtId}
              +
              {formattedDate}
              +
              +
              + ); + }); + if(!mutListTag.length) mutListTag.push(

              검색된 결과가 없습니다.

              ); // 게시판 목록 초기값 setListTag(mutListTag); }, function (resp) { @@ -88,15 +102,15 @@ function AdminPostMgtList(props) { } ); console.groupEnd("EgovAdminPostList.retrieveList()"); - },[listTag, searchCondition]); + },[listTag]); useEffect(() => { retrieveList(searchCondition); // eslint-disable-next-line react-hooks/exhaustive-deps - }, []); + }, [searchCondition]); const handleSelectChange = (e) => { - + setSearchCondition({...searchCondition, bbsSeq: e.target.value}) } function editPost(item){ @@ -104,7 +118,12 @@ function AdminPostMgtList(props) { if(item != undefined) { item.mode = CODE.MODE_MODIFY; } - setModalBody() + else { + item = {}; + item.mode = CODE.MODE_CREATE; + item.selectedBbsSeq = searchCondition.bbsSeq; + } + setModalBody( retrieveList(searchCondition)} searchCondition={searchCondition}/>) } console.log("------------------------------EgovAdminPostList [End]"); @@ -139,12 +158,11 @@ function AdminPostMgtList(props) {
              • - 검색유형선택 + 게시판선택 @@ -152,15 +170,9 @@ function AdminPostMgtList(props) {
              • 검색어 - { - wrdRef.current.value = e.target.value; - }} - /> - + {setSearchCondition({...searchCondition, searchKeyword: e.target.value})}}/> +
              @@ -168,14 +180,14 @@ function AdminPostMgtList(props) { {/* */} {/* */} -
              +
              - + 번호 제목 - 작성자 - 최종수정일 조회수 파일 + 작성자 + 작성일
              @@ -187,7 +199,7 @@ function AdminPostMgtList(props) {
              {/* */} { - retrieveList({ ...searchCondition, pageIndex: passedPage, searchCnd: cndRef.current.value, searchWrd: wrdRef.current.value }) + retrieveList({ ...searchCondition, pageIndex: passedPage}) //, searchCnd: cndRef.current.value, searchKeyword: wrdRef.current.value }} /> {/* */}
              diff --git a/egovframe-template-simple-react-contribution/src/pages/admin/board/EgovAdminBoardEdit.jsx b/egovframe-template-simple-react-contribution/src/pages/admin/board/EgovAdminBoardEdit.jsx index dea18ac..6b03968 100644 --- a/egovframe-template-simple-react-contribution/src/pages/admin/board/EgovAdminBoardEdit.jsx +++ b/egovframe-template-simple-react-contribution/src/pages/admin/board/EgovAdminBoardEdit.jsx @@ -32,9 +32,10 @@ function EgovAdminBoardEdit({props, reloadFunction}) { const [bbsTypeList, setBbsTypeList] = useState([]); const [roleList, setRoleList] = useState([]); + const [duplicateYn, setDuplicateYn] = useState(""); const retrieveList = useCallback(() => { - const retrieveListURL = '/admin/boards/get-option-list'; + const retrieveListURL = '/admin/boards/mgt/get-option-list'; const requestOptions = { method: "GET", @@ -72,6 +73,20 @@ function EgovAdminBoardEdit({props, reloadFunction}) { function editBoard(e) { e.preventDefault(); e.stopPropagation(); + + if (modeInfo.mode === CODE.MODE_CREATE) { + if (duplicateYn === "") { + alert("중복확인을 해주세요."); + return; + } else if (duplicateYn === "Y") { + alert("중복된 아이디 입니다."); + return; + } else if (duplicateYn === "C") { + alert("중복확인을 다시 해주세요."); + return; + } + } + const form = e.target; const info = { bbsId: form.bbsId.value, @@ -88,7 +103,7 @@ function EgovAdminBoardEdit({props, reloadFunction}) { info.bbsSeq = props.bbsSeq; } EgovNet.requestFetch( - '/admin/boards/board-mgt', + '/admin/boards/mgt/board-mgt', { method: "PUT", headers: { @@ -103,7 +118,7 @@ function EgovAdminBoardEdit({props, reloadFunction}) { } else if (Number(resp.resultCode) === Number(CODE.RCV_ERROR_AUTH)) { console.log("토큰 갱신중.") } else { - alert(resp.result.resultMessage) + alert(resp.resultMessage); } } ) @@ -112,7 +127,7 @@ function EgovAdminBoardEdit({props, reloadFunction}) { function deleteBoard(bbs){ if(window.confirm("삭제하시겠습니까?")) { EgovNet.requestFetch( - '/admin/boards/board-mgt', + '/admin/boards/mgt/board-mgt', { method: "DELETE", headers: { @@ -122,7 +137,6 @@ function EgovAdminBoardEdit({props, reloadFunction}) { }, (resp) => { if (Number(resp.resultCode) === Number(CODE.RCV_SUCCESS)) { - alert("삭제되었습니다.") reloadFunction(); } else if (Number(resp.resultCode) === Number(CODE.RCV_ERROR_AUTH)) { console.log("토큰 갱신중.") @@ -134,6 +148,44 @@ function EgovAdminBoardEdit({props, reloadFunction}) { } } + const handleInputChange = (e) => { + setDuplicateYn("C"); + }; + + const handleCheckDuplicate = () => { + const bbsId = document.querySelector('[name="bbsId"]').value; + if (!bbsId.trim()) { + alert("게시판 ID를 입력해주세요."); + return; + } + + const checkDuplicateURL = '/admin/boards/mgt/check-duplicate?bbsId=' + bbsId; + + const requestOptions = { + method: "GET", + headers: { + 'Content-type': 'application/json', + } + } + + EgovNet.requestFetch(checkDuplicateURL, + requestOptions, + (resp) => { + setDuplicateYn(resp.result.duplicateYn); + console.log("@@@ duplicateYn : " + JSON.stringify(resp.result.duplicateYn)); + if (resp.result.duplicateYn === "Y") { + alert("중복된 아이디 입니다."); + } + else if (resp.result.duplicateYn === "N") { + alert("사용 가능한 아이디 입니다."); + } + }, + function (resp) { + console.log("err response : ", resp); + } + ); + } + console.log("------------------------------EgovAdminBoardEdit [End]"); console.groupEnd("EgovAdminBoardEdit"); @@ -158,7 +210,12 @@ function EgovAdminBoardEdit({props, reloadFunction}) {
              필수
              + defaultValue={props?.bbsId} readOnly={modeInfo.mode === CODE.MODE_MODIFY} onChange={handleInputChange}/> +
              +
              + {modeInfo.mode !== CODE.MODE_MODIFY && ( + + )}
              @@ -179,7 +236,6 @@ function EgovAdminBoardEdit({props, reloadFunction}) {
              필수
              - {bbsTypeList.map((item) => ( ))} @@ -226,7 +282,7 @@ function EgovAdminBoardEdit({props, reloadFunction}) {
              필수
              - + {roleList.map((item) => ( ))} @@ -237,7 +293,6 @@ function EgovAdminBoardEdit({props, reloadFunction}) {
              필수
              - {roleList.map((item) => ( ))} @@ -248,15 +303,12 @@ function EgovAdminBoardEdit({props, reloadFunction}) { {/* */}
              - - {modeInfo.mode === CODE.MODE_MODIFY && - - } + {modeInfo.mode === CODE.MODE_MODIFY && ( + + )}
              -
              - +
              {/* */} diff --git a/egovframe-template-simple-react-contribution/src/pages/admin/boards/Keywords.jsx b/egovframe-template-simple-react-contribution/src/pages/admin/boards/Keywords.jsx deleted file mode 100644 index c485536..0000000 --- a/egovframe-template-simple-react-contribution/src/pages/admin/boards/Keywords.jsx +++ /dev/null @@ -1,185 +0,0 @@ -import React, {useState, useEffect, useCallback} from 'react'; -import {Link, useLocation} from 'react-router-dom'; - -import * as EgovNet from 'api/egovFetch'; -import URL from 'constants/url'; - -import {default as EgovLeftNav} from 'components/leftmenu/EgovLeftNavAdmin'; -import Modal from "react-bootstrap/Modal"; -import CODE from "../../../constants/code"; -import EgovAdminBoardEdit from "../board/EgovAdminBoardEdit"; -import {format} from "date-fns"; - -function StandardCodeMgt(props) { - - const location = useLocation(); - - const [searchCondition, setSearchCondition] = useState(location.state?.searchCondition || { pageIndex: 1, searchCnd: '0', searchWrd: '' });// 기존 조회에서 접근 했을 시 || 신규로 접근 했을 시 - const [paginationInfo, setPaginationInfo] = useState({}); - const [listTag, setListTag] = useState([]); - - const [show, setShow] = useState(false); - const [modalBody, setModalBody] = useState(); - const handleClose = () => setShow(false); - const handleShow = () => setShow(true); - - const retrieveList = useCallback(() => { - handleClose(); - console.groupCollapsed("AdminBoardList.retrieveList()"); - - const retrieveListURL = '/admin/boards/board-list'; - - const requestOptions = { - method: "GET", - headers: { - 'Content-type': 'application/json', - - }, - body: JSON.stringify() - } - - EgovNet.requestFetch(retrieveListURL, - requestOptions, - (resp) => { - - let mutListTag = []; - listTag.push(

              검색된 결과가 없습니다.

              ); // 게시판 목록 초기값 - - // 리스트 항목 구성 - resp.result.boardList.forEach(function (item, index) { - if (index === 0) mutListTag = []; // 목록 초기화 - - mutListTag.push( -
              -
              {item.bbsSeq}
              -
              {item.bbsId}
              -
              {item.bbsTitle}
              -
              {item.frstCrtId}
              -
              {item.frstCrtDt ? format(item.frstCrtDt, "yyyy-MM-dd HH:mm") : ""}
              -
              {item.lastChgDt ? format(item.lastChgDt, "yyyy-MM-dd HH:mm") : ""}
              -
              -
              - ); - }); - - setListTag(mutListTag); - console.log("@@@ resp : "); - }, - function (resp) { - console.log("err response : ", resp); - } - ); - console.groupEnd("EgovAdminBoardList.retrieveList()"); - },[]); - - useEffect(() => { - retrieveList(searchCondition); - // eslint-disable-next-line react-hooks/exhaustive-deps - }, []); - - function editBoard(item){ - handleShow(); - if(item != undefined) { - item.mode = CODE.MODE_MODIFY; - } - setModalBody() - } - - return ( -
              -
              - {/* */} -
              -
                -
              • Home
              • -
              • 사이트관리
              • -
              • 게시판현황
              • -
              • 키워드 관리
              • -
              -
              - {/* */} - -
              - {/* */} - - {/* */} - -
              -
              -

              사이트관리

              -
              -

              키워드 관리

              - {/* */} - {/*
              -
                -
              • - 검색유형선택 - -
              • -
              • - 검색어 - - { - wrdRef.current.value = e.target.value; - }} - /> - - -
              • -
              • - 등록 -
              • -
              -
              */} - {/* */} - - {/* */} -
              -
              - 번호 - 아이디 - 제목 - 작성자 - 작성일 - 수정일 - -
              -
              - {listTag} -
              -
              - {/* */} - -
              - {/* */} - {/* { - retrieveList({ ...searchCondition, pageIndex: passedPage, searchCnd: cndRef.current.value, searchWrd: wrdRef.current.value }) - }} />*/} - {/* */} -
              - - {/* */} -
              -
              -
              - - {modalBody} - -
              - ); -} - -export default StandardCodeMgt; \ No newline at end of file diff --git a/egovframe-template-simple-react-contribution/src/pages/admin/boards/List.jsx b/egovframe-template-simple-react-contribution/src/pages/admin/boards/List.jsx index 27d39a3..b9258da 100644 --- a/egovframe-template-simple-react-contribution/src/pages/admin/boards/List.jsx +++ b/egovframe-template-simple-react-contribution/src/pages/admin/boards/List.jsx @@ -32,7 +32,7 @@ function EgovAdminBoardList(props) { handleClose(); console.groupCollapsed("AdminBoardList.retrieveList()"); - const retrieveListURL = '/admin/boards/board-list'; + const retrieveListURL = '/admin/boards/mgt/board-list'; const requestOptions = { method: "GET", @@ -58,7 +58,6 @@ function EgovAdminBoardList(props) { mutListTag.push(
              -
              {item.bbsId}
              {item.bbsTitle}
              {item.frstCrtId}
              @@ -122,7 +121,6 @@ function EgovAdminBoardList(props) { {/* */}
              - 아이디 제목 작성자 diff --git a/egovframe-template-simple-react-contribution/src/pages/admin/committee/ProgressStatus/Edit.jsx b/egovframe-template-simple-react-contribution/src/pages/admin/committee/ProgressStatus/Edit.jsx index 1cc4804..de58317 100644 --- a/egovframe-template-simple-react-contribution/src/pages/admin/committee/ProgressStatus/Edit.jsx +++ b/egovframe-template-simple-react-contribution/src/pages/admin/committee/ProgressStatus/Edit.jsx @@ -224,7 +224,7 @@ function ProgressStatusEdit(props) { const getList = (orgSearchCondition) => { - EgovNet.requestFetch(`/admin/config/committee-code-management?paramCodeGroup=${orgSearchCondition.paramCodeGroup}¶mCodeLevel=${orgSearchCondition.paramCodeLevel}`, + EgovNet.requestFetch(`/admin/config/committee-code-mgt?paramCodeGroup=${orgSearchCondition.paramCodeGroup}¶mCodeLevel=${orgSearchCondition.paramCodeLevel}`, requestOptions, function (resp) { const myIndex = Number(String(orgSearchCondition.paramCodeLevel).replace('LV_','')) - 1; diff --git a/egovframe-template-simple-react-contribution/src/pages/admin/config/AboutSiteMgt.jsx b/egovframe-template-simple-react-contribution/src/pages/admin/config/AboutSiteMgt.jsx index 3bf6bab..725e5d9 100644 --- a/egovframe-template-simple-react-contribution/src/pages/admin/config/AboutSiteMgt.jsx +++ b/egovframe-template-simple-react-contribution/src/pages/admin/config/AboutSiteMgt.jsx @@ -5,9 +5,11 @@ import * as EgovNet from 'api/egovFetch'; import URL from 'constants/url'; import { default as EgovLeftNav } from 'components/leftmenu/EgovLeftNavAdmin'; -import CODE from "../../../constants/code"; +import CODE from "constants/code"; import Modal from "react-bootstrap/Modal"; import AboutSiteModal from "./aboutSiteMgt/AboutSiteModal"; +import {Image} from "react-bootstrap"; +import {SERVER_URL} from "config"; function StandardCodeMgt(props) { @@ -26,7 +28,7 @@ function StandardCodeMgt(props) { handleClose(); console.groupCollapsed("AdminPartnerSiteList.retrieveList()"); - const retrieveListURL = '/admin/config/partner-site-list'; + const retrieveListURL = '/admin/config/about-site-mgt/list'; const requestOptions = { method: "GET", @@ -50,10 +52,9 @@ function StandardCodeMgt(props) { mutListTag.push(
              -
              {item.siteTitle}
              {item.siteUrl}
              -
              {item.fileGrpId}
              +
              이미지 window.open(e.target.src)} width={"150"}/>
              {item.siteOrder}
              {item.useYn}
              @@ -147,7 +148,6 @@ function StandardCodeMgt(props) { {/* */}
              - 사이트명 URL 배너이미지 diff --git a/egovframe-template-simple-react-contribution/src/pages/admin/config/CommitteeCodeMgt.jsx b/egovframe-template-simple-react-contribution/src/pages/admin/config/CommitteeCodeMgt.jsx index c989b44..ef564cf 100644 --- a/egovframe-template-simple-react-contribution/src/pages/admin/config/CommitteeCodeMgt.jsx +++ b/egovframe-template-simple-react-contribution/src/pages/admin/config/CommitteeCodeMgt.jsx @@ -111,7 +111,7 @@ function CommitteeCodeMgt(props) { const getList = (searchCondition) => { - EgovNet.requestFetch(`/admin/config/committee-code-management?paramCodeGroup=${searchCondition.paramCodeGroup}¶mCodeLevel=${searchCondition.paramCodeLevel}`, + EgovNet.requestFetch(`/admin/config/committee-code-mgt?paramCodeGroup=${searchCondition.paramCodeGroup}¶mCodeLevel=${searchCondition.paramCodeLevel}`, requestOptions, function (resp) { if( searchCondition.paramCodeLevel === 'LV_01' ) { @@ -163,7 +163,7 @@ function CommitteeCodeMgt(props) { const requestTask = () => { - EgovNet.requestFetch(`/admin/config/committee-code-management/${deleteItem.orgId}`, + EgovNet.requestFetch(`/admin/config/committee-code-mgt/${deleteItem.orgId}`, requestOptions, function (resp) { let forChangeObject = {...searchCondition, paramCodeGroup, paramCodeLevel}; diff --git a/egovframe-template-simple-react-contribution/src/pages/admin/config/CommitteeCodeMgt/CommitteeCodeRegistrationPopup.jsx b/egovframe-template-simple-react-contribution/src/pages/admin/config/CommitteeCodeMgt/CommitteeCodeRegistrationPopup.jsx index 7422b46..6b15293 100644 --- a/egovframe-template-simple-react-contribution/src/pages/admin/config/CommitteeCodeMgt/CommitteeCodeRegistrationPopup.jsx +++ b/egovframe-template-simple-react-contribution/src/pages/admin/config/CommitteeCodeMgt/CommitteeCodeRegistrationPopup.jsx @@ -95,7 +95,7 @@ function CommitteeCodeRegistrationPopup(props) { if( props.createOrModifyCondition.mode === CODE.MODE_MODIFY ) { appendRequestURL = `/${props.createOrModifyCondition.target.orgId}`; } - const requestURL = "/admin/config/committee-code-management" + appendRequestURL; + const requestURL = "/admin/config/committee-code-mgt" + appendRequestURL; EgovNet.requestFetch(requestURL, requestOptions, function (resp) { diff --git a/egovframe-template-simple-react-contribution/src/pages/admin/config/MenuAuthMgt.jsx b/egovframe-template-simple-react-contribution/src/pages/admin/config/MenuAuthMgt.jsx index 4d498a1..fd7a434 100644 --- a/egovframe-template-simple-react-contribution/src/pages/admin/config/MenuAuthMgt.jsx +++ b/egovframe-template-simple-react-contribution/src/pages/admin/config/MenuAuthMgt.jsx @@ -33,16 +33,24 @@ function MenuAuthMgt(props) { roleList.forEach(function (role) { checkboxs.push(
              - { - const checked = e.target.checked; - if(checked) { - item.menuAuth += ","+role.itemCd - }else{ - item.menuAuth = item.menuAuth.replace(","+role.itemCd, ''); - } - }} - defaultChecked={item.menuAuth.includes(role.itemCd)}/> + {role.itemCd === "ROLE_001"? + () + : + ({ + const checked = e.target.checked; + if(checked) { + item.menuAuth += ","+role.itemCd + }else{ + item.menuAuth = item.menuAuth.replace(role.itemCd, ''); + if(item.menuAuth.startsWith(",")) { + item.menuAuth.replace(",", "") + } + } + }} + defaultChecked={item.menuAuth.includes(role.itemCd)} />) + }
              ) /*if(item.menuGroup){ diff --git a/egovframe-template-simple-react-contribution/src/pages/admin/config/aboutSiteMgt/AboutSiteModal.jsx b/egovframe-template-simple-react-contribution/src/pages/admin/config/aboutSiteMgt/AboutSiteModal.jsx index 371d331..e6d54be 100644 --- a/egovframe-template-simple-react-contribution/src/pages/admin/config/aboutSiteMgt/AboutSiteModal.jsx +++ b/egovframe-template-simple-react-contribution/src/pages/admin/config/aboutSiteMgt/AboutSiteModal.jsx @@ -19,6 +19,7 @@ function AboutSiteModal({props, reloadFunction}) { const navigate = useNavigate(); const location = useLocation(); const checkRef = useRef([]); + const fileInputRef = useRef(null); console.log("AboutSiteModal [location] : ", location); @@ -32,7 +33,18 @@ function AboutSiteModal({props, reloadFunction}) { useEffect(() => { initMode(); - // eslint-disable-next-line react-hooks/exhaustive-deps + const fileDOM = document.querySelector('#file'); + const preview = document.querySelector('.preview'); + + if(fileDOM) { + fileDOM.addEventListener('change', () => { + const reader = new FileReader(); + reader.onload = ({target}) => { + preview.src = target.result; + }; + reader.readAsDataURL(fileDOM.files[0]); + }); + } }, []); const initMode = () => { @@ -45,24 +57,22 @@ function AboutSiteModal({props, reloadFunction}) { e.preventDefault(); e.stopPropagation(); const form = e.target; - const info = { - siteTitle: form.siteTitle.value, - siteUrl: form.siteUrl.value, - fileGrpId: form.fileGrpId.value, - siteOrder: form.siteOrder.value, - useYn: form.useYn.value - } + const formData = new FormData(form); // 새 FormData 객체 생성 + + // FormData 객체에 파일 데이터 추가 + console.log("@@@ current : " + fileInputRef.current); + console.log("@@@ file : " + fileInputRef.current.files[0]); + formData.append('file', currentFile); + if (modeInfo.mode === CODE.MODE_MODIFY) { - info.siteSeq = props.siteSeq; + formData.append('siteSeq', props.siteSeq); // 수정 모드일 때 필요한 추가 정보 추가 + formData.append('fileGrpId', props.fileGrpId); } EgovNet.requestFetch( - '/admin/config/partner-site-mgt', + '/admin/config/about-site-mgt/partner-site-mgt', { method: "PUT", - headers: { - 'Content-type': 'application/json' - }, - body: JSON.stringify(info) + body: formData }, (resp) => { if (Number(resp.resultCode) === Number(CODE.RCV_SUCCESS)) { @@ -80,7 +90,7 @@ function AboutSiteModal({props, reloadFunction}) { function deletePartnerSite(partnerSite){ if(window.confirm("삭제하시겠습니까?")) { EgovNet.requestFetch( - '/admin/config/partner-site-mgt', + '/admin/config/about-site-mgt/partner-site-mgt', { method: "DELETE", headers: { @@ -102,6 +112,100 @@ function AboutSiteModal({props, reloadFunction}) { } } + const Logo = () => ( + + + + + ) + + const [currentFile, setCurrentFile] = useState(null); + const [uploadedInfo, setUploadedInfo] = useState(null); + const [previewImage, setPreviewImage] = useState(null); + + const UploadBox = () => { + const [isActive, setActive] = useState(false); + + const onDragEnter = (e: React.DragEvent) => { + e.preventDefault(); + e.stopPropagation(); + }; + const onDragLeave = (e: React.DragEvent) => { + e.preventDefault(); + e.stopPropagation(); + }; + const onDragOver = (e: React.DragEvent) => { + e.preventDefault(); + e.stopPropagation(); + }; + + const setFileInfo = (file) => { + const { name, size: byteSize, type } = file; + const isImage = type.includes('image'); + const size = (byteSize / (1024 * 1024)).toFixed(2) + 'mb'; + setUploadedInfo({ name, size, type }); // name, size, type 정보를 uploadedInfo에 저장 + + if (!isImage) { + setUploadedInfo({ name, size, type }); + return; + } + const reader = new FileReader(); + reader.onload = () => { + setPreviewImage(reader.result); + setUploadedInfo({ name, size, type, imageUrl: String(reader.result) }); + }; + reader.readAsDataURL(file); + }; + + const onDrop = (e: React.DragEvent) => { + e.preventDefault(); + e.stopPropagation(); + setActive(false); + + const droppedFile = e.dataTransfer.files[0]; + console.log("@@@ handleDrop file : " + droppedFile); + if (droppedFile.type.startsWith('image/')) { + setCurrentFile(droppedFile); + setFileInfo(droppedFile); + } else { + // 이미지 파일이 아닌 경우에 대한 처리 + alert('이미지 파일만 업로드할 수 있습니다.'); + } + }; + + const handleUpload = (e: ChangeEvent) => { + const file = e.target.files[0]; + console.log("@@@ handleUpload file : " + file); + if (file.type.startsWith('image/')) { + setCurrentFile(file); + setFileInfo(file); + } else { + // 이미지 파일이 아닌 경우에 대한 처리 + alert('이미지 파일만 업로드할 수 있습니다.'); + } + }; + + return ( + + ); + }; + console.log("------------------------------AboutSiteModal [End]"); console.groupEnd("AboutSiteModal"); @@ -118,6 +222,7 @@ function AboutSiteModal({props, reloadFunction}) { +
              {editPartnerSite(e)}} noValidate>
              @@ -134,18 +239,15 @@ function AboutSiteModal({props, reloadFunction}) { defaultValue={props?.siteUrl}/>
              -
              -
              필수
              -
              - -
              -
              필수
              + defaultValue={props?.siteOrder} onChange={(e) => { + const inputValue = e.target.value; + const numericValue = inputValue.replace(/\D/g, ''); + e.target.value = numericValue; + }}/>
              diff --git a/egovframe-template-simple-react-contribution/src/pages/admin/config/baseCode/ChildCodeDiv.jsx b/egovframe-template-simple-react-contribution/src/pages/admin/config/baseCode/ChildCodeDiv.jsx index 150d5ec..88c3fa7 100644 --- a/egovframe-template-simple-react-contribution/src/pages/admin/config/baseCode/ChildCodeDiv.jsx +++ b/egovframe-template-simple-react-contribution/src/pages/admin/config/baseCode/ChildCodeDiv.jsx @@ -20,7 +20,7 @@ function ChildCodeDiv({}, ref){ setCodeItemRow([]); setGrpCd(parentCd) EgovNet.requestFetch( - '/admin/config/code-item?grpCd='+parentCd, + '/admin/config/base-code-mgt/code-item?grpCd='+parentCd, { method: "GET" }, @@ -54,7 +54,7 @@ function ChildCodeDiv({}, ref){ alert("코드와 코드명을 입력해주세요.") }else{ EgovNet.requestFetch( - '/admin/config/code-item', + '/admin/config/base-code-mgt/code-item', { method: "POST", headers: { @@ -99,7 +99,7 @@ function ChildCodeDiv({}, ref){ useYn: action==="modify"?'Y':'N' } EgovNet.requestFetch( - '/admin/config/code-item', + '/admin/config/base-code-mgt/code-item', { method: "PUT", headers: { @@ -125,7 +125,7 @@ function ChildCodeDiv({}, ref){ } return ( - +
              코드 @@ -152,7 +152,7 @@ function ChildCodeDiv({}, ref){ 코드 그룹을 선택해주세요. )} - +
              ); } diff --git a/egovframe-template-simple-react-contribution/src/pages/admin/config/baseCode/ParentCodeDiv.jsx b/egovframe-template-simple-react-contribution/src/pages/admin/config/baseCode/ParentCodeDiv.jsx index 8d1e5de..2a8b9aa 100644 --- a/egovframe-template-simple-react-contribution/src/pages/admin/config/baseCode/ParentCodeDiv.jsx +++ b/egovframe-template-simple-react-contribution/src/pages/admin/config/baseCode/ParentCodeDiv.jsx @@ -14,7 +14,7 @@ function ParentCodeDiv({getCodeItem}){ const getCodeGrp = useCallback(()=>{ EgovNet.requestFetch( - '/admin/config/code-grp', + '/admin/config/base-code-mgt/code-grp', { method: "GET" }, @@ -62,7 +62,7 @@ function ParentCodeDiv({getCodeItem}){ alert("코드 그룹을 입력해주세요.") }else{ EgovNet.requestFetch( - '/admin/config/code-grp', + '/admin/config/base-code-mgt/code-grp', { method: "POST", headers: { @@ -102,7 +102,7 @@ function ParentCodeDiv({getCodeItem}){ useYn: action==="modify"?'Y':'N' } EgovNet.requestFetch( - '/admin/config/code-grp', + '/admin/config/base-code-mgt/code-grp', { method: "PUT", headers: { @@ -129,7 +129,7 @@ function ParentCodeDiv({getCodeItem}){ } return ( - +
              코드그룹 코드그룹명 @@ -146,7 +146,7 @@ function ParentCodeDiv({getCodeItem}){ - +
              ); } diff --git a/egovframe-template-simple-react-contribution/src/pages/admin/contents/Survey.jsx b/egovframe-template-simple-react-contribution/src/pages/admin/contents/Survey.jsx index 530d364..b72e1d4 100644 --- a/egovframe-template-simple-react-contribution/src/pages/admin/contents/Survey.jsx +++ b/egovframe-template-simple-react-contribution/src/pages/admin/contents/Survey.jsx @@ -23,7 +23,7 @@ function Survey({}) { const retrieveList = useCallback(() => { handleClose() EgovNet.requestFetch( - '/admin/survey/list', + '/admin/contents/survey/list', { method: "GET" }, @@ -58,7 +58,7 @@ function Survey({}) { function editUseYn(svySeq){ EgovNet.requestFetch( - '/admin/survey/info-use-yn', + '/admin/contents/survey/info-use-yn', { method: "PUT", headers: { diff --git a/egovframe-template-simple-react-contribution/src/pages/admin/contents/survey/QuestionModal.jsx b/egovframe-template-simple-react-contribution/src/pages/admin/contents/survey/QuestionModal.jsx index e5af92b..f30cce7 100644 --- a/egovframe-template-simple-react-contribution/src/pages/admin/contents/survey/QuestionModal.jsx +++ b/egovframe-template-simple-react-contribution/src/pages/admin/contents/survey/QuestionModal.jsx @@ -15,7 +15,7 @@ function QuestionModal({svySeq}){ function getSurveyQt(){ EgovNet.requestFetch( - '/admin/survey/info-qt?svySeq='+svySeq, + '/admin/contents/survey/info-qt?svySeq='+svySeq, { method: "GET" }, @@ -77,7 +77,7 @@ function QuestionModal({svySeq}){ function editSurveyQt(e){ EgovNet.requestFetch( - '/admin/survey/info-qt', + '/admin/contents/survey/info-qt', { method: "PUT", headers: { diff --git a/egovframe-template-simple-react-contribution/src/pages/admin/contents/survey/SurveyModal.jsx b/egovframe-template-simple-react-contribution/src/pages/admin/contents/survey/SurveyModal.jsx index 0234b73..906f540 100644 --- a/egovframe-template-simple-react-contribution/src/pages/admin/contents/survey/SurveyModal.jsx +++ b/egovframe-template-simple-react-contribution/src/pages/admin/contents/survey/SurveyModal.jsx @@ -21,7 +21,7 @@ function SurveyModal({savedInfo, reloadFunction}){ e.preventDefault(); e.stopPropagation(); EgovNet.requestFetch( - '/admin/survey/info', + '/admin/contents/survey/info', { method: "PUT", headers: { @@ -44,7 +44,7 @@ function SurveyModal({savedInfo, reloadFunction}){ e.preventDefault(); e.stopPropagation(); EgovNet.requestFetch( - '/admin/survey/info', + '/admin/contents/survey/info', { method: "DELETE", headers: { diff --git a/egovframe-template-simple-react-contribution/src/pages/admin/logs/FileDownloadStatus.jsx b/egovframe-template-simple-react-contribution/src/pages/admin/logs/FileDownloadStatus.jsx index 2fe065b..70a3c57 100644 --- a/egovframe-template-simple-react-contribution/src/pages/admin/logs/FileDownloadStatus.jsx +++ b/egovframe-template-simple-react-contribution/src/pages/admin/logs/FileDownloadStatus.jsx @@ -55,7 +55,7 @@ function FileConnections(props) { const retrieveList = useCallback((srchCnd) => { // console.groupCollapsed("EgovAdminUsageList.retrieveList()"); - const retrieveListURL = '/admin/logs/file'; + const retrieveListURL = '/admin/logs/file-download-status'; const requestOptions = { method: "POST", diff --git a/egovframe-template-simple-react-contribution/src/pages/admin/logs/MenuAccessInfo.jsx b/egovframe-template-simple-react-contribution/src/pages/admin/logs/MenuAccessInfo.jsx index 3a75376..a1a5ae6 100644 --- a/egovframe-template-simple-react-contribution/src/pages/admin/logs/MenuAccessInfo.jsx +++ b/egovframe-template-simple-react-contribution/src/pages/admin/logs/MenuAccessInfo.jsx @@ -36,7 +36,7 @@ function MenuConnections(props) { const retrieveList = useCallback((srchCnd) => { // console.groupCollapsed("EgovAdminUsageList.retrieveList()"); - const retrieveListURL = '/admin/logs/menu'; + const retrieveListURL = '/admin/logs/menu-access-info'; const requestOptions = { method: "POST", diff --git a/egovframe-template-simple-react-contribution/src/pages/admin/logs/PrivacyLogs.jsx b/egovframe-template-simple-react-contribution/src/pages/admin/logs/PrivacyLogs.jsx index 1d633ef..48a1c40 100644 --- a/egovframe-template-simple-react-contribution/src/pages/admin/logs/PrivacyLogs.jsx +++ b/egovframe-template-simple-react-contribution/src/pages/admin/logs/PrivacyLogs.jsx @@ -30,7 +30,7 @@ function PrivacyConnections(props) { const retrieveList = useCallback((srchCnd) => { // console.groupCollapsed("EgovAdminUsageList.retrieveList()"); - const retrieveListURL = '/admin/logs/privacy'; + const retrieveListURL = '/admin/logs/privacy-logs'; const requestOptions = { method: "POST", diff --git a/egovframe-template-simple-react-contribution/src/pages/admin/logs/UserConnections.jsx b/egovframe-template-simple-react-contribution/src/pages/admin/logs/UserConnections.jsx index bcb57c9..7f1d236 100644 --- a/egovframe-template-simple-react-contribution/src/pages/admin/logs/UserConnections.jsx +++ b/egovframe-template-simple-react-contribution/src/pages/admin/logs/UserConnections.jsx @@ -35,7 +35,7 @@ function UserConnections(props) { const retrieveList = useCallback((srchCnd) => { // console.groupCollapsed("EgovAdminUsageList.retrieveList()"); - const retrieveListURL = '/admin/logs/user'; + const retrieveListURL = '/admin/logs/user-connections'; const requestOptions = { method: "POST", diff --git a/egovframe-template-simple-react-contribution/src/pages/admin/standards/ApiKeys.jsx b/egovframe-template-simple-react-contribution/src/pages/admin/standards/ApiKeys.jsx index 3475d31..a75f909 100644 --- a/egovframe-template-simple-react-contribution/src/pages/admin/standards/ApiKeys.jsx +++ b/egovframe-template-simple-react-contribution/src/pages/admin/standards/ApiKeys.jsx @@ -32,7 +32,7 @@ function ApiKeys(props) { const retrieveList = useCallback((srchCnd) => { // console.groupCollapsed("EgovAdminUsageList.retrieveList()"); - const retrieveListURL = '/admin/standards/apikey'; + const retrieveListURL = '/admin/standards/api-keys'; const requestOptions = { method: "POST", @@ -95,7 +95,7 @@ function ApiKeys(props) { const handleSwitchToggle = async (item) => { try { - const updateApiEndpoint = '/admin/standards/apiupdate'; + const updateApiEndpoint = '/admin/standards/api-keys/api-update'; const requestOptions = { method: 'POST', headers: { @@ -122,7 +122,7 @@ function ApiKeys(props) { const handleApiKeyChart = (item) => { try { - const updateApiEndpoint = '/admin/standards/apiDailyChart'; + const updateApiEndpoint = '/admin/standards/api-keys/api-daily-chart'; const requestOptions = { method: 'POST', headers: { diff --git a/egovframe-template-simple-react-contribution/src/pages/admin/users/List.jsx b/egovframe-template-simple-react-contribution/src/pages/admin/users/List.jsx index 39e9d00..be26d13 100644 --- a/egovframe-template-simple-react-contribution/src/pages/admin/users/List.jsx +++ b/egovframe-template-simple-react-contribution/src/pages/admin/users/List.jsx @@ -20,9 +20,7 @@ function List({}) { }); const [listTag, setListTag] = useState([]); - const [paginationInfo, setPaginationInfo] = useState({}); - const [show, setShow] = useState(false); const [modalBody, setModalBody] = useState(); @@ -32,7 +30,7 @@ function List({}) { const retrieveList = useCallback((searchCondition) => { const params = EgovNet.convParams(searchCondition); EgovNet.requestFetch( - '/admin/users/list'+params, + '/admin/users/mgt/list'+params, { method: "GET" }, @@ -42,13 +40,15 @@ function List({}) { setListTag([]); // 리스트 항목 구성 + const cmtList = resp.result.cmtList; resp.result.userList.forEach(function (item, index) { mutListTag.push(
              - +
              {item.userNm}
              {item.email}
              {item.phoneNum}
              +
              {item.cmtOrgNm}
              {item.statusValue}
              @@ -72,15 +72,15 @@ function List({}) { setSearchCondition({...searchCondition, pageIndex: passedPage}) }); - function userInfoModal(userInfo){ + function userInfoModal(userInfo, cmtList){ handleShow() - setModalBody() + setModalBody() } const removeUserInfo = useCallback((seq)=>{ if(window.confirm("삭제하시겠습니까?\n복구할 수 없습니다.")){ EgovNet.requestFetch( - '/admin/users/info', + '/admin/users/mgt/info', { method: "DELETE", headers: { @@ -151,6 +151,7 @@ function List({}) { 이름 이메일 연락처 + 위원회 상태 삭제
              diff --git a/egovframe-template-simple-react-contribution/src/pages/admin/users/UserInfoModal.jsx b/egovframe-template-simple-react-contribution/src/pages/admin/users/UserInfoModal.jsx index 2d54780..2b676f8 100644 --- a/egovframe-template-simple-react-contribution/src/pages/admin/users/UserInfoModal.jsx +++ b/egovframe-template-simple-react-contribution/src/pages/admin/users/UserInfoModal.jsx @@ -1,4 +1,4 @@ -import React, {useCallback, useEffect, useState} from "react" +import React, {useEffect, useState} from "react" import Modal from "react-bootstrap/Modal"; import * as EgovNet from "api/egovFetch"; import Form from "react-bootstrap/Form"; @@ -6,11 +6,12 @@ import Row from "react-bootstrap/Row"; import Col from "react-bootstrap/Col"; 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({savedInfo, reloadFunction}){ - +function UserInfoModal({savedInfo, cmtList, reloadFunction}){ + const [selectedCmtList, setSelectedCmtList] = useState(cmtList); + const [cmtOrg, setCmtOrg] = useState({cmtSeq: savedInfo?.cmtOrg, cmtNm: savedInfo?.cmtOrgNm}); + function userInfoChange(e){ e.preventDefault(); e.stopPropagation(); @@ -23,20 +24,12 @@ function UserInfoModal({savedInfo, reloadFunction}){ userNm: form.userNm.value, email: form.email.value, phoneNum: form.phoneNum.value, - userRole: '', + userRole: form.userRole.value, + cmtOrg: form.cmtOrg.value, 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', + '/admin/users/mgt/info', { method: "PUT", headers: { @@ -56,10 +49,21 @@ function UserInfoModal({savedInfo, reloadFunction}){ } ) } - - function modalOpen(){ + const changeSelectorOption = (e) => { + selectedCmtList.forEach(function (cmt){ + if(cmt.cmtSeq === Number(e.target.value)){ + setCmtOrg({cmtSeq: cmt.cmtSeq, cmtNm: cmt.cmtNm}); + if(cmt.childList.length === 0){ + setSelectedCmtList(cmtList); + }else{ + setSelectedCmtList(cmt.childList); + } + } + }) + } + /*function modalOpen(){ EgovNet.requestFetch( - '/admin/users/info?userId='+savedInfo?.userId, + '/admin/users/mgt/info?userId='+savedInfo?.userId, { method: "GET", headers: { @@ -70,10 +74,10 @@ function UserInfoModal({savedInfo, reloadFunction}){ } ) - } + }*/ useEffect(() => { - modalOpen(); + /*modalOpen();*/ }, []); return ( @@ -99,7 +103,7 @@ function UserInfoModal({savedInfo, reloadFunction}){ 비밀번호 - + @@ -139,7 +143,23 @@ function UserInfoModal({savedInfo, reloadFunction}){ 사용자 권한 - + {/**/} + + + + + + 위원회 + + + + + + + {selectedCmtList.map((cmt) => ( + + ))} + diff --git a/egovframe-template-simple-react-contribution/src/pages/committee/Progress.jsx b/egovframe-template-simple-react-contribution/src/pages/committee/Progress.jsx new file mode 100644 index 0000000..925c320 --- /dev/null +++ b/egovframe-template-simple-react-contribution/src/pages/committee/Progress.jsx @@ -0,0 +1,14 @@ +import React, { useState } from 'react'; +import {Link, useLocation, useNavigate} from 'react-router-dom'; +import * as EgovNet from 'api/egovFetch'; + +function Progress(){ + + + + return ( +
              위원회 - 진행현황
              + ); +} + +export default Progress; \ No newline at end of file diff --git a/egovframe-template-simple-react-contribution/src/pages/committee/Schedule.jsx b/egovframe-template-simple-react-contribution/src/pages/committee/Schedule.jsx new file mode 100644 index 0000000..512f222 --- /dev/null +++ b/egovframe-template-simple-react-contribution/src/pages/committee/Schedule.jsx @@ -0,0 +1,14 @@ +import React, { useState } from 'react'; +import {Link, useLocation, useNavigate} from 'react-router-dom'; +import * as EgovNet from 'api/egovFetch'; + +function Schedule(){ + + + + return ( +
              위원회 - 위원회일정
              + ); +} + +export default Schedule; \ No newline at end of file diff --git a/egovframe-template-simple-react-contribution/src/pages/inform/Email.jsx b/egovframe-template-simple-react-contribution/src/pages/inform/Email.jsx new file mode 100644 index 0000000..b1a5226 --- /dev/null +++ b/egovframe-template-simple-react-contribution/src/pages/inform/Email.jsx @@ -0,0 +1,14 @@ +import React, { useState } from 'react'; +import {Link, useLocation, useNavigate} from 'react-router-dom'; +import * as EgovNet from 'api/egovFetch'; + +function Email(){ + + + + return ( +
              이메일 무단수집 거부
              + ); +} + +export default Email; \ No newline at end of file diff --git a/egovframe-template-simple-react-contribution/src/pages/inform/Private.jsx b/egovframe-template-simple-react-contribution/src/pages/inform/Private.jsx new file mode 100644 index 0000000..8a3ea2e --- /dev/null +++ b/egovframe-template-simple-react-contribution/src/pages/inform/Private.jsx @@ -0,0 +1,14 @@ +import React, { useState } from 'react'; +import {Link, useLocation, useNavigate} from 'react-router-dom'; +import * as EgovNet from 'api/egovFetch'; + +function Private(){ + + + + return ( +
              개인정보처리방침
              + ); +} + +export default Private; \ No newline at end of file diff --git a/egovframe-template-simple-react-contribution/src/pages/inform/Sitemap.jsx b/egovframe-template-simple-react-contribution/src/pages/inform/Sitemap.jsx new file mode 100644 index 0000000..349d697 --- /dev/null +++ b/egovframe-template-simple-react-contribution/src/pages/inform/Sitemap.jsx @@ -0,0 +1,14 @@ +import React, { useState } from 'react'; +import {Link, useLocation, useNavigate} from 'react-router-dom'; +import * as EgovNet from 'api/egovFetch'; + +function Sitemap(){ + + + + return ( +
              사이트맵
              + ); +} + +export default Sitemap; \ No newline at end of file diff --git a/egovframe-template-simple-react-contribution/src/pages/login/EgovLogin.jsx b/egovframe-template-simple-react-contribution/src/pages/login/EgovLogin.jsx index 3fe6b90..2e24093 100644 --- a/egovframe-template-simple-react-contribution/src/pages/login/EgovLogin.jsx +++ b/egovframe-template-simple-react-contribution/src/pages/login/EgovLogin.jsx @@ -21,12 +21,12 @@ function EgovLogin(props) {
              {/* */} -
              -
                -
              • Home
              • -
              • 로그인
              • -
              -
              + {/*
              */} + {/*
                */} + {/*
              • Home
              • */} + {/*
              • 로그인
              • */} + {/*
              */} + {/*
              */} {/* */}
              diff --git a/egovframe-template-simple-react-contribution/src/pages/login/EgovLoginContent.jsx b/egovframe-template-simple-react-contribution/src/pages/login/EgovLoginContent.jsx index b28bbcd..81f221f 100644 --- a/egovframe-template-simple-react-contribution/src/pages/login/EgovLoginContent.jsx +++ b/egovframe-template-simple-react-contribution/src/pages/login/EgovLoginContent.jsx @@ -82,40 +82,42 @@ function EgovLoginContent(props) { EgovNet.requestFetch(loginUrl, requestOptions, (resp) => { - if (Number(resp.resultCode) === Number(CODE.RCV_SUCCESS)) { - let accessToken = resp?.accessToken || null; - let resultVO = parseJwt(accessToken); - let refreshToken = resp?.refreshToken || null; + if(resp !== undefined){ + if (Number(resp.resultCode) === Number(CODE.RCV_SUCCESS)) { + let accessToken = resp?.accessToken || null; + let resultVO = parseJwt(accessToken); + let refreshToken = resp?.refreshToken || null; - // setSessionItem('accessToken', accessToken); - setLocalItem('accessToken', accessToken); - setLocalItem('refreshToken', refreshToken); - // setSessionItem('loginUser', resultVO); - props.onChangeLogin(resultVO); - if (saveIDFlag) { - setLocalItem(KEY_ID, resultVO?.id); + // setSessionItem('accessToken', accessToken); + setLocalItem('accessToken', accessToken); + setLocalItem('refreshToken', refreshToken); + // setSessionItem('loginUser', resultVO); + props.onChangeLogin(resultVO); + if (saveIDFlag) { + setLocalItem(KEY_ID, resultVO?.id); + } + navigate(URL.MAIN); + // PC와 Mobile 열린메뉴 닫기 + document.querySelector('.all_menu.WEB').classList.add('closed'); + document.querySelector('.btnAllMenu').classList.remove('active'); + document.querySelector('.btnAllMenu').title = '전체메뉴 닫힘'; + document.querySelector('.all_menu.Mobile').classList.add('closed'); + } else { + alert(resp.resultMessage) } - navigate(URL.MAIN); - // PC와 Mobile 열린메뉴 닫기 - document.querySelector('.all_menu.WEB').classList.add('closed'); - document.querySelector('.btnAllMenu').classList.remove('active'); - document.querySelector('.btnAllMenu').title = '전체메뉴 닫힘'; - document.querySelector('.all_menu.Mobile').classList.add('closed'); - } else { - alert(resp.resultMessage) } }) } const idFindModal = useCallback( ()=> { - setModalTitle("ID 찾기") + setModalTitle("아이디 찾기") setModalBody(IdFindForm) handleShow(); } ) const pwFindModal = () => { - setModalTitle("PW 찾기") + setModalTitle("비밀번호 찾기") setModalBody(PwFindForm) handleShow(); } @@ -129,40 +131,45 @@ function EgovLoginContent(props) { {/* */}

              로그인

              -

              전자정부표준프레임워크 경량환경 홈페이지 로그인 페이지입니다.
              로그인을 하시면 모든 서비스를 제한없이 이용하실 수 있습니다.

              -
              로그인 - - setUserInfo({ ...userInfo, username: e.target.value })} /> - setUserInfo({ ...userInfo, password: e.target.value })} /> - +
              + + setUserInfo({ ...userInfo, username: e.target.value })} /> +
              +
              + + setUserInfo({ ...userInfo, password: e.target.value })} /> +
              + {/**/} + {/* setUserInfo({ ...userInfo, username: e.target.value })} />*/} + {/* setUserInfo({ ...userInfo, password: e.target.value })} />*/} + {/**/} - + {/**/} - ID 찾기 - PW 찾기 - 회원가입 + 아이디 찾기 + | + 비밀번호 찾기 - + +
              +
              + 회원가입
              - -
                -
              • 비밀번호는 6~12자의 영문 대/소문자, 숫자, 특수문자를 혼합해서 사용하실 수 있습니다.
              • -
              • 쉬운 비밀번호나 자주 쓰는 사이트의 비밀번호가 같을 경우, 도용되기 쉬우므로 주기적으로 - 변경하셔서 사용하는 것이 좋습니다.
              • -
              diff --git a/egovframe-template-simple-react-contribution/src/pages/login/IdFindForm.jsx b/egovframe-template-simple-react-contribution/src/pages/login/IdFindForm.jsx index 1ac674d..4af8c9e 100644 --- a/egovframe-template-simple-react-contribution/src/pages/login/IdFindForm.jsx +++ b/egovframe-template-simple-react-contribution/src/pages/login/IdFindForm.jsx @@ -33,19 +33,22 @@ function IdFindForm(){ return ( - - - 이메일 + + + 찾으려는 아이디의 이메일을 입력해 주세요. - - + + + email icon + + 메일을 입력해주세요. - - - + + + diff --git a/egovframe-template-simple-react-contribution/src/pages/login/My.jsx b/egovframe-template-simple-react-contribution/src/pages/login/My.jsx new file mode 100644 index 0000000..5c5e838 --- /dev/null +++ b/egovframe-template-simple-react-contribution/src/pages/login/My.jsx @@ -0,0 +1,14 @@ +import React, { useState } from 'react'; +import {Link, useLocation, useNavigate} from 'react-router-dom'; +import * as EgovNet from 'api/egovFetch'; + +function My(){ + + + + return ( +
              마이 페이지
              + ); +} + +export default My; \ No newline at end of file diff --git a/egovframe-template-simple-react-contribution/src/pages/login/PwChange.jsx b/egovframe-template-simple-react-contribution/src/pages/login/PwChange.jsx new file mode 100644 index 0000000..6975e96 --- /dev/null +++ b/egovframe-template-simple-react-contribution/src/pages/login/PwChange.jsx @@ -0,0 +1,116 @@ +import React, { useState } from 'react'; +import {Link, useLocation, useNavigate} from 'react-router-dom'; +import * as EgovNet from 'api/egovFetch'; + +import CODE from "constants/code"; +import Row from 'react-bootstrap/Row'; +import Col from 'react-bootstrap/Col'; + +import {getLocalItem, setLocalItem} from 'utils/storage'; +import {parseJwt} from "../../utils/parseJwt"; + + +function PwChange(props) { + console.group("JoinContent"); + console.log("[Start] JoinContent ------------------------------"); + console.log("JoinContent [props] : ", props); + + const navigate = useNavigate(); + const location = useLocation(); + console.log("JoinContent [location] : ", location); + + const accessToken = getLocalItem('accessToken'); + const userInfo = parseJwt(accessToken); + // const [userInfo, setUserInfo] = useState({ id: '', password: '', passwordChk: '', userNm: '', email: '', phoneNum: ''}); + + const submitFormHandler = (e) => { + // console.log("JoinContent submitFormHandler()"); + // let valueChk = true; + // for(let value in userInfo){ + // if(!userInfo[value]){ + // valueChk = false; + // } + // } + // if(valueChk){ + // const loginUrl = "/auth/join" + // const requestOptions = { + // method: "POST", + // headers: { + // 'Content-type': 'application/json' + // }, + // body: JSON.stringify(userInfo) + // } + // + // EgovNet.requestFetch(loginUrl, + // requestOptions, + // (resp) => { + // let resultVO = resp.resultVO; + // let accessToken = resp?.accessToken || null; + // + // setLocalItem('accessToken', accessToken); + // if (Number(resp.resultCode) === Number(CODE.RCV_SUCCESS)) { + // alert(resp.resultMessage); + // navigate('/login'); + // }else{ + // alert(resp.resultMessage); + // } + // + // }) + // }else{ + // window.alert("입력되지 않은 값이 있습니다.") + // } + } + + console.log("------------------------------JoinContent [End]"); + console.groupEnd("JoinContent"); + + + return ( +
              +
              + +
              +
              + {/* */} +
              +

              비밀번호 변경

              +
              + {userInfo?.id?( +
              + + + + + + +
                +
              • 비밀번호는 6~12자의 영문 대/소문자, 숫자, 특수문자를 혼합해서 사용하실 수 있습니다. + {/*
                쉬운 비밀번호나 자주 쓰는 사이트의 비밀번호가 같을 경우, 도용되기 쉬우므로 주기적으로*/} + {/* 변경하셔서 사용하는 것이 좋습니다.*/} +
              • +
              +
              +
              +
              + ):( + + + + + + 비로그인 로그인창으로 + + + )} + +
              +
              + {/* */} +
              +
              +
              +
              + ); +} + +export default PwChange; \ No newline at end of file diff --git a/egovframe-template-simple-react-contribution/src/pages/login/PwFindForm.jsx b/egovframe-template-simple-react-contribution/src/pages/login/PwFindForm.jsx index 9573a1f..6523e4a 100644 --- a/egovframe-template-simple-react-contribution/src/pages/login/PwFindForm.jsx +++ b/egovframe-template-simple-react-contribution/src/pages/login/PwFindForm.jsx @@ -33,25 +33,28 @@ function PwFindForm(){ return (
              - - 아이디 + + 비밀번호를 찾고자하는 아이디와 이메일을 입력해 주세요. - - + + + email icon + + - - - 이메일 - - - + + + + email icon + + - - - + + + diff --git a/egovframe-template-simple-react-contribution/src/pages/login/join/InfoShareChk.jsx b/egovframe-template-simple-react-contribution/src/pages/login/join/InfoShareChk.jsx index 140969f..51977b5 100644 --- a/egovframe-template-simple-react-contribution/src/pages/login/join/InfoShareChk.jsx +++ b/egovframe-template-simple-react-contribution/src/pages/login/join/InfoShareChk.jsx @@ -3,7 +3,7 @@ import React from 'react' function InfoShareChk() { return (
                -
              • 건설기준 포털시스템(KCSC)은 회원님께 원활한 서비스 제공을 위해 최소한의 개인정보를 수집하고 있으며, 각 목적 별로 수집하는 개인정보를 다음과 같이 정하고 있습니다.
              • +
              • 건설기준 포털시스템(KCSC)은 회원님께 원활한 서비스 제공을 위해 최소한의 개인정보를 수집하고 있으며,
                각 목적 별로 수집하는 개인정보를 다음과 같이 정하고 있습니다.
              •  
              • ◌ 수집하는 개인정보의 항목
              •    수집항목: 아이디(ID), 비밀번호, 이메일(e-mail)
              • @@ -13,7 +13,7 @@ function InfoShareChk() {
              •    회원가입정보 : 탈퇴시까지
              • ◌ 정보주체의 동의 거부 권리 및 그에 따른 불이익 사항
              •  
              • -
              • 귀하는 건설기준 포털시스템(KCSC) 이용을 위한 개인정보의 수집·이용 동의를 거부할 권리가 있습니다. 다만, 개인정보의 수집·이용 동의를 거부할 경우 건설기준 포털시스템(KCSC) 일부 기능에 대한 서비스 이용에 제한을 받으실 수 있습니다.
              • +
              • 귀하는 건설기준 포털시스템(KCSC) 이용을 위한 개인정보의 수집·이용 동의를 거부할 권리가 있습니다.
                다만, 개인정보의 수집·이용 동의를 거부할 경우 건설기준 포털시스템(KCSC) 일부 기능에 대한 서비스 이용에 제한을 받으실 수 있습니다.
              ) } diff --git a/egovframe-template-simple-react-contribution/src/pages/login/join/Join.jsx b/egovframe-template-simple-react-contribution/src/pages/login/join/Join.jsx index 26d0118..2753cc9 100644 --- a/egovframe-template-simple-react-contribution/src/pages/login/join/Join.jsx +++ b/egovframe-template-simple-react-contribution/src/pages/login/join/Join.jsx @@ -71,13 +71,13 @@ function Join(props) {
              {/* */} -
              -
                -
              • Home
              • -
              • 로그인
              • -
              • 회원가입
              • -
              -
              + {/*
              */} + {/*
                */} + {/*
              • Home
              • */} + {/*
              • 로그인
              • */} + {/*
              • 회원가입
              • */} + {/*
              */} + {/*
              */} {/* */}
              @@ -89,33 +89,39 @@ function Join(props) { {infoShareChk?(
              + setUserInfo({ ...userInfo, id: e.target.value })} /> + setUserInfo({ ...userInfo, password: e.target.value })}/> setUserInfo({ ...userInfo, passwordChk: e.target.value })}/> +
                +
              • 비밀번호는 6~12자의 영문 대/소문자, 숫자, 특수문자를 혼합해서 사용하실 수 있습니다. + {/*
                쉬운 비밀번호나 자주 쓰는 사이트의 비밀번호가 같을 경우, 도용되기 쉬우므로 주기적으로*/} + {/* 변경하셔서 사용하는 것이 좋습니다.*/} +
              • +
              + setUserInfo({ ...userInfo, userNm: e.target.value })} /> + setUserInfo({ ...userInfo, email: e.target.value })} /> + setUserInfo({ ...userInfo, phoneNum: e.target.value })} />
              -
                -
              • 비밀번호는 6~12자의 영문 대/소문자, 숫자, 특수문자를 혼합해서 사용하실 수 있습니다.
              • -
              • 쉬운 비밀번호나 자주 쓰는 사이트의 비밀번호가 같을 경우, 도용되기 쉬우므로 주기적으로 - 변경하셔서 사용하는 것이 좋습니다.
              • -
              - +
              ):( - + - - + + )} diff --git a/egovframe-template-simple-react-contribution/src/pages/main/EgovLogin.jsx b/egovframe-template-simple-react-contribution/src/pages/main/EgovLogin.jsx new file mode 100644 index 0000000..84a0588 --- /dev/null +++ b/egovframe-template-simple-react-contribution/src/pages/main/EgovLogin.jsx @@ -0,0 +1,197 @@ +import React, {useCallback, useEffect, useRef, useState} from "react"; +import {getLocalItem, setLocalItem} from "utils/storage"; +import * as EgovNet from "api/egovFetch"; +import CODE from "constants/code"; +import {parseJwt} from "../../utils/parseJwt"; +import URL from "constants/url"; +import IdFindForm from "../login/IdFindForm"; +import PwFindForm from "../login/PwFindForm"; +import Row from "react-bootstrap/Row"; +import Col from "react-bootstrap/Col"; +import Form from "react-bootstrap/Form"; +import {Link, useLocation, useNavigate} from "react-router-dom"; +import Modal from "react-bootstrap/Modal"; + + +function EgovLoginContent(props) { + const navigate = useNavigate(); + const location = useLocation(); + + const sessionUser = parseJwt(getLocalItem('accessToken')); + + const [userInfo, setUserInfo] = useState({ username: '', password: 'default', email: '', userSe: 'ACC_TP02'}); + // eslint-disable-next-line no-unused-vars + + const [saveIDFlag, setSaveIDFlag] = useState(false); + + const [findModalState, setFindModalState] = useState(false); + const [modalTitle, setModalTitle] = useState(); + const [modalBody, setModalBody] = useState(); + const handleClose = () => setFindModalState(false); + const handleShow = () => setFindModalState(true); + + const checkRef = useRef(); + + const KEY_ID = "KEY_ID"; + const KEY_SAVE_ID_FLAG = "KEY_SAVE_ID_FLAG"; + + const handleSaveIDFlag = () => { + setLocalItem(KEY_SAVE_ID_FLAG, !saveIDFlag) + setSaveIDFlag(!saveIDFlag); + }; + + useEffect(() => { + let idFlag = getLocalItem(KEY_SAVE_ID_FLAG); + if (idFlag === null) { + setSaveIDFlag(false); + // eslint-disable-next-line react-hooks/exhaustive-deps + idFlag = false; + } else { + setSaveIDFlag(idFlag); + } + + if (idFlag === false) { + setLocalItem(KEY_ID, ""); + } else { + } + }, []); + + useEffect(() => { + let data = getLocalItem(KEY_ID); + if (data !== null) { + setUserInfo({ username: data, password: 'default', email: '', userSe: 'ACC_TP02' }); + } + }, []); + + const submitFormHandler = (e) => { + console.log("EgovLoginContent submitFormHandler()"); + + const loginUrl = "/auth/login" + const requestOptions = { + method: "POST", + headers: { + 'Content-type': 'application/json' + }, + body: JSON.stringify(userInfo) + } + + EgovNet.requestFetch(loginUrl, + requestOptions, + (resp) => { + if(resp !== undefined){ + if (Number(resp.resultCode) === Number(CODE.RCV_SUCCESS)) { + let accessToken = resp?.accessToken || null; + let resultVO = parseJwt(accessToken); + let refreshToken = resp?.refreshToken || null; + + // setSessionItem('accessToken', accessToken); + setLocalItem('accessToken', accessToken); + setLocalItem('refreshToken', refreshToken); + // setSessionItem('loginUser', resultVO); + props.onChangeLogin(resultVO); + if (saveIDFlag) { + setLocalItem(KEY_ID, resultVO?.id); + } + // PC와 Mobile 열린메뉴 닫기 + document.querySelector('.all_menu.WEB').classList.add('closed'); + document.querySelector('.btnAllMenu').classList.remove('active'); + document.querySelector('.btnAllMenu').title = '전체메뉴 닫힘'; + document.querySelector('.all_menu.Mobile').classList.add('closed'); + } else { + alert(resp.resultMessage) + } + } + }) + } + + const idFindModal = useCallback( + ()=> { + setModalTitle("아이디 찾기") + setModalBody(IdFindForm) + handleShow(); + } + ) + const pwFindModal = () => { + setModalTitle("비밀번호 찾기") + setModalBody(PwFindForm) + handleShow(); + } + + + return ( + <> + {sessionUser != null ? ( +
              + + 최근검색어 + 전체삭제 + +
              +
              + {/*
              최근 검색한 내용이 없습니다.
              */} +
              검색어
              +
              검색어
              +
              검색어검색어검색어검색어검색어검색어검색어검색어
              +
              검색어
              +
              검색어
              +
              검색어
              +
              +
              +
              +
              + + Q&A 접수현황 + 0 개 + +
              +
              + + 즐겨찾기 + 바로가기 > + +
              +
              +
              + ) : ( + <> +
              + 로그인 +
              + + setUserInfo({ ...userInfo, username: e.target.value })} /> +
              +
              + + setUserInfo({ ...userInfo, password: e.target.value })} /> +
              + + + + + + 아이디 찾기 + | + 비밀번호 찾기 + + + +
              +
              + 회원가입 +
              + + + + {modalTitle} + + {modalBody} + + + )} + + ); +} + +export default EgovLoginContent; \ No newline at end of file diff --git a/egovframe-template-simple-react-contribution/src/pages/main/EgovMain.jsx b/egovframe-template-simple-react-contribution/src/pages/main/EgovMain.jsx index 2f80d88..fc017c6 100644 --- a/egovframe-template-simple-react-contribution/src/pages/main/EgovMain.jsx +++ b/egovframe-template-simple-react-contribution/src/pages/main/EgovMain.jsx @@ -1,213 +1,413 @@ -import React, { useState, useEffect, useCallback } from 'react'; -import { Link, useLocation } from 'react-router-dom'; +import React, {useState, useEffect, useCallback, useRef} from 'react'; +import { Link, useLocation, useNavigate } from 'react-router-dom'; import Row from 'react-bootstrap/Row'; import Col from 'react-bootstrap/Col'; import Button from 'react-bootstrap/Button'; +import CountUp from 'react-countup'; + +import { Box, Tabs, Tab, Typography } from '@mui/material'; + +import Slider from "react-slick"; +import "slick-carousel/slick/slick.css"; +import "slick-carousel/slick/slick-theme.css"; + import * as EgovNet from 'api/egovFetch'; import URL from 'constants/url'; +import EgovLogin from "../main/EgovLogin"; +import {parseJwt} from "../../utils/parseJwt"; +import {getLocalItem, setLocalItem} from "utils/storage"; +import CODE from "../../constants/code"; + + +function a11yProps(index) { + return { + id: `wrapped-tab-${index}`, + 'aria-controls': `wrapped-tabpanel-${index}`, + }; +} + function EgovMain(props) { console.group("EgovMain"); console.log("[Start] EgovMain ------------------------------"); console.log("EgovMain [props] : ", props); const location = useLocation(); + const navigate = useNavigate(); console.log("EgovMain [location] : ", location); - // eslint-disable-next-line no-unused-vars - const [noticeBoard, setNoticeBoard] = useState(); - // eslint-disable-next-line no-unused-vars - const [gallaryBoard, setGallaryBoard] = useState(); - const [noticeListTag, setNoticeListTag] = useState(); - const [gallaryListTag, setGallaryListTag] = useState(); + const [user, setUser] = useState(parseJwt(getLocalItem('accessToken')) || null); + console.log(user); - const retrieveList = useCallback(() => { - console.groupCollapsed("EgovMain.retrieveList()"); - - const retrieveListURL = '/cmm/main/mainPageAPI.do'; - const requestOptions = { - method: "POST", - headers: { - 'Content-type': 'application/json' - }, - body: JSON.stringify() + const handlePlusClick = () => { + const urls = [ + URL.SUPPORT_LIST_NOCODE+'/KCSC-NTC', + URL.COMMITTEE_PROGRESS, + URL.SUPPORT_LIST_NOCODE+'/KCSC-NOT', + URL.SUPPORT_RESEARCH, + URL.SUPPORT_LIST_NOCODE+'/KCSC-TEC', + URL.SUPPORT_LIST_NOCODE+'/KCSC-NWS' + ]; + if (value >= 0 && value < urls.length) { + navigate(urls[value]); } + }; - EgovNet.requestFetch(retrieveListURL, - requestOptions, - (resp) => { + const settings = { + dots: false, + infinite: true, + speed: 500, + slidesToShow: 6, + slidesToScroll: 1, + arrows: false, + autoplay: true, + autoplaySpeed: 3000, + pauseOnHover: true + }; - setNoticeBoard(resp.result.notiList); - setGallaryBoard(resp.result.galList); + const banners = [ + { src: '/assets/images/f-logo.png', url: 'https://talbakkum.com' }, + { src: '/assets/images/copy2.png', url: 'https://talbakkum.com' }, + { src: '/assets/images/f-logo.png', url: 'https://talbakkum.com' }, + { src: '/assets/images/f-logo.png', url: 'https://talbakkum.com' }, + { src: '/assets/images/copy2.png', url: 'https://talbakkum.com' }, + { src: '/assets/images/f-logo.png', url: 'https://talbakkum.com' }, + { src: '/assets/images/f-logo.png', url: 'https://talbakkum.com' }, + { src: '/assets/images/f-logo.png', url: 'https://talbakkum.com' }, + { src: '/assets/images/f-logo.png', url: 'https://talbakkum.com' }, + { src: '/assets/images/copy2.png', url: 'https://talbakkum.com' }, + { src: '/assets/images/f-logo.png', url: 'https://talbakkum.com' }, + { src: '/assets/images/f-logo.png', url: 'https://talbakkum.com' }, + { src: '/assets/images/copy2.png', url: 'https://talbakkum.com' }, + { src: '/assets/images/f-logo.png', url: 'https://talbakkum.com' }, + { src: '/assets/images/f-logo.png', url: 'https://talbakkum.com' }, + { src: '/assets/images/f-logo.png', url: 'https://talbakkum.com' }, + // 필요한 만큼 배너 이미지를 추가합니다. + ]; - let mutNotiListTag = []; - mutNotiListTag.push(
            • 검색된 결과가 없습니다.
            • ); // 게시판 목록 초기값 + // TAB 상태를 정의합니다. + const [value, setValue] = useState(0); + const handleChange = (event, newValue) => { + setValue(newValue); + }; - // 리스트 항목 구성 - resp.result.notiList.forEach(function (item, index) { - if (index === 0) mutNotiListTag = []; // 목록 초기화 - mutNotiListTag.push( -
            • - - {item.nttSj} - {item.frstRegisterPnttm} - -
            • - ); - }); - setNoticeListTag(mutNotiListTag); + // eslint-disable-next-line no-unused-vars + // const [noticeBoard, setNoticeBoard] = useState(); + // // eslint-disable-next-line no-unused-vars + // const [gallaryBoard, setGallaryBoard] = useState(); + // const [noticeListTag, setNoticeListTag] = useState(); + // const [gallaryListTag, setGallaryListTag] = useState(); + // + // const retrieveList = useCallback(() => { + // console.groupCollapsed("EgovMain.retrieveList()"); + // + // + // const retrieveListURL = '/'; + // const requestOptions = { + // method: "POST", + // + // headers: { + // 'Content-type': 'application/json' + // }, + // body: JSON.stringify() + // } + // + // EgovNet.requestFetch(retrieveListURL, + // requestOptions, + // (resp) => { + // + // setNoticeBoard(resp.result.notiList); + // setGallaryBoard(resp.result.galList); + // + // let mutNotiListTag = []; + // mutNotiListTag.push(
            • 검색된 결과가 없습니다.
            • ); // 게시판 목록 초기값 + // + // // 리스트 항목 구성 + // resp.result.notiList.forEach(function (item, index) { + // if (index === 0) mutNotiListTag = []; // 목록 초기화 + // mutNotiListTag.push( + //
            • + // + // {item.nttSj} + // {item.frstRegisterPnttm} + // + //
            • + // ); + // }); + // setNoticeListTag(mutNotiListTag); + // + // let mutGallaryListTag = []; + // mutGallaryListTag.push(
            • 검색된 결과가 없습니다.
            • ); // 게시판 목록 초기값 + // + // // 리스트 항목 구성 + // resp.result.galList.forEach(function (item, index) { + // if (index === 0) mutGallaryListTag = []; // 목록 초기화 + // mutGallaryListTag.push( + //
            • + // + // {item.nttSj} + // {item.frstRegisterPnttm} + // + //
            • + // ); + // }); + // setGallaryListTag(mutGallaryListTag); + // }, + // function (resp) { + // console.log("err response : ", resp); + // } + // ); + // console.groupEnd("EgovMain.retrieveList()"); + // },[]); + // + // useEffect(() => { + // retrieveList(); + // }, [retrieveList]); - let mutGallaryListTag = []; - mutGallaryListTag.push(
            • 검색된 결과가 없습니다.
            • ); // 게시판 목록 초기값 - // 리스트 항목 구성 - resp.result.galList.forEach(function (item, index) { - if (index === 0) mutGallaryListTag = []; // 목록 초기화 - mutGallaryListTag.push( -
            • - - {item.nttSj} - {item.frstRegisterPnttm} - -
            • - ); - }); - setGallaryListTag(mutGallaryListTag); + const onChangeLogin = (user) => { + setUser(user); + // props.onChangeLogin(user); + } + + const logOutHandler = () => {// 로그인 정보 존재할 때 + const logOutUrl = '/auth/logout'; + const requestOptions = { + headers: { + 'Content-type': 'application/json', }, + credentials: 'include', + } + EgovNet.requestFetch(logOutUrl, requestOptions, function (resp) { - console.log("err response : ", resp); + console.log("===>>> logout resp= ", resp); + if (parseInt(resp.resultCode) === parseInt(CODE.RCV_SUCCESS)) { + onChangeLogin({ loginVO: {} }); + setLocalItem('loginUser', {"id":""}); + setLocalItem('accessToken', null); + setLocalItem('refreshToken', null); + window.alert("로그아웃되었습니다!"); + + // PC와 Mobile 열린메뉴 닫기: 2023.04.13(목) 김일국 추가 + document.querySelector('.all_menu.WEB').classList.add('closed'); + document.querySelector('.btnAllMenu').classList.remove('active'); + document.querySelector('.btnAllMenu').title = '전체메뉴 닫힘'; + document.querySelector('.all_menu.Mobile').classList.add('closed'); + onChangeLogin(null); + } } ); - console.groupEnd("EgovMain.retrieveList()"); - },[]); - - useEffect(() => { - retrieveList(); - }, [retrieveList]); + } console.log("------------------------------EgovMain [End]"); console.groupEnd("EgovMain"); return ( -
              +
              {/* container */}
              -
              -
              - {/*단순 홈페이지 전자정부 국가건설기준센터의 경량환경 내부업무에 대한 최신 정보와 기술을 제공하고 있습니다.*/} -

              건설기준코드 검색

              - - 공통코드 - 지반코드 - 구조코드 - 내진코드 - 가설코드 - 교량코드 - 터널코드 - 공동구코드 - 설비코드 - 조경코드 - 건축코드 - 도로코드 - 철도코드 - 하천코드 - 댐코드 - 상수도코드 - 하수도코드 - 농업기반코드 +
              +
              +
              실시간 인기키워드
              +
              현재 기준 사용자가 가장 많이 검색하는 키워드입니다.
              +
              2024년 5월 9일 목요일 오전 11:45
              + + +
              1 가설공사
              +
              2 가설공사
              +
              3 가설공사
              +
              4 가설공사가설공사
              +
              5 가설공사
              + + +
                6 가설공사
              +
                7 가설공사가설공사가설공사가설공사
              +
                8 가설공사
              +
                9 가설공사
              +
              10 가설공사
              +
              - - {/*
              */} - {/*
              */} - {/* */} - {/*
              */} - {/*
              */} - {/*

              공지사항

              */} - {/*
                */} - {/* {noticeListTag}*/} - {/*
              */} - {/* 더보기*/} - {/*
              */} - - {/*
              */} - {/*

              갤러리

              */} - {/*
                */} - {/* {gallaryListTag}*/} - {/*
              */} - {/* 더보기*/} - {/*
              */} - {/*
              */} - {/*
              */} - - {/*
              */} - {/* */} - {/* 자료실*/} - {/* 다양한 자료를
              다운로드 받으실 수 있습니다.
              */} - {/* */} - {/* */} - {/* 국가건설기준센터*/} - {/* 국가건설기준센터의
              약도 등의 정보를 제공합니다.
              */} - {/* */} - {/*
              */} - {/*
              */} +
              +
              자주찾는 서비스
              +
              버튼을 선택하시면 해당 서비스로 이동합니다.
              + + + +
              +
              코드검색
              +
              + + + + +
              +
              코드안내
              +
              + + + + +
              +
              위원회일정
              +
              + + + + +
              +
              전문시방서
              +
              + + +
              +
              +
              +
              {user ? ( + <> + + {user.id} 님. + + + + ) : ('로그인')} +
              +
              + +
              +
              +
              +
              +
              훈령/예규/지침
              +
              영문건설기준
              +
              건설기준용어
              +
              주요행사
              +
              수요조사
              +
              API 서비스
              +
              관련사이트
              +
              +
              +
              +
              Q&A
              + + + + 1/2 + + +
              +
              +
              + + 00.jpg + + + 콘크리트 내구성 설계 및 평가 문의요.. 정말 잘 되나요? 콘크리트 내구성 설계 및 평가 문의요.. 정말 잘 되나요? + 2024.01.23 +
              +
              + + 00.jpg + + + 콘크리트 내구성 설계 및 평가 문의요.. 정말 잘 되나요? 콘크리트 내구성 설계 및 평가 문의요.. 정말 잘 되나요? + 2024.01.23
              +
              + + 00.jpg + + + 콘크리트 내구성 설계 및 평가 문의요.. 정말 잘 되나요? 콘크리트 내구성 설계 및 평가 문의요.. 정말 잘 되나요? + 2024.01.23
              +
              + + 00.jpg + + + 콘크리트 내구성 설계 및 평가 문의요.. 정말 잘 되나요? 콘크리트 내구성 설계 및 평가 문의요.. 정말 잘 되나요? + 2024.01.23
              +
              +
              +
              +
              다운로드 수
              +
              회원가입자 수
              +
              일 편균 방문자
              +
              개정고시
              +
              +
              +
              + + + + + + + + + + + + Item 0 + Item 1 + Item 2 + Item 3 + Item 4 + Item 5 +
              +
              +
              +
              + + {banners.map((banner, index) => ( +
              + + {`Banner + +
              + ))} +
              - - {/*
              */} - {/*
              */} - {/*
              */} - {/*

              주요사업 소개

              */} - {/*

              국가건설기준센터가 제공하는
              */} - {/* 주요 사업을 소개합니다.

              */} - {/*
              */} - {/* 자세히 보기*/} - {/*
              */} - {/*
              */} - {/*
              */} - {/*

              대표서비스 소개

              */} - {/*

              국가건설기준센터 실행환경의
              */} - {/* 서비스 그룹에서 제공하는
              */} - {/* 대표서비스입니다.

              */} - {/*
              */} - {/* 자세히 보기*/} - {/*
              */} - {/*
              */} - {/*
              */} - {/*

              서비스 신청

              */} - {/*

              국가건설기준센터 경량환경
              */} - {/* 홈페이지의 다양한 서비스를
              */} - {/* 신청 하실 수 있습니다.

              */} - {/*
              */} - {/* 자세히 보기*/} - {/*
              */} - {/*
              */} - {/*
              */} - {/*

              일정 현황

              */} - {/*

              국가건설기준센터 경량환경
              */} - {/* 홈페이지의 전체적인 일정
              */} - {/* 현황을 조회하실 수 있습니다.

              */} - {/*
              */} - {/* 자세히 보기*/} - {/*
              */} - {/*
              */}
              ); } + +function TabPanel(props) { + const { children, value, index, ...other } = props; + + return ( + + ); +} + export default EgovMain; diff --git a/egovframe-template-simple-react-contribution/src/pages/standardCode/StandardCodeEng.jsx b/egovframe-template-simple-react-contribution/src/pages/standardCode/StandardCodeEng.jsx new file mode 100644 index 0000000..e7b0c69 --- /dev/null +++ b/egovframe-template-simple-react-contribution/src/pages/standardCode/StandardCodeEng.jsx @@ -0,0 +1,107 @@ +import React, { useState } from 'react'; +import {Link, useLocation, useNavigate} from 'react-router-dom'; +import * as EgovNet from 'api/egovFetch'; +import URL from "constants/url"; + +import Row from "react-bootstrap/Row"; +import Col from "react-bootstrap/Col"; +import Button from "react-bootstrap/Button"; + +function CodeEng(){ + const navigate = useNavigate(); + + const goToDown = () => { + // navigate('/support/create/KCSC-QA'); + alert('다운로드 진행중입니다.') // 추후 삭제해주세요. + }; + + + return ( +
              +
              + {/* */} +
              +
                +
              • Home
              • +
              • 정보제공
              • +
              • 영문 건설기준
              • +
              +
              + {/* */} + +
              +
              + {/* */} +

              영문 건설기준

              + + {/* */} +
              +
                +
              • + - 건설산업의 해외진출 시 참고자료로 활용 할 수 있도록 영문 건설기준을 단계적으로 제공 할 예정입니다. +
              • +
              • + - 영문 건설기준은 영문화 시점에서의 국문 건설기준을 번역한 것으로 현행 국문 건설기준의 최신 내용을 반영하지 못한 부분이 있음을 알려드리오니, 영문화된 건설기준 활용 시 유의하여 주시기 바랍니다. +
              • +
              • + - 그리고, 법령, 표준 등의 영문 명칭과 건설용어 등은 검토와 협의를 통해 수정하고 있으며 이를 비롯하여 영문 건설기준에 대한 의견을 남겨주시면 검토 후 반영할 수 있도록 하겠습니다. +
              • +
              +
              + +
              대표메일 : kcsc@kict.re.kr
              + + {/* */} +
              +
              + 기준명 + 설계기준(KDS) + 표준시방서(KCS) +
              +
              + {/* */} + {/*

              검색된 결과가 없습니다.

              */} + + {/* */} + +
              공통 (KDS 10 00 00)
              +
              + +
              +
              + +
              +
              + +
              지반 (KDS 11 00 00)
              +
              + + +
              +
              + +
              +
              + +
              구조 (KDS 14 00 00)
              +
              + +
              +
              + + +
              +
              +
              +
              + {/* */} + + {/* */} +
              +
              +
              +
              + ); +} + +export default CodeEng; \ No newline at end of file diff --git a/egovframe-template-simple-react-contribution/src/pages/standardCode/StandardCodeOld.jsx b/egovframe-template-simple-react-contribution/src/pages/standardCode/StandardCodeOld.jsx new file mode 100644 index 0000000..186850e --- /dev/null +++ b/egovframe-template-simple-react-contribution/src/pages/standardCode/StandardCodeOld.jsx @@ -0,0 +1,14 @@ +import React, { useState } from 'react'; +import {Link, useLocation, useNavigate} from 'react-router-dom'; +import * as EgovNet from 'api/egovFetch'; + +function CodeOld(){ + + + + return ( +
              12(구) 건설기준코드
              + ); +} + +export default CodeOld; \ No newline at end of file diff --git a/egovframe-template-simple-react-contribution/src/pages/standardCode/StandardCodeTerm.jsx b/egovframe-template-simple-react-contribution/src/pages/standardCode/StandardCodeTerm.jsx new file mode 100644 index 0000000..dc92530 --- /dev/null +++ b/egovframe-template-simple-react-contribution/src/pages/standardCode/StandardCodeTerm.jsx @@ -0,0 +1,14 @@ +import React, { useState } from 'react'; +import {Link, useLocation, useNavigate} from 'react-router-dom'; +import * as EgovNet from 'api/egovFetch'; + +function CodeTerm(){ + + + + return ( +
              건설기준코드 용어
              + ); +} + +export default CodeTerm; \ No newline at end of file diff --git a/egovframe-template-simple-react-contribution/src/pages/support/Api.jsx b/egovframe-template-simple-react-contribution/src/pages/support/Api.jsx new file mode 100644 index 0000000..4074f50 --- /dev/null +++ b/egovframe-template-simple-react-contribution/src/pages/support/Api.jsx @@ -0,0 +1,14 @@ +import React, { useState } from 'react'; +import {Link, useLocation, useNavigate} from 'react-router-dom'; +import * as EgovNet from 'api/egovFetch'; + +function API(){ + + + + return ( +
              API 서비스
              + ); +} + +export default API; \ No newline at end of file diff --git a/egovframe-template-simple-react-contribution/src/pages/support/Create.jsx b/egovframe-template-simple-react-contribution/src/pages/support/Create.jsx new file mode 100644 index 0000000..4c7f82e --- /dev/null +++ b/egovframe-template-simple-react-contribution/src/pages/support/Create.jsx @@ -0,0 +1,153 @@ +import React, { useState } from 'react'; +import {Link, useNavigate} from 'react-router-dom'; + +import * as EgovNet from 'api/egovFetch'; +import URL from 'constants/url'; + +import Row from 'react-bootstrap/Row'; +import Col from 'react-bootstrap/Col'; +import Button from 'react-bootstrap/Button'; + +function Create(){ + const navigate = useNavigate(); + + const goToList = () => { + navigate('/support/list/KCSC-QA'); + }; + + + return ( +
              +
              + {/* */} +
              +
                +
              • Home
              • +
              • 정보제공
              • +
              • 게시판명
              • +
              +
              + {/* */} + +
              +
              + {/* */} +

              게시판명

              + +
              + {/*카테고리랑 공개여부는 Q&A만 보이게 처리*/} +
              +
              카테고리
              +
              +
              + +
              +
              + +
              +
              + +
              +
              + +
              +
              + +
              +
              +
              +
              +
              공개여부
              +
              + 공개 + 비공개 +
              +
              + {/*카테고리랑 공개여부는 Q&A만 보이게 처리*/} + +
              +
              첨부파일
              +
              + 파일을 이곳에 드래그 해주세요. + + {/*글 수정시 첨부파일 삭제버튼 사용*/} + + file_name.hwp [3,626] byte + + +
              +
              +
              +
              제목
              +
              + +
              +
              +
              +
              + 에디터 넣어주세요.
              + 에디터 넣어주세요.
              + 에디터 넣어주세요.
              + 에디터 넣어주세요.
              + 에디터 넣어주세요. +
              + + {/*Q&A만 보이게 처리하세요*/} +
              + 개인정보 수집 이용 동의 + + 국가건설기준센터는 게시물 작성자의 개인정보를 다음의 목적을 위해 처리합니다.
              + 처리한 개인정보는 다음의 목적 이외의 용도로는 사용되지 않으며, 이용 목적이 변경될 시에는 사전동의를 구할 예정입니다.
              + + ① 개인정보의 수집·이용 목적 : 질의신청
              + ② 수집하려는 개인정보의 항목 : 작성자 아이디
              + ③ 개인정보의 보유 및 이용 기간 : 작성자가 게시물을 삭제할 때 까지
              + + 귀하께서는 개인정보 수집에 대한 동의를 거부할 권리가 있으며, 동의를 거부하는 경우 "질의신청"을 이용 할 수 없습니다.
              + 위의 개인정보 수집 및 이용동의에 동의 하며 "질의신청"을 진행하겠습니까?
              + + + + + +
              + + + + + + + {/* */} +
              +
              +
              +
              + ); +} + +export default Create; \ No newline at end of file diff --git a/egovframe-template-simple-react-contribution/src/pages/support/Detail.jsx b/egovframe-template-simple-react-contribution/src/pages/support/Detail.jsx new file mode 100644 index 0000000..a4a67b7 --- /dev/null +++ b/egovframe-template-simple-react-contribution/src/pages/support/Detail.jsx @@ -0,0 +1,148 @@ +import React, { useState } from 'react'; +import {Link, useNavigate} from 'react-router-dom'; + +import * as EgovNet from 'api/egovFetch'; +import URL from 'constants/url'; + +import Row from 'react-bootstrap/Row'; +import Col from 'react-bootstrap/Col'; +import Button from 'react-bootstrap/Button'; + +function Detail(){ + const navigate = useNavigate(); + + const goToList = () => { + navigate('/support/list/KCSC-QA'); + }; + + const goToCreate = () => { + navigate('/support/create/KCSC-QA'); + }; + + return ( +
              +
              + {/* */} +
              +
                +
              • Home
              • +
              • 정보제공
              • +
              • 게시판명
              • +
              +
              + {/* */} + +
              +
              + {/* */} +

              게시판명

              + +
              +
              +
              카테고리
              +
              + 설계기준 > 시설물편 > 건축 구조기준 > 건축물 설계하중 +
              +
              등록일자
              +
              + 2011-08-08 11:11:11 +
              +
              +
              +
              작성자
              +
              + 박성환 +
              +
              조회
              +
              + 100 +
              +
              +
              +
              첨부파일
              +
              + + file_name.hwp [3626] byte + +
              +
              +
              +
              [공지] jsp파일을 못찼습니다. 제목 뿌려주세요.
              +
              +
              +
              + Q + 안녕하세요 웹호스팅에 올렸더니 jsp파일에서 이런에러로그가 남았는데요 jsp파일을 못찾는것같습니다? xml을 수정해야하나요?
              + 심각: Servlet.service() for servlet action threw exception
              + javax.servlet.ServletException: Could not get RequestDispatcher for [/WEB-INF/jsp/egovframework//main/main.jsp]: check that + this file exists within your WAR
              + at org.springframework.web.servlet.view.InternalResourceView.renderMergedOutputModel(InternalResourceView.java:217) +
              +
              + A +
                +
              • + {/*답변 처리중인경우*/} + {/*질문 확인 후 답변을 처리중입니다.*/} + + {/*답변 달린경우*/} + admin님의 답변 2011-08-08 12:33:33 + 심각: Servlet.service() for servlet action threw exception은 jsp파일을 열어서 보셔야합니다. + javax.servlet.ServletException: Could not get RequestDispatcher for [/WEB-INF/jsp/egovframework//main/main.jsp]: check that + this file exists within your WAR +
              • +
              +
              + + + + + + + + + {/* */} + + + + + + {/*
              */} + + {/*
              */} + + + + +
              + {/* */} +
              +
                +
              • + chanjin, 2011-08-08 12:33:33 + 심각: Servlet.service() for servlet action threw exception은 jsp파일을 열어서 보셔야합니다.
                + javax.servlet.ServletException: Could not get RequestDispatcher for [/WEB-INF/jsp/egovframework//main/main.jsp]: check that
                + 삭제 +
              • +
              • + sunrise, 2011-08-07 11:11:11 + tomcat서버를 재시동해보세요. 전 그렇게 하니깐 되던데요. + 삭제 +
              • +
              • + auto, 2011-08-07 11:11:11 + 제가 살펴볼께요 메일로 주세요. test@naver.com + 삭제 +
              • +
              +
              + + {/* */} +
              +
              +
              +
              + ); +} + +export default Detail; \ No newline at end of file diff --git a/egovframe-template-simple-react-contribution/src/pages/support/List.jsx b/egovframe-template-simple-react-contribution/src/pages/support/List.jsx new file mode 100644 index 0000000..95668b1 --- /dev/null +++ b/egovframe-template-simple-react-contribution/src/pages/support/List.jsx @@ -0,0 +1,143 @@ +import React, { useState } from 'react'; +import {Link, useNavigate} from 'react-router-dom'; + +import * as EgovNet from 'api/egovFetch'; +import URL from 'constants/url'; + +import Row from 'react-bootstrap/Row'; +import Col from 'react-bootstrap/Col'; +import Button from 'react-bootstrap/Button'; + +function List(){ + const navigate = useNavigate(); + + const goToCreate = () => { + navigate('/support/create/KCSC-QA'); + }; + + + return ( +
              +
              + {/* */} +
              +
                +
              • Home
              • +
              • 정보제공
              • +
              • 게시판명
              • +
              +
              + {/* */} + +
              +
              + {/* */} +

              게시판명

              + + {/* */} +
              +
                +
              • + +
              • +
              • + +
              • +
              • + +
              • +
              +
              + {/* */} + + {/* */} +
              +
              + 번호 + 제목 + 작성자 + 조회수 + 등록일 + 파일 +
              +
              + {/* */} + {/*

              검색된 결과가 없습니다.

              */} + + {/* */} + +
              3
              +
              [공지] 공통컴포넌트 중 모니터링 관련 서비스 실행시 오류가 발생합니다 [15]
              +
              관리자
              +
              3
              +
              2021-7-24
              +
              + + +
              2
              +
              validation 처리 시.패스워드에 대한 메소드를 찾지 못합니다.
              +
              홍길동
              +
              3
              +
              2021-7-24
              +
              + + +
              1
              +
              + {/*미답변시 아이콘*/} +   + {/*답변완료시 아이콘*/} + {/*  */} + 공통컴포넌트 중 모니터링 관련 서비스 실행시 오류가 발생합니다.
              +
              홍길동
              +
              3
              +
              2021-7-24
              +
              + +
              +
              + {/* */} + + + + {/* */} + +
                +
              • +
              • +
              • +
              • +
              • +
              • +
              • +
              • +
              • +
              • +
              • +
              • +
              • +
              • +
              + + {/* */} + + {/* 수요조사는 버튼명 "의견 접수" 수요조사와 QNA만 작성가능하게 관리자 세팅되어야 함/관리자 쓰기권한만 작성가능 */} + +
              + + {/* */} +
              +
              +
              +
              + ); +} + +export default List; \ No newline at end of file diff --git a/egovframe-template-simple-react-contribution/src/pages/support/Poll.jsx b/egovframe-template-simple-react-contribution/src/pages/support/Poll.jsx new file mode 100644 index 0000000..d7b38f6 --- /dev/null +++ b/egovframe-template-simple-react-contribution/src/pages/support/Poll.jsx @@ -0,0 +1,131 @@ +import React, { useState } from 'react'; +import {Link, useLocation, useNavigate} from 'react-router-dom'; +import * as EgovNet from 'api/egovFetch'; +import URL from "constants/url"; + +import Row from "react-bootstrap/Row"; +import Col from "react-bootstrap/Col"; +import Button from "react-bootstrap/Button"; + + +function Poll(){ + const navigate = useNavigate(); + + const goToDetail = () => { + // navigate('/support/list/KCSC-QA'); + }; + + + return ( +
              +
              + {/* */} +
              +
                +
              • Home
              • +
              • 정보제공
              • +
              • 설문조사
              • +
              +
              + {/* */} + +
              +
              + {/* */} +

              설문조사

              + + {/* */} + + 2023년 건설기준 포털시스템 이용자 만족도 조사 + + +
              +
              +
              참여기간
              +
              + 2014-06-25 ~ 2015-09-17 +
              +
              +
              +
              내용
              +
              + 본 연구의 목적은 “건설공사기준 코드체계(국토교통부 고시 제2013-640호, ‘13.10)” 전환에 따른 분야별 코드별로 현행 설계기준과 표준시방서에 대하여 중복 및 상충 항목의 검토 정비하여 통합 코드(안) 마련. +
              +
              +
              + + + + 2022년 건설기준 포털시스템 이용자 만족도 조사 + + +
              +
              +
              참여기간
              +
              + 2013-12-26 ~ 2015-06-30 +
              +
              +
              +
              내용
              +
              + 본 연구의 목적은 “건설공사기준 코드체계(국토교통부 고시 제2013-640호, ‘13.10)” 전환에 따른 분야별 코드별로 현행 설계기준과 표준시방서에 대하여 중복 및 상충 항목의 검토 정비하여 통합 코드(안) 마련. +
              +
              +
              + + + + 2021년 건설기준 포털시스템 이용자 만족도 조사 + + +
              +
              +
              참여기간
              +
              + 2013-03-01 ~ 2014-07-01 +
              +
              +
              +
              내용
              +
              + ㅇ 현장 여건 변화 및 민원 등에 따른 합리적 표준시방서 개정 + ㅇ 2009년 개정 이후 민원 및 감사원 지적 등에 따른 시방서 내용 개정 +
              +
              +
              + + + + {/* */} + +
                +
              • +
              • +
              • +
              • +
              • +
              • +
              • +
              • +
              • +
              • +
              • +
              • +
              • +
              • +
              + + {/* */} + + {/* 수요조사는 버튼명 "의견 접수" 수요조사와 QNA만 작성가능하게 관리자 세팅되어야 함/관리자 쓰기권한만 작성가능 */} + +
              +
              +
              +
              +
              + ); +} + +export default Poll; \ No newline at end of file diff --git a/egovframe-template-simple-react-contribution/src/pages/support/Qna.jsx b/egovframe-template-simple-react-contribution/src/pages/support/Qna.jsx new file mode 100644 index 0000000..1eb1cf7 --- /dev/null +++ b/egovframe-template-simple-react-contribution/src/pages/support/Qna.jsx @@ -0,0 +1,87 @@ +import React, { useState } from 'react'; +import {Link, useNavigate} from 'react-router-dom'; +// import * as EgovNet from 'api/egovFetch'; + +import Row from 'react-bootstrap/Row'; +import Col from 'react-bootstrap/Col'; +import Button from 'react-bootstrap/Button'; + +import URL from 'constants/url'; +import StandardCodeInfo from "../standardCode/info/StandardCodeInfo"; + +function QNA(){ + const navigate = useNavigate(); + + const goToQna = () => { + navigate('/support/list/KCSC-QA'); + }; + + return ( +
              +
              + {/* */} +
              +
                +
              • Home
              • +
              • 정보제공
              • +
              • Q&A
              • +
              +
              + {/* */} + +
              +
              + {/* */} +

              Q & A

              + +
              + + + + 건설기준 포털시스템(국가건설기준센터)에서는 건설공사의 기술성, 환경성 향상 및 품질확보와 효율적인 공사 관리를 위한 건설기준(설계기준, 표준시방서, 전문시방서)을 제공하고 있습니다.
              + 건설기준을 활용과정에서 각종 질의, 제안사항 등이 있으신 경우에는 본 질의지원 시스템을 적극 활용하여 주시기 바랍니다. + +
              +
              +
              + + + + (질의처리 관련) 건설기준 관련단체와 협의가 필요한 경우 질의처리 기간이 2주 이상 소요될 수 있음을 양지하시기 바라며, 최대한 빠른 질의처리가 이루어질 수 있도록 노력하겠습니다. + + + + + + (건설기준 유권해석) 건설기준의 유권해석은 「건설기술진흥업무 운영규정(국토교통부 훈령)」제40조제2항제3호의 규정에 따라 해당 건설기준 소관부서(부처)에서 담당하도록 되어 있습니다.
              + 따라서 우리 센터에서는 건설기준 관련 질의에 대한 검토 의견을 드릴 수는 있으나, 이 의견이 건설기준 유권해석은 아님을 양지하여 주시기 바랍니다.
              + 건설기준에 대한 유권해석을 원하시는 경우에는 조금 불편하시더라도 국민신문고 등을 통해 해당 건설기준의 소관부서(부처)에 문의하여 주시기 바랍니다 + +
              + + + + (민원공개 관련) ⌜공공기관의 정보공개에 관한 법률⌟ 제9조(비공개대상정보)에 따라 아래의 사항은 질의응답이나 민원공개가 제한됨을 알려드립니다..
              + * 성명·주민등록번호 등 개인에 관한 사항으로서 공개될 경우 사생활의 비밀 또는 자유를 침해할 우려가 있다고 인정되는 정보
              + * 불법적인 사유나 불편·부당한 수단을 동원하여 민원처리기관에 특정한 행위를 요구하는 경우
              + * 기타 질의자가 비공개를 요청하는 경우 등 + +
              +
              +
              + 건설기준 포털시스템에서는 개인정보(개인 연락처, 이메일 등)를 수집하지 않습니다.
              + 질의 답변은 접수현황에서 확인하시기 바랍니다. +
              +
              + +
              + + {/* */} +
              +
              +
              +
              + ); +} + +export default QNA; \ No newline at end of file diff --git a/egovframe-template-simple-react-contribution/src/pages/support/Research.jsx b/egovframe-template-simple-react-contribution/src/pages/support/Research.jsx new file mode 100644 index 0000000..536055d --- /dev/null +++ b/egovframe-template-simple-react-contribution/src/pages/support/Research.jsx @@ -0,0 +1,184 @@ +import React, { useState } from 'react'; +import {Link, useLocation, useNavigate} from 'react-router-dom'; +import * as EgovNet from 'api/egovFetch'; +import URL from "constants/url"; + +import Row from "react-bootstrap/Row"; +import Col from "react-bootstrap/Col"; +import Button from "react-bootstrap/Button"; +import Modal from 'react-bootstrap/Modal'; + +function Research(){ + const [show, setShow] = useState(false); + const [modalContent, setModalContent] = useState({}); + const handleClose = () => setShow(false); + const handleShow = (content) => { + setModalContent(content); + setShow(true); + }; + + const items = [ + { + id: 1, + modalPeriod: '2014-06-25 ~ 2015-09-17', + modalCharge: '이영호 연구위원', + modalGoal: '본 연구의 목적은 “건설공사기준 코드체계(국토교통부 고시 제2013-640호, ‘13.10)” 전환에 따른 분야별 코드별로 현행 설계기준과 표준시방서에 대하여 중복 및 상충 항목의 검토 정비하여 통합 코드(안) 마련.', + modalTitle: '예산절감을 위한 건설기준 개정 연구', + modalBody: ` + - 교량 건설기준 국제 통용성 분석 연구
              + - [기고문]건설산업 변화와 디지털 건설기준 도입
              + - [기고문]인공지능 기술을 활용한 건설기준 중복 상충부 검토
              + - 건설산업 디지털 전환 동향 파악을 위한 국외출장 결과
              + - 건설기준 주요 민원사례 소개
              + - 2023년 건설기준위원회 및 중앙건설기술심의위원회 개최 현황
              + - 2023년 건설기준 제·개정 고시 현황 + `, + modalEffect: ` + - 교량 건설기준 국제 통용성 분석 연구
              + - [기고문]건설산업 변화와 디지털 건설기준 도입 + ` + }, + { + id: 2, + modalPeriod: '2013-12-26 ~ 2015-06-30', + moadalCharge: '이영호 연구위원', + modalGoal: '본 연구의 목적은 “건설공사기준 코드체계(국토교통부 고시 제2013-640호, ‘13.10)” 전환에 따른 분야별 코드별로 현행 설계기준과 표준시방서에 대하여 중복 및 상충 항목의 검토 정비하여 통합 코드(안) 마련.', + modalTitle: '건설공사 설계·시공 표준화 연구(도로 및 수자원 시설분야)(국가 R&D)', + modalBody: ` + - 다른 내용1
              + - 다른 내용2
              + - 다른 내용3
              + - 다른 내용4
              + `, + modalEffect: ` + - 교량 건설기준 국제 통용성 분석 연구
              + - [기고문]건설산업 변화와 디지털 건설기준 도입 + ` + }, + // 더 많은 항목을 추가 + ]; + + + return ( +
              +
              + {/* */} +
              +
                +
              • Home
              • +
              • 정보제공
              • +
              • 건설기준 연구
              • +
              +
              + {/* */} + +
              +
              + {/* */} +

              건설기준 연구

              + + {/* */} + {items.map(item => ( + + + {item.modalTitle} + + +
              +
              +
              연구기간
              +
              + {item.modalPeriod} +
              +
              +
              +
              연구책임자
              +
              + {item.modalCharge} +
              +
              +
              +
              연구목적
              +
              + {item.modalGoal} +
              +
              +
              +
              + ))} + + + 도로공사표준시방서 개정(국고보조금사업) + + +
              +
              +
              연구기간
              +
              + 2013-03-01 ~ 2014-07-01 +
              +
              +
              +
              연구책임자
              +
              + 한국도로교통협회 +
              +
              +
              +
              연구목적
              +
              + ㅇ 현장 여건 변화 및 민원 등에 따른 합리적 표준시방서 개정
              + ㅇ 2009년 개정 이후 민원 및 감사원 지적 등에 따른 시방서 내용 개정 +
              +
              +
              + + + + {/* */} + +
                +
              • +
              • +
              • +
              • +
              • +
              • +
              • +
              • +
              • +
              • +
              • +
              • +
              • +
              • +
              + + {/* */} + + {/* 수요조사는 버튼명 "의견 접수" 수요조사와 QNA만 작성가능하게 관리자 세팅되어야 함/관리자 쓰기권한만 작성가능 */} + +
              +
              +
              +
              + + + + {modalContent.title} + + +
              연구내용
              +
              +
              +
              +
              기대효과
              +
              +
              +
              +
              +
              + ); +} + +export default Research; \ No newline at end of file diff --git a/egovframe-template-simple-react-contribution/src/pages/support/Site.jsx b/egovframe-template-simple-react-contribution/src/pages/support/Site.jsx new file mode 100644 index 0000000..15aeda3 --- /dev/null +++ b/egovframe-template-simple-react-contribution/src/pages/support/Site.jsx @@ -0,0 +1,14 @@ +import React, { useState } from 'react'; +import {Link, useLocation, useNavigate} from 'react-router-dom'; +import * as EgovNet from 'api/egovFetch'; + +function Site(){ + + + + return ( +
              관련사이트
              + ); +} + +export default Site; \ No newline at end of file diff --git a/egovframe-template-simple-react-contribution/src/routes/index.jsx b/egovframe-template-simple-react-contribution/src/routes/index.jsx index 10e53ce..e4c6bdc 100644 --- a/egovframe-template-simple-react-contribution/src/routes/index.jsx +++ b/egovframe-template-simple-react-contribution/src/routes/index.jsx @@ -13,37 +13,66 @@ import EgovError from 'components/EgovError'; import EgovMain from 'pages/main/EgovMain'; import EgovLogin from 'pages/login/EgovLogin'; import Join from 'pages/login/join/Join'; +import My from 'pages/login/My'; +import Private from 'pages/inform/Private'; +import Email from 'pages/inform/Email'; +import ChangePw from 'pages/login/PwChange' //ABOUT import EgovAboutSite from 'pages/about/EgovAboutSite'; import EgovAboutHistory from 'pages/about/EgovAboutHistory'; +import EgovAboutPromote from 'pages/about/EgovAboutPromote'; import EgovAboutOrganization from 'pages/about/EgovAboutOrganization'; import EgovAboutLocation from 'pages/about/EgovAboutLocation'; +import EgovAboutSitemap from 'pages/about/EgovAboutSitemap'; //INTRO -import EgovIntroWork from 'pages/intro/EgovIntroWork'; -import EgovIntroService from 'pages/intro/EgovIntroService'; +// import EgovIntroWork from 'pages/intro/EgovIntroWork'; +// import EgovIntroService from 'pages/intro/EgovIntroService'; + +//COMMITTEE +import CommitteeProgress from 'pages/committee/Progress'; +import CommitteeSchedule from 'pages/committee/Schedule'; //SUPPORT +import SupportList from 'pages/support/List'; +import SupportDetail from 'pages/support/Detail'; +import SupportCreate from 'pages/support/Create'; +import SupportQna from 'pages/support/Qna'; + +import SupportSite from 'pages/support/Site'; +import SupportApi from 'pages/support/Api'; +import SupportResearch from 'pages/support/Research'; +import SupportPoll from 'pages/support/Poll'; + import EgovSupportDownloadList from 'pages/support/download/EgovDownloadList'; -import EgovSupportDownloadDetail from 'pages/support/download/EgovDownloadDetail'; -import EgovSupportDownloadCreate from 'pages/support/download/EgovDownloadCreate'; -import EgovSupportQnaList from 'pages/support/qna/EgovQnaList'; -import EgovSupportQnaDetail from 'pages/support/qna/EgovQnaDetail'; -import EgovSupportApply from 'pages/support/apply/EgovSupportApply'; +// import EgovSupportDownloadDetail from 'pages/support/download/EgovDownloadDetail'; +// import EgovSupportDownloadCreate from 'pages/support/download/EgovDownloadCreate'; +// import EgovSupportQnaList from 'pages/support/qna/EgovQnaList'; +// import EgovSupportQnaDetail from 'pages/support/qna/EgovQnaDetail'; +// import EgovSupportApply from 'pages/support/apply/EgovSupportApply'; + +//건설기준코드 +import CodeViewer from 'pages/standardCode/viewer/CodeViewer'; +import StandardCodePage from "../pages/standardCode/list/StandardCodePage"; +import StandardCodeInfo from "../pages/standardCode/info/StandardCodeInfo"; +import StandardCodeTerm from "pages/standardCode/StandardCodeTerm"; +import StandardCodeEng from "pages/standardCode/StandardCodeEng"; +import StandardCodeOld from "pages/standardCode/StandardCodeOld"; + //INFORM -import EgovDailyList from 'pages/inform/daily/EgovDailyList'; -import EgovDailyDetail from 'pages/inform/daily/EgovDailyDetail'; -import EgovWeeklyList from 'pages/inform/weekly/EgovWeeklyList'; - -import EgovNoticeList from 'pages/inform/notice/EgovNoticeList'; -import EgovNoticeDetail from 'pages/inform/notice/EgovNoticeDetail'; -import EgovNoticeEdit from 'pages/inform/notice/EgovNoticeEdit'; - -import EgovGalleryList from 'pages/inform/gallery/EgovGalleryList'; -import EgovGalleryDetail from 'pages/inform/gallery/EgovGalleryDetail'; -import EgovGalleryEdit from 'pages/inform/gallery/EgovGalleryEdit'; +// import EgovDailyList from 'pages/inform/daily/EgovDailyList'; +// import EgovDailyDetail from 'pages/inform/daily/EgovDailyDetail'; +// import EgovWeeklyList from 'pages/inform/weekly/EgovWeeklyList'; +// +// import EgovNoticeList from 'pages/inform/notice/EgovNoticeList'; +// import EgovNoticeDetail from 'pages/inform/notice/EgovNoticeDetail'; +// import EgovNoticeEdit from 'pages/inform/notice/EgovNoticeEdit'; +// +// import EgovGalleryList from 'pages/inform/gallery/EgovGalleryList'; +// import EgovGalleryDetail from 'pages/inform/gallery/EgovGalleryDetail'; +// import EgovGalleryEdit from 'pages/inform/gallery/EgovGalleryEdit'; //ADMIN import EgovAdminScheduleList from 'pages/admin/schedule/EgovAdminScheduleList'; @@ -63,6 +92,9 @@ import EgovAdminNoticeEdit from 'pages/admin/notice/EgovAdminNoticeEdit'; import EgovAdminGalleryList from 'pages/admin/gallery/EgovAdminGalleryList'; import EgovAdminGalleryDetail from 'pages/admin/gallery/EgovAdminGalleryDetail'; import EgovAdminGalleryEdit from 'pages/admin/gallery/EgovAdminGalleryEdit'; + + + //사이트관리자 암호 바꾸기 기능 추가 2023.04.15(토) 김일국 추가 import EgovAdminPasswordUpdate from 'pages/admin/manager/EgovAdminPasswordUpdate'; @@ -79,8 +111,7 @@ import AdminUsersList from 'pages/admin/users/List'; // 관리자 - 게시판 현황 import AdminBoardsList from 'pages/admin/boards/List'; // 관리자 - 게시판 현황/게시판 관리 -import AdminBoardsPosts from 'pages/admin/boards/Posts'; // 관리자 - 게시판 현황/게시물 관리 -import AdminBoardsKeywords from 'pages/admin/boards/Keywords'; // 관리자 - 게시판 현황/키워드 관리 +import AdminPostMgtList from "../pages/admin/board/AdminPostMgtList"; // 관리자 - 게시판 현황/게시물 관리 // 관리자 - 건설기준 관리 import AdminStandardsReferenceCodes from 'pages/admin/standards/ReferenceCodes'; // 관리자 - 건설기준 관리/참조코드 조회 @@ -101,7 +132,6 @@ import AdminCommitteeProgressStatus from 'pages/admin/committee/ProgressStatus'; import AdminCommitteeProgressStatusDetail from 'pages/admin/committee/ProgressStatus/Detail'; // 관리자 - 위원회 관리/진행현황 관리/진행현황 관리 상세 import AdminCommitteeProgressStatusEdit from 'pages/admin/committee/ProgressStatus/Edit'; // 관리자 - 위원회 관리/진행현황 관리/진행현황 관리 생성 또는 수정 - import AdminCommitteeSchedules from 'pages/admin/committee/Schedules'; // 관리자 - 위원회 관리/위원회 일정 관리 import AdminCommitteeSchedulesDetail from 'pages/admin/committee/Schedules/Detail'; // 관리자 - 위원회 관리/위원회 일정 관리/일정관리상세 import AdminCommitteeSchedulesEdit from 'pages/admin/committee/Schedules/Edit'; // 관리자 - 위원회 관리/위원회 일정 관리/일정관리생성 또는 수정 @@ -113,15 +143,8 @@ import AdminLogsPrivacyLogs from 'pages/admin/logs/PrivacyLogs'; import AdminLogsFileDownloadStatus from 'pages/admin/logs/FileDownloadStatus'; // 관리자 - 위원회 관리/파일 다운현황 -//건설기준코드 -import CodeViewer from 'pages/standardCode/viewer/CodeViewer'; -import StandardCodePage from "../pages/standardCode/list/StandardCodePage"; -import StandardCodeInfo from "../pages/standardCode/info/StandardCodeInfo"; - - import * as EgovNet from 'api/egovFetch'; // jwt토큰 위조 검사 때문에 추가 import initPage from 'js/ui'; -import AdminPostMgtList from "../pages/admin/board/AdminPostMgtList"; const RootRoutes = () => { //useLocation객체를 이용하여 정규표현식을 사용한 /admin/~ 으로 시작하는 경로와 비교에 사용(아래 1줄) */} @@ -206,6 +229,10 @@ const SecondRoutes = () => { setLoginVO(user)}/>}/> {/*{JOIN}*/} } /> + } /> + } /> + } /> + } /> {/* ERROR */} } /> @@ -214,45 +241,75 @@ const SecondRoutes = () => { } /> } /> } /> + } /> } /> } /> + } /> {/* INTRO */} - } /> - } /> - } /> + {/*} />*/} + {/*} />*/} + {/*} />*/} + + {/* COMMITTEE */} + } /> + } /> + } /> {/* SUPPORT */} - } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> } /> - } /> - } /> + {/*} />*/} + {/*} />*/} - } /> - } /> + {/*} />*/} + {/*} />*/} - } /> + {/*} />*/} {/* INFORM */} - } /> + {/*} />*/} - } /> - } /> - } /> - } /> + {/*} />*/} + {/*} />*/} + {/*} />*/} + {/*} />*/} + + {/*} />*/} + {/*} />*/} + {/*} />*/} + {/*} />*/} + {/*} />*/} + + {/*} />*/} + {/*} />*/} + {/*} />*/} + {/*} />*/} + {/*} />*/} + + {/*기준코드 뷰어*/} + } /> + } /> + } /> + } /> + } /> + } /> + + + {/*기준코드리스트*/} + } /> + } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> {/* ADMIN */} } /> @@ -297,11 +354,10 @@ const SecondRoutes = () => { {/* 관리자 - 게시판 현황 */} } /> } /> - } /> {/* 관리자 - 건설기준 관리 */} } /> - } /> + } /> } /> } /> @@ -326,8 +382,6 @@ const SecondRoutes = () => { } /> } /> - - {/* 관리자 - 로그 관리 */} } /> } /> @@ -335,16 +389,6 @@ const SecondRoutes = () => { } /> - - {/*기준코드 뷰어*/} - } /> - } /> - - } /> - {/*기준코드리스트*/} - } /> - } /> - diff --git a/kcsc-back-end/build.gradle b/kcsc-back-end/build.gradle index 34a1ba0..2ca397a 100644 --- a/kcsc-back-end/build.gradle +++ b/kcsc-back-end/build.gradle @@ -89,6 +89,10 @@ dependencies { implementation 'org.apache.commons:commons-lang3' + // https://mvnrepository.com/artifact/org.apache.httpcomponents.client5/httpclient5 + implementation group: 'org.apache.httpcomponents.client5', name: 'httpclient5', version: '5.3.1' + // https://mvnrepository.com/artifact/com.googlecode.json-simple/json-simple + implementation group: 'com.googlecode.json-simple', name: 'json-simple', version: '1.1.1' } diff --git a/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/boards/AdminBoardsController.java b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/boards/AdminBoardsController.java index 1072a1f..b851ff6 100644 --- a/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/boards/AdminBoardsController.java +++ b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/boards/AdminBoardsController.java @@ -53,7 +53,7 @@ public class AdminBoardsController extends BaseController { @ApiResponse(responseCode = "200", description = "조회 성공"), @ApiResponse(responseCode = "403", description = "인가된 사용자가 아님") }) - @RequestMapping(method = RequestMethod.GET, value = "/board-list", consumes = MediaType.APPLICATION_JSON_VALUE) + @RequestMapping(method = RequestMethod.GET, value = "/mgt/board-list", consumes = MediaType.APPLICATION_JSON_VALUE) public ResultVO getBoardList() throws Exception { ResultVO resultVO = new ResultVO(); Map resultMap = new HashMap<>(); @@ -72,7 +72,7 @@ public class AdminBoardsController extends BaseController { @ApiResponse(responseCode = "200", description = "조회 성공"), @ApiResponse(responseCode = "403", description = "인가된 사용자가 아님") }) - @RequestMapping(method = RequestMethod.GET, value = "/get-option-list", consumes = MediaType.APPLICATION_JSON_VALUE) + @RequestMapping(method = RequestMethod.GET, value = "/mgt/get-option-list", consumes = MediaType.APPLICATION_JSON_VALUE) public ResultVO getOptionList() throws Exception { ResultVO resultVO = new ResultVO(); Map resultMap = new HashMap<>(); @@ -83,6 +83,25 @@ public class AdminBoardsController extends BaseController { return resultVO; } + @Operation( + summary = "게시판 ID 중복 확인", + description = "게시판 ID 중복 확인", + tags = {"AdminBoardsController"} + ) + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "조회 성공"), + @ApiResponse(responseCode = "403", description = "인가된 사용자가 아님") + }) + @RequestMapping(method = RequestMethod.GET, value = "/mgt/check-duplicate", consumes = MediaType.APPLICATION_JSON_VALUE) + public ResultVO checkDuplicate(String bbsId) throws Exception { + ResultVO resultVO = new ResultVO(); + Map resultMap = new HashMap<>(); + + resultMap.put("duplicateYn", adminBoardsService.checkDuplicate(bbsId)); + resultVO.setResult(resultMap); + return resultVO; + } + @Operation( summary = "게시판 저장", description = "게시판 저장", @@ -92,7 +111,7 @@ public class AdminBoardsController extends BaseController { @ApiResponse(responseCode = "200", description = "저장 성공"), @ApiResponse(responseCode = "403", description = "인가된 사용자가 아님") }) - @RequestMapping(method = RequestMethod.PUT, value = "/board-mgt") + @RequestMapping(method = RequestMethod.PUT, value = "/mgt/board-mgt") public ResultVO saveBoardMgt(@RequestBody @Valid TnBbs bbs, Errors errors, @AuthenticationPrincipal LoginVO user) { ResultVO resultVO = new ResultVO(); if (user == null) { @@ -124,13 +143,13 @@ public class AdminBoardsController extends BaseController { @ApiResponse(responseCode = "200", description = "삭제 성공"), @ApiResponse(responseCode = "403", description = "인가된 사용자가 아님") }) - @RequestMapping(method = RequestMethod.DELETE, value = "/board-mgt") + @RequestMapping(method = RequestMethod.DELETE, value = "/mgt/board-mgt") public ResultVO deleteBoardMgt(@RequestBody TnBbs bbs, @AuthenticationPrincipal LoginVO user) { ResultVO resultVO = new ResultVO(); if (user == null) { resultVO.setResultCode(ResponseCode.TOKEN_EXPIRED.getCode()); } else { - String result = adminBoardsService.deleteBoard(bbs, user.getId()); + String result = adminBoardsService.deleteBoard(bbs); if (result == null) { resultVO.setResultCode(ResponseCode.SUCCESS.getCode()); } else if (result.equals("notFind")) { @@ -151,12 +170,16 @@ public class AdminBoardsController extends BaseController { @ApiResponse(responseCode = "200", description = "조회 성공"), @ApiResponse(responseCode = "403", description = "인가된 사용자가 아님") }) - @RequestMapping(method = RequestMethod.GET, value = "/post-list", consumes = MediaType.APPLICATION_JSON_VALUE) - public ResultVO getPostList() throws Exception { + @RequestMapping(method = RequestMethod.GET, value = "/posts/post-list", consumes = MediaType.APPLICATION_JSON_VALUE) + public ResultVO getPostList(TnBbsContents params) throws Exception { ResultVO resultVO = new ResultVO(); - Map resultMap = new HashMap<>(); + params.setQueryInfo(); + Map resultMap = adminBoardsService.selectPostList(params); resultMap.put("categoryList", adminBoardsService.selectBoardList()); - resultMap.put("postList", adminBoardsService.selectPostList()); + int totCnt = Integer.parseInt((String)resultMap.get("resultCnt")); + params.setContentCnt(totCnt); + params.setPaginationInfo(); + resultMap.put("paginationInfo", params); resultVO.setResult(resultMap); return resultVO; } @@ -170,7 +193,7 @@ public class AdminBoardsController extends BaseController { @ApiResponse(responseCode = "200", description = "조회 성공"), @ApiResponse(responseCode = "403", description = "인가된 사용자가 아님") }) - @RequestMapping(method = RequestMethod.POST, value = "/get-category-and-file-list", consumes = MediaType.APPLICATION_JSON_VALUE) + @RequestMapping(method = RequestMethod.POST, value = "/posts/get-category-and-file-list", consumes = MediaType.APPLICATION_JSON_VALUE) public ResultVO getCategoryList(@RequestBody TnBbsContents tnBbsContents) throws Exception { ResultVO resultVO = new ResultVO(); Map resultMap = new HashMap<>(); @@ -206,7 +229,7 @@ public class AdminBoardsController extends BaseController { @ApiResponse(responseCode = "200", description = "저장 성공"), @ApiResponse(responseCode = "403", description = "인가된 사용자가 아님") }) - @RequestMapping(method = RequestMethod.PUT, value = "/post-mgt") + @RequestMapping(method = RequestMethod.PUT, value = "/posts/post-mgt") public ResultVO savePostMgt( @Valid TnBbsContents contents, HttpServletRequest request, @@ -245,14 +268,14 @@ public class AdminBoardsController extends BaseController { @ApiResponse(responseCode = "200", description = "삭제 성공"), @ApiResponse(responseCode = "403", description = "인가된 사용자가 아님") }) - @RequestMapping(method = RequestMethod.DELETE, value = "/post-mgt") + @RequestMapping(method = RequestMethod.DELETE, value = "/posts/post-mgt") public ResultVO deletePostMgt(@RequestBody TnBbsContents contents, HttpServletRequest request, @AuthenticationPrincipal LoginVO user) { ResultVO resultVO = new ResultVO(); if (user == null) { resultVO.setResultCode(ResponseCode.TOKEN_EXPIRED.getCode()); } else { contents.setIpAddress(ClientUtils.getRemoteIP(request)); - String result = adminBoardsService.deletePost(contents, user.getId()); + String result = adminBoardsService.deletePost(contents); if (result == null) { resultVO.setResultCode(ResponseCode.SUCCESS.getCode()); } else if (result.equals("notFind")) { diff --git a/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/boards/entity/TnBbsContents.java b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/boards/entity/TnBbsContents.java index 42bd06c..f0a42e8 100644 --- a/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/boards/entity/TnBbsContents.java +++ b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/boards/entity/TnBbsContents.java @@ -1,4 +1,5 @@ package com.dbnt.kcscbackend.admin.boards.entity; +import com.dbnt.kcscbackend.config.common.BoardParams; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; @@ -15,7 +16,7 @@ import java.time.LocalDateTime; @DynamicInsert @DynamicUpdate @Table(name = "tn_bbs_contents") -public class TnBbsContents { +public class TnBbsContents extends BoardParams { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "bbs_cont_seq") diff --git a/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/boards/mapper/AdminBoardsMapper.java b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/boards/mapper/AdminBoardsMapper.java new file mode 100644 index 0000000..55b22ea --- /dev/null +++ b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/boards/mapper/AdminBoardsMapper.java @@ -0,0 +1,14 @@ +package com.dbnt.kcscbackend.admin.boards.mapper; + +import com.dbnt.kcscbackend.admin.boards.entity.TnBbsContents; +import org.apache.ibatis.annotations.Mapper; + +import java.util.List; + +@Mapper +public interface AdminBoardsMapper { + + List selectPostList(TnBbsContents params); + + Integer selectPostListCnt(TnBbsContents params); +} diff --git a/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/boards/repository/TnBbsRepository.java b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/boards/repository/TnBbsRepository.java index b700de4..393b11d 100644 --- a/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/boards/repository/TnBbsRepository.java +++ b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/boards/repository/TnBbsRepository.java @@ -4,9 +4,12 @@ import com.dbnt.kcscbackend.admin.boards.entity.TnBbs; import org.springframework.data.jpa.repository.JpaRepository; import java.util.List; +import java.util.Optional; public interface TnBbsRepository extends JpaRepository { List findAllByOrderByBbsSeqDesc(); + Optional findByBbsId(String bbsId); + } diff --git a/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/boards/service/AdminBoardsService.java b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/boards/service/AdminBoardsService.java index d8ba319..9bd1902 100644 --- a/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/boards/service/AdminBoardsService.java +++ b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/boards/service/AdminBoardsService.java @@ -2,6 +2,7 @@ package com.dbnt.kcscbackend.admin.boards.service; import com.dbnt.kcscbackend.admin.boards.entity.TnBbs; import com.dbnt.kcscbackend.admin.boards.entity.TnBbsContents; +import com.dbnt.kcscbackend.admin.boards.mapper.AdminBoardsMapper; import com.dbnt.kcscbackend.admin.boards.repository.TnBbsContentsRepository; import com.dbnt.kcscbackend.admin.boards.repository.TnBbsRepository; import com.dbnt.kcscbackend.admin.config.entity.TcMenu; @@ -17,9 +18,7 @@ import org.springframework.web.multipart.MultipartFile; import javax.servlet.http.HttpServletRequest; import java.text.SimpleDateFormat; import java.time.LocalDateTime; -import java.util.Date; -import java.util.List; -import java.util.Optional; +import java.util.*; @Service @RequiredArgsConstructor @@ -27,12 +26,20 @@ public class AdminBoardsService extends EgovAbstractServiceImpl { private final TnBbsRepository tnBbsRepository; private final TnBbsContentsRepository tnBbsContentsRepository; + private final AdminBoardsMapper adminBoardsMapper; private final FileService fileService; public List selectBoardList() { return tnBbsRepository.findAllByOrderByBbsSeqDesc(); } + public String checkDuplicate(String bbsId) { + Optional result = tnBbsRepository.findByBbsId(bbsId); + String duplicateYn = result.isPresent() ? "Y" : "N"; + System.out.println("@@@ duplicateYn : " + duplicateYn); + return duplicateYn; + } + @Transactional public void saveBoard(TnBbs bbs, String userId) { if (bbs.getBbsSeq() == null) { @@ -57,21 +64,26 @@ public class AdminBoardsService extends EgovAbstractServiceImpl { } @Transactional - public String deleteBoard(TnBbs bbs, String userId) { + public String deleteBoard(TnBbs bbs) { TnBbs savedBoard = tnBbsRepository.findById(bbs.getBbsSeq()).orElse(null); if (savedBoard == null) { return "notFind"; } else { - savedBoard.setUseYn("N"); - savedBoard.setLastChgDt(LocalDateTime.now()); - savedBoard.setLastChgId(userId); - tnBbsRepository.save(savedBoard); + tnBbsRepository.deleteById(bbs.getBbsSeq()); return null; } } - public List selectPostList() { - return tnBbsContentsRepository.findAll(); + public Map selectPostList(TnBbsContents params) { + Map resultMap = new HashMap<>(); + + params.setFixedYn("N"); + resultMap.put("postList", adminBoardsMapper.selectPostList(params)); + resultMap.put("resultCnt", String.valueOf(adminBoardsMapper.selectPostListCnt(params))); + + params.setFixedYn("Y"); + resultMap.put("fixedList", adminBoardsMapper.selectPostList(params)); + return resultMap; } /** @@ -155,16 +167,12 @@ public class AdminBoardsService extends EgovAbstractServiceImpl { } @Transactional - public String deletePost(TnBbsContents contents, String userId) { + public String deletePost(TnBbsContents contents) { TnBbsContents savedPost = tnBbsContentsRepository.findById(contents.getBbsContSeq()).orElse(null); if (savedPost == null) { return "notFind"; } else { - savedPost.setIpAddress(contents.getIpAddress()); - savedPost.setUseYn("N"); - savedPost.setLastChgDt(LocalDateTime.now()); - savedPost.setLastChgId(userId); - tnBbsContentsRepository.save(savedPost); + tnBbsContentsRepository.deleteById(contents.getBbsContSeq()); return null; } } diff --git a/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/committee/AdminCommitteeController.java b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/committee/AdminCommitteeController.java index 5aac4b0..82c0a8c 100644 --- a/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/committee/AdminCommitteeController.java +++ b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/committee/AdminCommitteeController.java @@ -1,38 +1,23 @@ package com.dbnt.kcscbackend.admin.committee; import com.dbnt.kcscbackend.admin.committee.service.AdminCommitteeProgressStatusService; -import com.dbnt.kcscbackend.admin.config.entity.TcMenu; -import com.dbnt.kcscbackend.admin.config.entity.TnPartnerSite; -import com.dbnt.kcscbackend.admin.config.model.CreateCommitteeCodeManagementVO; -import com.dbnt.kcscbackend.admin.config.model.SetCommitteeCodeManagementVO; -import com.dbnt.kcscbackend.admin.config.service.AdminCommitteeCodeManagementService; -import com.dbnt.kcscbackend.admin.config.service.AdminConfigService; +import com.dbnt.kcscbackend.admin.config.service.ConfigService; import com.dbnt.kcscbackend.auth.entity.LoginVO; -import com.dbnt.kcscbackend.commonCode.entity.TcCodeGrp; -import com.dbnt.kcscbackend.commonCode.entity.TcCodeItem; import com.dbnt.kcscbackend.commonCode.service.CommonCodeService; import com.dbnt.kcscbackend.config.common.BaseController; import com.dbnt.kcscbackend.config.common.ResponseCode; import com.dbnt.kcscbackend.config.common.ResultVO; -import io.swagger.annotations.ApiParam; 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.data.domain.Pageable; -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.*; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; -import javax.validation.Valid; -import java.time.LocalDateTime; -import java.util.HashMap; -import java.util.Map; @RestController @RequiredArgsConstructor @@ -40,7 +25,7 @@ import java.util.Map; @Tag(name="AdminCommitteeController", description = "사이트관리 위원회관리 메뉴 컨트롤러") public class AdminCommitteeController extends BaseController { - private final AdminConfigService adminConfigService; + private final ConfigService configService; private final CommonCodeService commonCodeService; @Resource(name = "adminCommitteeProgressStatusService") diff --git a/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/config/AdminConfigController.java b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/config/AdminConfigController.java index 92412e5..e0f2970 100644 --- a/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/config/AdminConfigController.java +++ b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/config/AdminConfigController.java @@ -7,12 +7,14 @@ import com.dbnt.kcscbackend.admin.config.model.SetCommitteeCodeManagementVO; import com.dbnt.kcscbackend.admin.config.service.AdminCommitteeCodeManagementService; import com.dbnt.kcscbackend.commonCode.entity.TcCodeGrp; import com.dbnt.kcscbackend.commonCode.entity.TcCodeItem; -import com.dbnt.kcscbackend.admin.config.service.AdminConfigService; +import com.dbnt.kcscbackend.admin.config.service.ConfigService; import com.dbnt.kcscbackend.auth.entity.LoginVO; import com.dbnt.kcscbackend.commonCode.service.CommonCodeService; 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.file.entity.TnAttachFile; +import com.dbnt.kcscbackend.file.service.FileService; import io.swagger.annotations.ApiParam; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.responses.ApiResponse; @@ -24,12 +26,19 @@ import org.springframework.security.core.annotation.AuthenticationPrincipal; import org.springframework.validation.Errors; import org.springframework.validation.FieldError; import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; import javax.validation.Valid; +import java.io.BufferedOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.InputStream; import java.time.LocalDateTime; import java.util.HashMap; +import java.util.List; import java.util.Map; @RestController @@ -38,8 +47,9 @@ import java.util.Map; @Tag(name="AdminConfigController", description = "사이트관리 환결설정 메뉴 컨트롤러") public class AdminConfigController extends BaseController { - private final AdminConfigService adminConfigService; + private final ConfigService configService; private final CommonCodeService commonCodeService; + private final FileService fileService; @Resource(name = "adminCommitteeCodeManagementService") private AdminCommitteeCodeManagementService adminCommitteeCodeManagementService; @@ -53,11 +63,11 @@ public class AdminConfigController extends BaseController { @ApiResponse(responseCode = "200", description = "조회 성공"), @ApiResponse(responseCode = "403", description = "인가된 사용자가 아님") }) - @RequestMapping(method = RequestMethod.GET, value = "/code-grp") + @RequestMapping(method = RequestMethod.GET, value = "/base-code-mgt/code-grp") public ResultVO getCodeGrp() throws Exception{ ResultVO resultVO = new ResultVO(); Map resultMap = new HashMap<>(); - resultMap.put("codeGrpList", adminConfigService.selectCodeGrpList()); + resultMap.put("codeGrpList", configService.selectCodeGrpList()); resultVO.setResult(resultMap); return resultVO; } @@ -72,7 +82,7 @@ public class AdminConfigController extends BaseController { @ApiResponse(responseCode = "303", description = "만료된 토큰"), @ApiResponse(responseCode = "403", description = "인가된 사용자가 아님") }) - @RequestMapping(method = RequestMethod.POST, value = "/code-grp", consumes = MediaType.APPLICATION_JSON_VALUE) + @RequestMapping(method = RequestMethod.POST, value = "/base-code-mgt/code-grp", consumes = MediaType.APPLICATION_JSON_VALUE) public ResultVO addCodeGrp(@RequestBody TcCodeGrp codeGrp, @AuthenticationPrincipal LoginVO user) throws Exception{ ResultVO resultVO = new ResultVO(); if(user == null){ @@ -88,7 +98,7 @@ public class AdminConfigController extends BaseController { codeGrp.setFrstCrtDt(LocalDateTime.now()); codeGrp.setFrstCrtId(user.getId()); codeGrp.setUseYn("Y"); - String result = adminConfigService.addCodeGrp(codeGrp); + String result = configService.addCodeGrp(codeGrp); if(result.equals("isSaved")){ resultVO.setResultCode(ResponseCode.SAVE_ERROR.getCode()); resultVO.setResultMessage("중복되는 코드그룹이 있습니다."); @@ -110,7 +120,7 @@ public class AdminConfigController extends BaseController { @ApiResponse(responseCode = "303", description = "만료된 토큰"), @ApiResponse(responseCode = "403", description = "인가된 사용자가 아님") }) - @RequestMapping(method = RequestMethod.PUT, value = "/code-grp", consumes = MediaType.APPLICATION_JSON_VALUE) + @RequestMapping(method = RequestMethod.PUT, value = "/base-code-mgt/code-grp", consumes = MediaType.APPLICATION_JSON_VALUE) public ResultVO modifyCodeGrp(@RequestBody TcCodeGrp codeGrp, @AuthenticationPrincipal LoginVO user) throws Exception{ ResultVO resultVO = new ResultVO(); if(user == null){ @@ -125,7 +135,7 @@ public class AdminConfigController extends BaseController { }else{ codeGrp.setLastChgDt(LocalDateTime.now()); codeGrp.setLastChgId(user.getId()); - String result = adminConfigService.modifyCodeGrp(codeGrp); + String result = configService.modifyCodeGrp(codeGrp); if(result.equals("modified")){ resultVO.setResultCode(ResponseCode.SUCCESS.getCode()); }else{ @@ -145,11 +155,11 @@ public class AdminConfigController extends BaseController { @ApiResponse(responseCode = "200", description = "조회 성공"), @ApiResponse(responseCode = "403", description = "인가된 사용자가 아님") }) - @RequestMapping(method = RequestMethod.GET, value = "/code-item") + @RequestMapping(method = RequestMethod.GET, value = "/base-code-mgt/code-item") public ResultVO getCodeItem(String grpCd) throws Exception{ ResultVO resultVO = new ResultVO(); Map resultMap = new HashMap<>(); - resultMap.put("codeItemList", adminConfigService.selectCodeItemList(grpCd)); + resultMap.put("codeItemList", configService.selectCodeItemList(grpCd)); resultVO.setResult(resultMap); return resultVO; } @@ -164,7 +174,7 @@ public class AdminConfigController extends BaseController { @ApiResponse(responseCode = "303", description = "만료된 토큰"), @ApiResponse(responseCode = "403", description = "인가된 사용자가 아님") }) - @RequestMapping(method = RequestMethod.POST, value = "/code-item", consumes = MediaType.APPLICATION_JSON_VALUE) + @RequestMapping(method = RequestMethod.POST, value = "/base-code-mgt/code-item", consumes = MediaType.APPLICATION_JSON_VALUE) public ResultVO addCodeItem(@RequestBody TcCodeItem codeItem, @AuthenticationPrincipal LoginVO user) throws Exception{ ResultVO resultVO = new ResultVO(); if(user == null){ @@ -180,7 +190,7 @@ public class AdminConfigController extends BaseController { codeItem.setFrstCrtDt(LocalDateTime.now()); codeItem.setFrstCrtId(user.getId()); codeItem.setUseYn("Y"); - String result = adminConfigService.addCodeItem(codeItem); + String result = configService.addCodeItem(codeItem); if(result.equals("isSaved")){ resultVO.setResultCode(ResponseCode.SAVE_ERROR.getCode()); resultVO.setResultMessage("중복되는 코드가 있습니다."); @@ -202,7 +212,7 @@ public class AdminConfigController extends BaseController { @ApiResponse(responseCode = "303", description = "만료된 토큰"), @ApiResponse(responseCode = "403", description = "인가된 사용자가 아님") }) - @RequestMapping(method = RequestMethod.PUT, value = "/code-item", consumes = MediaType.APPLICATION_JSON_VALUE) + @RequestMapping(method = RequestMethod.PUT, value = "/base-code-mgt/code-item", consumes = MediaType.APPLICATION_JSON_VALUE) public ResultVO modifyCodeItem(@RequestBody TcCodeItem codeItem, @AuthenticationPrincipal LoginVO user) throws Exception{ ResultVO resultVO = new ResultVO(); if(user == null){ @@ -217,7 +227,7 @@ public class AdminConfigController extends BaseController { }else{ codeItem.setLastChgDt(LocalDateTime.now()); codeItem.setLastChgId(user.getId()); - String result = adminConfigService.modifyCodeItem(codeItem); + String result = configService.modifyCodeItem(codeItem); if(result.equals("modified")){ resultVO.setResultCode(ResponseCode.SUCCESS.getCode()); }else{ @@ -241,7 +251,7 @@ public class AdminConfigController extends BaseController { public ResultVO getMenuMgt(){ ResultVO resultVO = new ResultVO(); Map resultMap = new HashMap<>(); - resultMap.put("menuList", adminConfigService.selectMenuList()); + resultMap.put("menuList", configService.selectMenuList()); resultVO.setResult(resultMap); return resultVO; } @@ -274,7 +284,7 @@ public class AdminConfigController extends BaseController { resultVO.setResultCode(ResponseCode.AUTH_ERROR.getCode()); resultVO.setResultMessage(ResponseCode.AUTH_ERROR.getMessage()); } else { - adminConfigService.saveMenu(menu, user.getId()); + configService.saveMenu(menu, user.getId()); resultVO.setResultCode(ResponseCode.SUCCESS.getCode()); } } @@ -300,7 +310,7 @@ public class AdminConfigController extends BaseController { resultVO.setResultCode(ResponseCode.AUTH_ERROR.getCode()); resultVO.setResultMessage(ResponseCode.AUTH_ERROR.getMessage()); } else { - String result = adminConfigService.deleteMenu(menu.getMenuId(), user.getId()); + String result = configService.deleteMenu(menu.getMenuId(), user.getId()); if(result==null){ resultVO.setResultCode(ResponseCode.SUCCESS.getCode()); }else if(result.equals("notFind")){ @@ -325,7 +335,7 @@ public class AdminConfigController extends BaseController { public ResultVO getMenuAuthMgt(){ ResultVO resultVO = new ResultVO(); Map resultMap = new HashMap<>(); - resultMap.put("menuList", adminConfigService.selectMenuAuthList()); + resultMap.put("menuList", configService.selectMenuAuthList()); resultMap.put("roleList", commonCodeService.selectCodeItemList("ROLE")); resultVO.setResult(resultMap); return resultVO; @@ -350,7 +360,7 @@ public class AdminConfigController extends BaseController { resultVO.setResultCode(ResponseCode.AUTH_ERROR.getCode()); resultVO.setResultMessage(ResponseCode.AUTH_ERROR.getMessage()); } else { - adminConfigService.editMenuAuth(menu); + configService.editMenuAuth(menu); resultVO.setResultCode(ResponseCode.SUCCESS.getCode()); } } @@ -367,7 +377,7 @@ public class AdminConfigController extends BaseController { @ApiResponse(responseCode = "303", description = "만료된 토큰"), @ApiResponse(responseCode = "403", description = "인가된 사용자가 아님") }) - @GetMapping(value = "/committee-code-management") + @GetMapping(value = "/committee-code-mgt") public ResultVO getCommitteeCodeManagement( @AuthenticationPrincipal LoginVO user, HttpServletRequest request, @@ -414,7 +424,7 @@ public class AdminConfigController extends BaseController { @ApiResponse(responseCode = "303", description = "만료된 토큰"), @ApiResponse(responseCode = "403", description = "인가된 사용자가 아님") }) - @PostMapping(value = "/committee-code-management") + @PostMapping(value = "/committee-code-mgt") public ResultVO createCommitteeCodeManagement( @AuthenticationPrincipal LoginVO user, HttpServletRequest request, @@ -454,7 +464,7 @@ public class AdminConfigController extends BaseController { @ApiResponse(responseCode = "200", description = "등록 성공"), @ApiResponse(responseCode = "403", description = "인가된 사용자가 아님") }) - @DeleteMapping(value = "/committee-code-management/{orgId}") + @DeleteMapping(value = "/committee-code-mgt/{orgId}") public ResultVO deleteSchedule ( @AuthenticationPrincipal LoginVO user, @@ -496,16 +506,67 @@ public class AdminConfigController extends BaseController { @ApiResponse(responseCode = "200", description = "조회 성공"), @ApiResponse(responseCode = "403", description = "인가된 사용자가 아님") }) - @RequestMapping(method = RequestMethod.GET, value = "/partner-site-list", consumes = MediaType.APPLICATION_JSON_VALUE) + @RequestMapping(method = RequestMethod.GET, value = "/about-site-mgt/list", consumes = MediaType.APPLICATION_JSON_VALUE) public ResultVO getPartnerSiteList() throws Exception { ResultVO resultVO = new ResultVO(); Map resultMap = new HashMap<>(); - - resultMap.put("partnerSiteList", adminConfigService.selectPartnerSiteList()); + List tnPartnerSite = configService.selectPartnerSiteList(); + for (TnPartnerSite partnerSite : tnPartnerSite) { + String fileGrpId = partnerSite.getFileGrpId(); + String filePath = fileService.findByFileGrpId(fileGrpId).get(0).getFilePath(); + partnerSite.setFilePath(filePath); + } + resultMap.put("partnerSiteList", tnPartnerSite); resultVO.setResult(resultMap); return resultVO; } + @Operation( + summary = "관련사이트 리스트 이미지", + description = "관련사이트 리스트 이미지", + tags = {"AdminConfigController"} + ) + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "저장 성공"), + @ApiResponse(responseCode = "403", description = "인가된 사용자가 아님") + }) + @RequestMapping(method = RequestMethod.GET, value = "/about-site-mgt/get-site-image") + public void getSiteImage(HttpServletResponse response, @RequestParam String fileGrpId) throws Exception { + List dbImgList = fileService.findByFileGrpId(fileGrpId); + String realFile = dbImgList.get(0).getFilePath(); + String fileNm = dbImgList.get(0).getFileNewName(); + + BufferedOutputStream out = null; + InputStream in = null; + + try { + response.setContentType("image/jpeg;charset=UTF-8"); + response.setHeader("Content-Disposition", "inline;filename=\"" + fileNm + "\""); + File file = new File(realFile); + if (file.exists()) { + in = new FileInputStream(file); + out = new BufferedOutputStream(response.getOutputStream()); + int len; + byte[] buf = new byte[1024]; + while ((len = in.read(buf)) > 0) { + out.write(buf, 0, len); + } + } + } catch (Exception e) { + + } finally { + if (out != null) { + out.flush(); + } + if (out != null) { + out.close(); + } + if (in != null) { + in.close(); + } + } + } + @Operation( summary = "관련사이트 저장", description = "관련사이트 저장", @@ -515,8 +576,13 @@ public class AdminConfigController extends BaseController { @ApiResponse(responseCode = "200", description = "저장 성공"), @ApiResponse(responseCode = "403", description = "인가된 사용자가 아님") }) - @RequestMapping(method = RequestMethod.PUT, value = "/partner-site-mgt") - public ResultVO savePartnerSite(@RequestBody @Valid TnPartnerSite tnPartnerSite, Errors errors, @AuthenticationPrincipal LoginVO user) { + @RequestMapping(method = RequestMethod.PUT, value = "/about-site-mgt/partner-site-mgt") + public ResultVO savePartnerSite( + @Valid TnPartnerSite tnPartnerSite, + HttpServletRequest request, + Errors errors, + @RequestParam(required = false) MultipartFile[] file, + @AuthenticationPrincipal LoginVO user) throws Exception { ResultVO resultVO = new ResultVO(); if (user == null) { resultVO.setResultCode(ResponseCode.TOKEN_EXPIRED.getCode()); @@ -531,7 +597,8 @@ public class AdminConfigController extends BaseController { resultVO.setResultMessage(msg.toString()); } else { System.out.println("@@@ bbs.getBbsSeq() : " + tnPartnerSite.getSiteSeq()); - adminConfigService.savePartnerSite(tnPartnerSite, user.getId()); + System.out.println("@@@ file : " + file); + configService.savePartnerSite(tnPartnerSite, request, user, file); resultVO.setResultCode(ResponseCode.SUCCESS.getCode()); } } @@ -547,13 +614,13 @@ public class AdminConfigController extends BaseController { @ApiResponse(responseCode = "200", description = "삭제 성공"), @ApiResponse(responseCode = "403", description = "인가된 사용자가 아님") }) - @RequestMapping(method = RequestMethod.DELETE, value = "/partner-site-mgt") + @RequestMapping(method = RequestMethod.DELETE, value = "/about-site-mgt/partner-site-mgt") public ResultVO removePartnerSite(@RequestBody TnPartnerSite tnPartnerSite, @AuthenticationPrincipal LoginVO user) { ResultVO resultVO = new ResultVO(); if (user == null) { resultVO.setResultCode(ResponseCode.TOKEN_EXPIRED.getCode()); } else { - String result = adminConfigService.deletePartnerSite(tnPartnerSite, user.getId()); + String result = configService.deletePartnerSite(tnPartnerSite, user.getId()); if (result == null) { resultVO.setResultCode(ResponseCode.SUCCESS.getCode()); } else if (result.equals("notFind")) { @@ -573,7 +640,7 @@ public class AdminConfigController extends BaseController { @ApiResponse(responseCode = "200", description = "등록 성공"), @ApiResponse(responseCode = "403", description = "인가된 사용자가 아님"), }) - @PutMapping(value = "/committee-code-management/{orgId}") + @PutMapping(value = "/committee-code-mgt/{orgId}") public ResultVO setCommitteeCodeManagement( HttpServletRequest request, @AuthenticationPrincipal LoginVO loginVO, diff --git a/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/config/entity/TbMenuRole.java b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/config/entity/TbMenuRole.java index 22e0205..81d889b 100644 --- a/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/config/entity/TbMenuRole.java +++ b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/config/entity/TbMenuRole.java @@ -28,6 +28,12 @@ public class TbMenuRole { @Column(name = "write_yn") private String writeYn; + public TbMenuRole(String roleId, String menuId, String writeYn) { + this.roleId = roleId; + this.menuId = menuId; + this.writeYn = writeYn; + } + @Embeddable @Data @NoArgsConstructor diff --git a/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/config/entity/TcMenu.java b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/config/entity/TcMenu.java index a310df2..4db653f 100644 --- a/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/config/entity/TcMenu.java +++ b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/config/entity/TcMenu.java @@ -10,6 +10,7 @@ import org.springframework.format.annotation.DateTimeFormat; import javax.persistence.*; import javax.validation.constraints.NotBlank; import java.time.LocalDateTime; +import java.util.List; @Getter @Setter @@ -53,9 +54,18 @@ public class TcMenu { @Column(name = "use_yn") private String useYn; + @Transient + private String groupTitle; + @Transient private String menuTypeValue; @Transient private String menuAuth; + + @Transient + private String role; + + @Transient + private List childList; } diff --git a/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/config/entity/TnPartnerSite.java b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/config/entity/TnPartnerSite.java index 3f5b1a8..aecd812 100644 --- a/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/config/entity/TnPartnerSite.java +++ b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/config/entity/TnPartnerSite.java @@ -35,4 +35,7 @@ public class TnPartnerSite { @Column(name = "use_yn", nullable = false, length = 1) private String useYn; + + @Transient + private String filePath; } diff --git a/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/config/mapper/TcMenuMapper.java b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/config/mapper/TcMenuMapper.java index c45db0d..1b85f0a 100644 --- a/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/config/mapper/TcMenuMapper.java +++ b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/config/mapper/TcMenuMapper.java @@ -11,4 +11,6 @@ public interface TcMenuMapper { List selectMenuList(); List selectMenuAuthList(); + + List selectMenuListToRole(TcMenu params); } diff --git a/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/config/service/AdminConfigService.java b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/config/service/ConfigService.java similarity index 75% rename from kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/config/service/AdminConfigService.java rename to kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/config/service/ConfigService.java index ba9a1a8..570324d 100644 --- a/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/config/service/AdminConfigService.java +++ b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/config/service/ConfigService.java @@ -1,6 +1,5 @@ package com.dbnt.kcscbackend.admin.config.service; -import com.dbnt.kcscbackend.admin.boards.entity.TnBbs; import com.dbnt.kcscbackend.admin.config.entity.TbMenuRole; import com.dbnt.kcscbackend.admin.config.entity.TcMenu; import com.dbnt.kcscbackend.admin.config.entity.TnPartnerSite; @@ -8,23 +7,30 @@ import com.dbnt.kcscbackend.admin.config.mapper.TcMenuMapper; import com.dbnt.kcscbackend.admin.config.repository.TbMenuRoleRepository; import com.dbnt.kcscbackend.admin.config.repository.TcMenuRepository; import com.dbnt.kcscbackend.admin.config.repository.TnPartnerSiteRepository; +import com.dbnt.kcscbackend.auth.entity.LoginVO; import com.dbnt.kcscbackend.commonCode.entity.TcCodeGrp; import com.dbnt.kcscbackend.commonCode.entity.TcCodeItem; import com.dbnt.kcscbackend.commonCode.repository.TcCodeGrpRepository; import com.dbnt.kcscbackend.commonCode.repository.TcCodeItemRepository; +import com.dbnt.kcscbackend.file.entity.TnAttachFile; +import com.dbnt.kcscbackend.file.service.FileService; import lombok.RequiredArgsConstructor; import org.egovframe.rte.fdl.cmmn.EgovAbstractServiceImpl; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.multipart.MultipartFile; +import javax.servlet.http.HttpServletRequest; +import java.text.SimpleDateFormat; import java.time.LocalDateTime; import java.util.ArrayList; +import java.util.Date; import java.util.List; import java.util.Optional; @Service @RequiredArgsConstructor -public class AdminConfigService extends EgovAbstractServiceImpl { +public class ConfigService extends EgovAbstractServiceImpl { private final TcCodeGrpRepository codeGrpRepository; private final TcCodeItemRepository codeItemRepository; @@ -32,6 +38,7 @@ public class AdminConfigService extends EgovAbstractServiceImpl { private final TbMenuRoleRepository menuRoleRepository; private final TcMenuMapper menuMapper; private final TnPartnerSiteRepository tnPartnerSiteRepository; + private final FileService fileService; public List selectCodeGrpList(){ return codeGrpRepository.findByUseYn("Y"); @@ -123,6 +130,7 @@ public class AdminConfigService extends EgovAbstractServiceImpl { menu.setFrstCrtId(userId); menu.setUseYn("Y"); menuRepository.save(menu); + menuRoleRepository.save(new TbMenuRole("ROLE_001", menu.getMenuId(), "Y")); }else{ savedMenu.setMenuTitle(menu.getMenuTitle()); savedMenu.setMenuGroup(menu.getMenuGroup()); @@ -154,6 +162,14 @@ public class AdminConfigService extends EgovAbstractServiceImpl { return menuMapper.selectMenuAuthList(); } + + public List selectMenuListToRole(String menuTypeCd, String role){ + TcMenu params = new TcMenu(); + params.setMenuTypeCd(menuTypeCd); + params.setRole(role); + return menuMapper.selectMenuListToRole(params); + } + @Transactional public void editMenuAuth(TcMenu menu) { String[] roleAry = menu.getMenuAuth().split(","); @@ -175,17 +191,47 @@ public class AdminConfigService extends EgovAbstractServiceImpl { return tnPartnerSiteRepository.findAllByOrderBySiteOrder(); } - @Transactional - public void savePartnerSite(TnPartnerSite tnPartnerSite, String userId) { + /** + * 파일이 저장될 중간 경로를 생성한다. + * D:/kcscUploadFiles/XXXX/abc.jpg XXXX에 해당하는 경로다. + * + * @return 중간 경로 + */ + private String getMiddlePath() { + //파일이 저장될 경로를 생성한다. + String domainPath = "partnerSite"; + Date nowDate = new Date(); + String strNowYyyy = new SimpleDateFormat("yyyy").format(nowDate); + String strNowYyyyMmdd = new SimpleDateFormat("yyyyMMdd").format(nowDate); + String middlePath = domainPath + "/" + strNowYyyy + "/" + strNowYyyyMmdd + "/"; + + return middlePath; + } + + public void savePartnerSite(TnPartnerSite tnPartnerSite, HttpServletRequest request, LoginVO user, MultipartFile[] file) throws Exception { if (tnPartnerSite.getSiteSeq() == null) { + String fileGrpId = fileService.addTnAttachFile(request, user, file, this.getMiddlePath()); + tnPartnerSite.setFileGrpId(fileGrpId); tnPartnerSiteRepository.save(tnPartnerSite); } else { + String fileGrpId = tnPartnerSite.getFileGrpId(); + System.out.println("@@@ fileGrpId : " + fileGrpId); + if (file != null && file.length > 0) { + List tnAttachFileList = fileService.findByFileGrpId(fileGrpId); + if (tnAttachFileList != null) { + for (TnAttachFile item : tnAttachFileList) { + fileService.deleteTnAttachFile(request, user, item.getFileSeq().longValue()); + } + } + fileGrpId = fileService.addTnAttachFile(request, user, file, this.getMiddlePath()); + } TnPartnerSite savedPartnerSite = tnPartnerSiteRepository.findById(tnPartnerSite.getSiteSeq()).orElse(null); savedPartnerSite.setSiteTitle(tnPartnerSite.getSiteTitle()); savedPartnerSite.setSiteUrl(tnPartnerSite.getSiteUrl()); savedPartnerSite.setFileGrpId(tnPartnerSite.getFileGrpId()); savedPartnerSite.setSiteOrder(tnPartnerSite.getSiteOrder()); savedPartnerSite.setUseYn(tnPartnerSite.getUseYn()); + savedPartnerSite.setFileGrpId(fileGrpId); tnPartnerSiteRepository.save(savedPartnerSite); } } diff --git a/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/contents/survey/AdminSurveyController.java b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/contents/survey/AdminSurveyController.java index 280f10b..106b893 100644 --- a/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/contents/survey/AdminSurveyController.java +++ b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/contents/survey/AdminSurveyController.java @@ -24,7 +24,7 @@ import java.util.Map; @RestController @RequiredArgsConstructor -@RequestMapping("/admin/survey") +@RequestMapping("/admin/contents/survey") public class AdminSurveyController { private final AdminSurveyService adminSurveyService; diff --git a/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/leftNav/LeftNavController.java b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/leftNav/LeftNavController.java new file mode 100644 index 0000000..ff89e0b --- /dev/null +++ b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/leftNav/LeftNavController.java @@ -0,0 +1,62 @@ +package com.dbnt.kcscbackend.admin.leftNav; + + +import com.dbnt.kcscbackend.admin.config.entity.TcMenu; +import com.dbnt.kcscbackend.admin.config.service.ConfigService; +import com.dbnt.kcscbackend.admin.users.service.UsersService; +import com.dbnt.kcscbackend.auth.entity.LoginVO; +import com.dbnt.kcscbackend.config.common.ResultVO; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; +import org.springframework.security.core.annotation.AuthenticationPrincipal; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import java.util.*; + +@RestController +@RequiredArgsConstructor +@RequestMapping("/leftNav") +@Tag(name="LeftNavController", description = "leftNav 컨트롤러") +public class LeftNavController { + + private final ConfigService configService; + private final UsersService usersService; + + @RequestMapping(method = RequestMethod.GET, value = "/menu") + public ResultVO getMenu( + @AuthenticationPrincipal LoginVO user, + @RequestParam(value="menuType", required = true) String menuTypeCd + ){ + ResultVO resultVO = new ResultVO(); + String userRole = usersService.selectUserInfo(user.getUserSeq()).getUserRole(); + List menuList = configService.selectMenuListToRole(menuTypeCd, userRole); + Map groupMap = new LinkedHashMap<>(); + for(TcMenu menu: menuList){ + groupMap.put(menu.getMenuGroup(), menu.getGroupTitle()); + } + List groupList = new ArrayList<>(); + for(Map.Entry group: groupMap.entrySet()){ + TcMenu temp = new TcMenu(); + temp.setMenuId(group.getKey()); + temp.setMenuTitle(group.getValue()); + groupList.add(temp); + } + for(TcMenu group: groupList){ + for(TcMenu menu: menuList){ + if(group.getMenuId().equals(menu.getMenuGroup())){ + if(group.getChildList()==null){ + group.setChildList(new ArrayList<>()); + } + group.getChildList().add(menu); + } + } + } + Map resultMap = new HashMap<>(); + resultMap.put("menuList", groupList); + resultVO.setResult(resultMap); + return resultVO; + } +} diff --git a/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/logs/AdminLogsController.java b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/logs/AdminLogsController.java index a1c5c36..a91bdb7 100644 --- a/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/logs/AdminLogsController.java +++ b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/logs/AdminLogsController.java @@ -41,7 +41,7 @@ public class AdminLogsController extends BaseController { @ApiResponse(responseCode = "200", description = "조회 성공"), @ApiResponse(responseCode = "403", description = "인가된 사용자가 아님") }) - @RequestMapping(method = RequestMethod.POST, value = "/menu", consumes = MediaType.APPLICATION_JSON_VALUE) + @RequestMapping(method = RequestMethod.POST, value = "/menu-access-info", consumes = MediaType.APPLICATION_JSON_VALUE) public ResultVO MenuListCount(@RequestBody Map dateRange, @AuthenticationPrincipal LoginVO user) throws Exception { @@ -70,7 +70,7 @@ public class AdminLogsController extends BaseController { @ApiResponse(responseCode = "200", description = "조회 성공"), @ApiResponse(responseCode = "403", description = "인가된 사용자가 아님") }) - @RequestMapping(method = RequestMethod.POST, value = "/user", consumes = MediaType.APPLICATION_JSON_VALUE) + @RequestMapping(method = RequestMethod.POST, value = "/user-connections", consumes = MediaType.APPLICATION_JSON_VALUE) public ResultVO UserListCount(@RequestBody Map dateRange, @AuthenticationPrincipal LoginVO user) throws Exception { @@ -99,7 +99,7 @@ public class AdminLogsController extends BaseController { @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-logs", consumes = MediaType.APPLICATION_JSON_VALUE) public ResultVO selectPrivacyLogsList(@RequestBody ThPrivacyLog thPrivacyLog, @AuthenticationPrincipal LoginVO user) throws Exception { @@ -127,7 +127,7 @@ public class AdminLogsController extends BaseController { @ApiResponse(responseCode = "200", description = "조회 성공"), @ApiResponse(responseCode = "403", description = "인가된 사용자가 아님") }) - @RequestMapping(method = RequestMethod.POST, value = "/file", consumes = MediaType.APPLICATION_JSON_VALUE) + @RequestMapping(method = RequestMethod.POST, value = "/file-download-status", consumes = MediaType.APPLICATION_JSON_VALUE) public ResultVO FileListCount(@RequestBody Map dateRange, @AuthenticationPrincipal LoginVO user) throws Exception { diff --git a/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/standards/AdminStandardsController.java b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/standards/AdminStandardsController.java index d0dc80c..17402fa 100644 --- a/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/standards/AdminStandardsController.java +++ b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/standards/AdminStandardsController.java @@ -38,7 +38,7 @@ public class AdminStandardsController extends BaseController { @ApiResponse(responseCode = "200", description = "조회 성공"), @ApiResponse(responseCode = "403", description = "인가된 사용자가 아님") }) - @RequestMapping(method = RequestMethod.POST, value = "/apikey", consumes = MediaType.APPLICATION_JSON_VALUE) + @RequestMapping(method = RequestMethod.POST, value = "/api-keys", consumes = MediaType.APPLICATION_JSON_VALUE) public ResultVO selectApiList(@RequestBody TnApiKey tnApiKey, @AuthenticationPrincipal LoginVO user) throws Exception { @@ -66,7 +66,7 @@ public class AdminStandardsController extends BaseController { @ApiResponse(responseCode = "303", description = "만료된 토큰"), @ApiResponse(responseCode = "403", description = "인가된 사용자가 아님") }) - @RequestMapping(method = RequestMethod.POST, value = "/apiupdate", consumes = MediaType.APPLICATION_JSON_VALUE) + @RequestMapping(method = RequestMethod.POST, value = "/api-keys/api-update", consumes = MediaType.APPLICATION_JSON_VALUE) public ResultVO modifyApi(@RequestBody TnApiKey tnApiKey, @AuthenticationPrincipal LoginVO user) throws Exception{ ResultVO resultVO = new ResultVO(); @@ -92,7 +92,7 @@ public class AdminStandardsController extends BaseController { @ApiResponse(responseCode = "303", description = "만료된 토큰"), @ApiResponse(responseCode = "403", description = "인가된 사용자가 아님") }) - @RequestMapping(method = RequestMethod.POST, value = "/apiDailyChart", consumes = MediaType.APPLICATION_JSON_VALUE) + @RequestMapping(method = RequestMethod.POST, value = "/api-keys/api-daily-chart", consumes = MediaType.APPLICATION_JSON_VALUE) public ResultVO ApiChart(@RequestBody Map dateRange, @AuthenticationPrincipal LoginVO user) throws Exception{ ResultVO resultVO = new ResultVO(); Map resultMap = new HashMap<>(); diff --git a/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/users/AdminUsersController.java b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/users/AdminUsersController.java index 83f6025..4559ef6 100644 --- a/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/users/AdminUsersController.java +++ b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/users/AdminUsersController.java @@ -2,9 +2,10 @@ package com.dbnt.kcscbackend.admin.users; import com.dbnt.kcscbackend.admin.logs.service.AdminLogsService; -import com.dbnt.kcscbackend.admin.users.service.AdminUsersService; +import com.dbnt.kcscbackend.admin.users.service.UsersService; import com.dbnt.kcscbackend.auth.entity.LoginVO; import com.dbnt.kcscbackend.auth.entity.UserInfo; +import com.dbnt.kcscbackend.commonCode.service.CmtService; import com.dbnt.kcscbackend.commonCode.service.CommonCodeService; import com.dbnt.kcscbackend.config.common.BaseController; import com.dbnt.kcscbackend.config.common.ResponseCode; @@ -35,9 +36,10 @@ import java.util.Map; @Tag(name="AdminConfigController", description = "사이트관리 사용자관리 메뉴 컨트롤러") public class AdminUsersController extends BaseController { - private final AdminUsersService adminUsersService; + private final UsersService usersService; private final AdminLogsService adminLogsService; private final CommonCodeService commonCodeService; + private final CmtService cmtService; @Operation( summary = "사용자 목록 조회", @@ -48,15 +50,16 @@ public class AdminUsersController extends BaseController { @ApiResponse(responseCode = "200", description = "조회 성공"), @ApiResponse(responseCode = "403", description = "인가된 사용자가 아님") }) - @RequestMapping(method = RequestMethod.GET, value = "/list") + @RequestMapping(method = RequestMethod.GET, value = "/mgt/list") public ResultVO getUserList(UserInfo params, HttpServletRequest request, @AuthenticationPrincipal LoginVO user) throws Exception{ adminLogsService.insertPrivacyLog(user.getId(), ClientUtils.getRemoteIP(request), "PRV_LIST", null); ResultVO resultVO = new ResultVO(); Map resultMap = new HashMap<>(); params.setQueryInfo(); resultMap.put("userSeOption", commonCodeService.selectCodeItemList("ACC_TYPE")); - resultMap.put("userList", adminUsersService.selectUserList(params)); - params.setContentCnt(adminUsersService.selectUserListCnt(params)); + resultMap.put("cmtList", cmtService.selectCmtOrgList()); + resultMap.put("userList", usersService.selectUserList(params)); + params.setContentCnt(usersService.selectUserListCnt(params)); params.setPaginationInfo(); resultMap.put("paginationInfo", params); resultVO.setResult(resultMap); @@ -72,7 +75,7 @@ public class AdminUsersController extends BaseController { @ApiResponse(responseCode = "200", description = "조회 성공"), @ApiResponse(responseCode = "403", description = "인가된 사용자가 아님") }) - @RequestMapping(method = RequestMethod.GET, value = "/info") + @RequestMapping(method = RequestMethod.GET, value = "/mgt/info") public ResultVO getUserInfo(UserInfo params, HttpServletRequest request, @AuthenticationPrincipal LoginVO user) throws Exception{ adminLogsService.insertPrivacyLog(user.getId(), ClientUtils.getRemoteIP(request), "PRV_VIEW", params.getUserId()); ResultVO resultVO = new ResultVO(); @@ -91,7 +94,7 @@ public class AdminUsersController extends BaseController { @ApiResponse(responseCode = "200", description = "수정 성공"), @ApiResponse(responseCode = "403", description = "인가된 사용자가 아님") }) - @RequestMapping(method = RequestMethod.PUT, value = "/info") + @RequestMapping(method = RequestMethod.PUT, value = "/mgt/info") public ResultVO modifyUserInfo(@RequestBody @Valid UserInfo info, Errors errors, HttpServletRequest request, @AuthenticationPrincipal LoginVO user) throws Exception{ adminLogsService.insertPrivacyLog(user.getId(), ClientUtils.getRemoteIP(request), "PRV_UPDT", info.getUserId()); ResultVO resultVO = new ResultVO(); @@ -107,7 +110,7 @@ public class AdminUsersController extends BaseController { resultVO.setResultCode(ResponseCode.SAVE_ERROR.getCode()); resultVO.setResultMessage("비밀번호 확인이 잘못 입력되었습니다."); }else { - Integer insertResult = adminUsersService.updateUserInfo(info, user.getId()); + Integer insertResult = usersService.updateUserInfo(info, user.getId()); if(insertResult!=null){ if(insertResult==-1){ resultVO.setResultCode(ResponseCode.SAVE_ERROR.getCode()); @@ -136,11 +139,11 @@ public class AdminUsersController extends BaseController { @ApiResponse(responseCode = "200", description = "삭제 성공"), @ApiResponse(responseCode = "403", description = "인가된 사용자가 아님") }) - @RequestMapping(method = RequestMethod.DELETE, value = "/info", consumes = MediaType.APPLICATION_JSON_VALUE) + @RequestMapping(method = RequestMethod.DELETE, value = "/mgt/info", consumes = MediaType.APPLICATION_JSON_VALUE) public ResultVO deleteUserInfo(@RequestBody UserInfo info, HttpServletRequest request, @AuthenticationPrincipal LoginVO user) throws Exception{ adminLogsService.insertPrivacyLog(user.getId(), ClientUtils.getRemoteIP(request), "PRV_DLT", info.getUserId()); ResultVO resultVO = new ResultVO(); - adminUsersService.deleteUserInfo(info.getUserSeq()); + usersService.deleteUserInfo(info.getUserSeq()); resultVO.setResultCode(ResponseCode.SUCCESS.getCode()); return resultVO; } diff --git a/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/users/service/AdminUsersService.java b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/users/service/UsersService.java similarity index 93% rename from kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/users/service/AdminUsersService.java rename to kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/users/service/UsersService.java index ed940e4..d6f17f3 100644 --- a/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/users/service/AdminUsersService.java +++ b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/users/service/UsersService.java @@ -1,6 +1,5 @@ package com.dbnt.kcscbackend.admin.users.service; -import com.dbnt.kcscbackend.admin.logs.repository.PrivacyLogsRepository; import com.dbnt.kcscbackend.admin.users.mapper.AdminUsersMapper; import com.dbnt.kcscbackend.auth.entity.UserInfo; import com.dbnt.kcscbackend.auth.repository.UserInfoRepository; @@ -14,7 +13,7 @@ import java.util.List; @Service @RequiredArgsConstructor -public class AdminUsersService extends EgovAbstractServiceImpl { +public class UsersService extends EgovAbstractServiceImpl { private final UserInfoRepository userInfoRepository; private final AdminUsersMapper usersMapper; @@ -52,6 +51,7 @@ public class AdminUsersService extends EgovAbstractServiceImpl { savedInfo.setEmail(info.getEmail()); savedInfo.setPhoneNum(info.getPhoneNum()); savedInfo.setUserRole(info.getUserRole()); + savedInfo.setCmtOrg(info.getCmtOrg()); savedInfo.setStatus(info.getStatus()); savedInfo.setLastChgId(updateUser); savedInfo.setLastChgDt(LocalDateTime.now()); diff --git a/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/auth/EgovLoginApiController.java b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/auth/EgovLoginApiController.java index 3ffe480..dbc01e1 100644 --- a/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/auth/EgovLoginApiController.java +++ b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/auth/EgovLoginApiController.java @@ -1,5 +1,6 @@ package com.dbnt.kcscbackend.auth; +import com.dbnt.kcscbackend.admin.users.service.UsersService; import com.dbnt.kcscbackend.auth.entity.UserInfo; import com.dbnt.kcscbackend.auth.service.EgovLoginService; import com.dbnt.kcscbackend.config.common.BaseController; @@ -64,6 +65,7 @@ public class EgovLoginApiController extends BaseController { private final EgovJwtTokenUtil egovJwtTokenUtil; private final RefreshTokenRepository refreshTokenRepository; + private final UsersService usersService; @Operation( summary = "회원가입", @@ -151,7 +153,7 @@ public class EgovLoginApiController extends BaseController { String password = loginService.updateTempPassword(loginVO); if(password!=null){ resultMap.put("resultCode", ResponseCode.SUCCESS.getCode()); - resultMap.put("resultMessage", "비밀번호가 발급되었습니다.\n 새 비밀번호: "+password); + resultMap.put("resultMessage", "새 비밀번호가 발급되었습니다.\n "+password); }else{ resultMap.put("resultCode", ResponseCode.SAVE_ERROR.getCode()); resultMap.put("resultMessage", "조회에 실패하였습니다."); @@ -179,7 +181,8 @@ public class EgovLoginApiController extends BaseController { if (refreshToken != null){ String serverToken = refreshToken.getRefreshToken(); if(egovJwtTokenUtil.getUserSeFromToken(clientToken).equals(egovJwtTokenUtil.getUserSeFromToken(serverToken))){ - return egovJwtTokenUtil.getUserIdFromToken(clientToken).equals("admin"); + UserInfo user = usersService.selectUserInfo(Integer.parseInt(egovJwtTokenUtil.getUserSeqFromToken(clientToken))); + return user.getUserRole().equals("ROLE_001")||user.getUserRole().equals("ROLE_002")||user.getUserRole().equals("ROLE_003"); } } return false; diff --git a/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/auth/entity/LoginVO.java b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/auth/entity/LoginVO.java index 52b7c3d..125d4df 100644 --- a/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/auth/entity/LoginVO.java +++ b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/auth/entity/LoginVO.java @@ -61,6 +61,9 @@ public class LoginVO implements Serializable{ @Schema(description = "사용자 구분", allowableValues = {"ACC_TP01", "ACC_TP02"}, defaultValue = "ACC_TP02") private String userSe; + @Schema(description = "사용자 ROLE") + private String userRole; + @Schema(description = "이름") @NotBlank(message = "이름을 입력해주세요.") private String userNm; diff --git a/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/auth/entity/UserInfo.java b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/auth/entity/UserInfo.java index 6696f90..65b99d3 100644 --- a/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/auth/entity/UserInfo.java +++ b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/auth/entity/UserInfo.java @@ -57,6 +57,8 @@ public class UserInfo extends BoardParams implements UserDetails{ private String phoneNum; @Column(name = "user_role") private String userRole; + @Column(name = "cmt_org") + private Integer cmtOrg; @Column(name = "status") private String status; @Column(name = "frst_crt_dt") @@ -72,6 +74,8 @@ public class UserInfo extends BoardParams implements UserDetails{ private String passwordChk; @Transient private String statusValue; + @Transient + private String cmtOrgNm; @Override @JsonIgnore diff --git a/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/auth/service/impl/EgovLoginServiceImpl.java b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/auth/service/impl/EgovLoginServiceImpl.java index 1f07ead..832a746 100644 --- a/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/auth/service/impl/EgovLoginServiceImpl.java +++ b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/auth/service/impl/EgovLoginServiceImpl.java @@ -64,6 +64,7 @@ public class EgovLoginServiceImpl extends EgovAbstractServiceImpl implements Ego info.setEmail(loginVO.getEmail()); info.setPhoneNum(loginVO.getPhoneNum()); info.setUserSe("ACC_TP02"); + info.setUserRole("ROLE_005"); info.setStatus("USE_ST"); info.setFrstCrtDt(LocalDateTime.now()); userInfoRepository.save(info); diff --git a/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/commonCode/entity/TnCmtOrg.java b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/commonCode/entity/TnCmtOrg.java index 8e83ee1..dc272f8 100644 --- a/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/commonCode/entity/TnCmtOrg.java +++ b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/commonCode/entity/TnCmtOrg.java @@ -8,6 +8,8 @@ import org.springframework.format.annotation.DateTimeFormat; import javax.persistence.*; import java.io.Serializable; import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; @Getter @Setter @@ -57,6 +59,9 @@ public class TnCmtOrg { @Column(name = "old_seq") private Long oldSeq; + @Transient + private List childList = new ArrayList<>(); + @Embeddable @Data @NoArgsConstructor diff --git a/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/commonCode/repository/TnCmtOrgRepository.java b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/commonCode/repository/TnCmtOrgRepository.java index 11ced52..38d6990 100644 --- a/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/commonCode/repository/TnCmtOrgRepository.java +++ b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/commonCode/repository/TnCmtOrgRepository.java @@ -10,6 +10,8 @@ import java.util.List; import java.util.Map; public interface TnCmtOrgRepository extends JpaRepository { + + List findByUseYnOrderByCmtTypeAsc(String useYn); List findByUseYnAndUpCmtSeqOrderByCmtOrder(String useYn, Long upCmtSeq); TnCmtOrg findByUseYnAndCmtSeq(String useYn, Long cmtSeq); List findByUseYnAndUpCmtSeqAndCmtTypeOrderByCmtOrder(String useYn, Long upCmtSeq, String cmtType); diff --git a/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/commonCode/service/CmtService.java b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/commonCode/service/CmtService.java new file mode 100644 index 0000000..8cc0002 --- /dev/null +++ b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/commonCode/service/CmtService.java @@ -0,0 +1,37 @@ +package com.dbnt.kcscbackend.commonCode.service; + +import com.dbnt.kcscbackend.commonCode.entity.TnCmtOrg; +import com.dbnt.kcscbackend.commonCode.repository.TnCmtOrgRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.List; + +@Service +@RequiredArgsConstructor +public class CmtService { + private final TnCmtOrgRepository tnCmtOrgRepository; + + public List selectCmtOrgList(){ + List cmtList = tnCmtOrgRepository.findByUseYnOrderByCmtTypeAsc("Y"); + List lv1List = new ArrayList<>(); + for(TnCmtOrg cmt: cmtList){ + if(cmt.getCmtType().equals("LV_01")){ + lv1List.add(cmt); + } + cmt.getChildList().addAll(findChildCmt(cmt, cmtList)); + } + return lv1List; + } + + private List findChildCmt(TnCmtOrg parent, List cmtList){ + List tempList = new ArrayList<>(); + for(TnCmtOrg cmt: cmtList){ + if(parent.getCmtSeq().equals(cmt.getUpCmtSeq())){ + tempList.add(cmt); + } + } + return tempList; + } +} diff --git a/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/config/common/AuthCheckInterceptor.java b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/config/common/AuthCheckInterceptor.java new file mode 100644 index 0000000..502f833 --- /dev/null +++ b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/config/common/AuthCheckInterceptor.java @@ -0,0 +1,43 @@ +package com.dbnt.kcscbackend.config.common; + +import com.dbnt.kcscbackend.admin.config.entity.TcMenu; +import com.dbnt.kcscbackend.admin.config.service.ConfigService; +import com.dbnt.kcscbackend.admin.users.service.UsersService; +import com.dbnt.kcscbackend.auth.entity.LoginVO; +import lombok.RequiredArgsConstructor; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.stereotype.Component; +import org.springframework.web.servlet.HandlerInterceptor; +import org.springframework.web.servlet.ModelAndView; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.util.List; + +@Component +@RequiredArgsConstructor +public class AuthCheckInterceptor implements HandlerInterceptor { + + private final UsersService usersService; + private final ConfigService configService; + private final Logger log = LoggerFactory.getLogger(this.getClass().getSimpleName()); + + @Override + public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { + /*관리자 메뉴 접근시 권한 체크*/ + String requestUri = request.getRequestURI(); + String userRole = usersService.selectUserInfo(((LoginVO)((UsernamePasswordAuthenticationToken)request.getUserPrincipal()).getPrincipal()).getUserSeq()).getUserRole(); + List menuList = configService.selectMenuListToRole("MNU_0000", userRole); + boolean requestFlag = false; + for(TcMenu menu: menuList){ + if(requestUri.contains(menu.getMenuUrl())){ + requestFlag = true; + break; + } + } + log.info("requestFlag: "+requestFlag); + return requestFlag; + } +} diff --git a/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/config/jwt/EgovJwtTokenUtil.java b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/config/jwt/EgovJwtTokenUtil.java index e448128..8c48dfc 100644 --- a/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/config/jwt/EgovJwtTokenUtil.java +++ b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/config/jwt/EgovJwtTokenUtil.java @@ -70,10 +70,6 @@ public class EgovJwtTokenUtil implements Serializable{ Claims claims = getClaimFromToken(token); return claims.get("userSe").toString(); } - public String getInfoFromToken(String type, String token) { - Claims claims = getClaimFromToken(token); - return claims.get(type).toString(); - } public Claims getClaimFromToken(String token) { return getAllClaimsFromToken(token); } @@ -96,7 +92,8 @@ public class EgovJwtTokenUtil implements Serializable{ claims.put("userSeq", loginVO.getUserSeq()); claims.put("id", loginVO.getUserId()); claims.put("remoteAddr", remoteAddr); - claims.put("userSe", loginVO.getUserSe() ); + claims.put("userSe", loginVO.getUserSe()); + claims.put("userRole", loginVO.getUserRole()); claims.put("type", "Authorization"); log.debug("===>>> secret = "+SECRET_KEY); diff --git a/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/config/jwt/JwtAuthenticationFilter.java b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/config/jwt/JwtAuthenticationFilter.java index 00287f9..83cc8bd 100644 --- a/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/config/jwt/JwtAuthenticationFilter.java +++ b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/config/jwt/JwtAuthenticationFilter.java @@ -69,10 +69,7 @@ public class JwtAuthenticationFilter extends OncePerRequestFilter { logger.debug("jwtToken validated"); loginVO.setUserSeq(Integer.parseInt(jwtTokenUtil.getUserSeqFromToken(jwtToken))); loginVO.setId(id); - loginVO.setUserSe( jwtTokenUtil.getUserSeFromToken(jwtToken) ); -// loginVO.setUniqId( jwtTokenUtil.getInfoFromToken("uniqId",jwtToken) ); -// loginVO.setOrgnztId( jwtTokenUtil.getInfoFromToken("orgnztId",jwtToken) ); -// loginVO.setName( jwtTokenUtil.getInfoFromToken("name",jwtToken) ); + loginVO.setUserSe(jwtTokenUtil.getUserSeFromToken(jwtToken)); UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(loginVO, null, Arrays.asList(new SimpleGrantedAuthority("ROLE_USER")) diff --git a/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/config/security/SecurityConfig.java b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/config/security/SecurityConfig.java index 85a7126..8bfaa68 100644 --- a/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/config/security/SecurityConfig.java +++ b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/config/security/SecurityConfig.java @@ -61,33 +61,42 @@ public class SecurityConfig { // 인증 예외 List private String[] AUTH_WHITELIST = { - "/", - "/login", - "/auth/login", - "/auth/accessTokenRefresh", // jwt accessToken 갱신 - "/auth/join",//회원가입 - "/auth/findId", // id 찾기 - "/auth/findPw", // pw 찾기 + "/", + "/login", + "/auth/login", + "/auth/accessTokenRefresh", // jwt accessToken 갱신 + "/auth/join",//회원가입 + "/auth/findId", // id 찾기 + "/auth/findPw", // pw 찾기 - "/cmm/main/**.do", // 메인페이지 - "/cmm/fms/FileDown.do", //파일 다운로드 - "/file/download", //파일 다운로드 - "/file/standardCode-download", //파일 다운로드 - "/cmm/fms/getImage.do", //갤러리 이미지보기 + "/cmm/main/**.do", // 메인페이지 + "/cmm/fms/FileDown.do", //파일 다운로드 + "/file/download", //파일 다운로드 + "/file/standardCode-download", //파일 다운로드 + "/cmm/fms/getImage.do", //갤러리 이미지보기 - "/cop/bbs/selectUserBBSMasterInfAPI.do", //게시판 마스터 상세 조회 - "/cop/bbs/selectBoardListAPI.do", //게시판 목록조회 - "/cop/bbs/selectBoardArticleAPI.do", //게시물 상세조회 + "/cop/bbs/selectUserBBSMasterInfAPI.do", //게시판 마스터 상세 조회 + "/cop/bbs/selectBoardListAPI.do", //게시판 목록조회 + "/cop/bbs/selectBoardArticleAPI.do", //게시물 상세조회 - /* swagger v2 */ - "/v2/api-docs", - "/swagger-resources", - "/swagger-resources/**", - "/swagger-ui.html", - "/swagger-ui/**", + /* swagger v2 */ + "/v2/api-docs", + "/swagger-resources", + "/swagger-resources/**", + "/swagger-ui.html", + "/swagger-ui/**", - /*기준코드 조회*/ - "/standardCode/**" + /* 기준코드 조회 */ + "/standardCode/**", + + /* 통합검색 요청 */ + "/search/doc", + + /* 관련사이트 이미지 조회 */ + "/admin/config/get-site-image/**", + + /*권한별 메뉴 호출*/ + "/leftNav/menu" }; private static final String[] ORIGINS_WHITELIST = { "http://localhost:3000", diff --git a/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/config/security/WebMvcConfig.java b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/config/security/WebMvcConfig.java index d45700d..a0491a0 100644 --- a/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/config/security/WebMvcConfig.java +++ b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/config/security/WebMvcConfig.java @@ -1,7 +1,10 @@ package com.dbnt.kcscbackend.config.security; +import com.dbnt.kcscbackend.config.common.AuthCheckInterceptor; +import lombok.RequiredArgsConstructor; import org.springframework.context.annotation.Configuration; import org.springframework.web.method.support.HandlerMethodArgumentResolver; +import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import java.util.List; @@ -17,7 +20,19 @@ import java.util.List; * 2023/07/13 crlee 최초 생성 */ @Configuration +@RequiredArgsConstructor public class WebMvcConfig implements WebMvcConfigurer { + private final AuthCheckInterceptor authCheckInterceptor; + + @Override + public void addInterceptors(InterceptorRegistry registry){ + /*관리자 메뉴 접근시 권한 체크*/ + registry.addInterceptor(authCheckInterceptor) + .addPathPatterns("/admin/**") + .excludePathPatterns( + "/admin/dashboard/**" + ); + } @Override public void addArgumentResolvers(List argumentResolvers) { argumentResolvers.add(new CustomAuthenticationPrincipalResolver()); diff --git a/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/search/SearchController.java b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/search/SearchController.java new file mode 100644 index 0000000..0eac27b --- /dev/null +++ b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/search/SearchController.java @@ -0,0 +1,28 @@ +package com.dbnt.kcscbackend.search; + +import com.dbnt.kcscbackend.search.service.SearchService; +import lombok.RequiredArgsConstructor; +import org.json.simple.JSONArray; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import java.util.List; + +@RestController +@RequiredArgsConstructor +@RequestMapping("/search") +public class SearchController { + + private final SearchService searchService; + + @RequestMapping("/doc") + public JSONArray searchDoc( + @RequestParam(value="target", required = true) String target, + @RequestParam(value="searchText", required = true) String text, + @RequestParam(value="pageNum", required = false, defaultValue = "1") Integer pageNum, + @RequestParam(value="pageSize", required = false, defaultValue = "15") Integer pageSize + ){ + return searchService.searchRequest(target, text, pageNum, pageSize); + } +} diff --git a/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/search/service/SearchService.java b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/search/service/SearchService.java new file mode 100644 index 0000000..126a01f --- /dev/null +++ b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/search/service/SearchService.java @@ -0,0 +1,48 @@ +package com.dbnt.kcscbackend.search.service; + +import lombok.RequiredArgsConstructor; + +import org.apache.hc.client5.http.classic.methods.HttpGet; +import org.apache.hc.client5.http.impl.classic.CloseableHttpClient; +import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse; +import org.apache.hc.client5.http.impl.classic.HttpClients; +import org.apache.hc.core5.http.ParseException; +import org.apache.hc.core5.http.io.entity.EntityUtils; +import org.json.simple.JSONArray; +import org.json.simple.parser.JSONParser; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; + +import java.io.IOException; +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; + +@Service +@RequiredArgsConstructor +public class SearchService { + @Value("${kcsc.opensearch.url}") + protected String kcscOpensearchUrl; + + public JSONArray searchRequest(String target, String text, Integer pageNum, Integer pageSize) { + String url = kcscOpensearchUrl; + switch (target){ + case "title": url+="/doc-search/doc-title?";break; + case "index": url+="/doc-search/doc-index?";break; + case "content": url+="/doc-search/doc-content?";break; + } + String param = "searchText="+URLEncoder.encode(text, StandardCharsets.UTF_8)+"&pageNum="+pageNum+"&pageSize="+pageSize; + try{ + CloseableHttpClient httpClient = HttpClients.createDefault(); + HttpGet httpGet = new HttpGet(url+param); + httpGet.addHeader("User-Agent", "Mozilla/5.0"); + httpGet.addHeader("Content-type", "application/json;charset=UTF-8"); + CloseableHttpResponse httpResponse = httpClient.execute(httpGet); + String json = EntityUtils.toString(httpResponse.getEntity(), "UTF-8"); + return (JSONArray)new JSONParser().parse(json); + } catch (IOException | ParseException e) { + throw new RuntimeException(e); + } catch (org.json.simple.parser.ParseException e) { + throw new RuntimeException(e); + } + } +} diff --git a/kcsc-back-end/src/main/resources/application-dev.properties b/kcsc-back-end/src/main/resources/application-dev.properties index 604bda4..828b8e1 100644 --- a/kcsc-back-end/src/main/resources/application-dev.properties +++ b/kcsc-back-end/src/main/resources/application-dev.properties @@ -33,3 +33,10 @@ logging.level.com.atoz_develop.mybatissample.repository=TRACE Globals.posblAtchFileSize=5242880 Globals.fileStorePath=D:\\kcscUploadFiles Globals.addedOptions=false + +#JWT +# redisConfig +spring.redis.host=localhost +spring.redis.port=6379 + +kcsc.opensearch.url=http://192.168.0.89:8090 \ No newline at end of file diff --git a/kcsc-back-end/src/main/resources/application-local.properties b/kcsc-back-end/src/main/resources/application-local.properties deleted file mode 100644 index 20ab5a8..0000000 --- a/kcsc-back-end/src/main/resources/application-local.properties +++ /dev/null @@ -1,41 +0,0 @@ - -# Access-Control-Allow-Origin -Globals.Allow.Origin = http://localhost:3000 - - -spring.devtools.livereload.enabled=true -#Datasource Configuration -spring.sql.init.encoding=utf-8 -#maximum-pool-size: CPU core count -spring.datasource.hikari.maximum-pool-size=4 -#postgresql -#spring.datasource.driverClassName=net.sf.log4jdbc.sql.jdbcapi.DriverSpy -#spring.datasource.url=jdbc:log4jdbc:postgresql://118.219.150.34:50654/kcsc -#spring.datasource.username=kcsc -#spring.datasource.password=dbnt0928! -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://118.219.150.34:50503/kcsc -spring.datasource.username=dbnt0031 -spring.datasource.password=dbnt0928! - - -#jpa -spring.jpa.show-sql=true -spring.jpa.generate-ddl=false -spring.jpa.hibernate.naming.physical-strategy = org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl -spring.jpa.properties.hibernate.proc.param_null_passing=true -spring.jpa.properties.hibernate.jdbc.time_zone=Asia/Seoul - - - -# MyBatis -mybatis.mapper-locations: mybatisMapper/*.xml -mybatis.configuration.map-underscore-to-camel-case=true -mybatis.type-aliases-package=com.dbnt.kcscbackend.**.entity -logging.level.com.atoz_develop.mybatissample.repository=TRACE - -# File Config -Globals.posblAtchFileSize=5242880 -Globals.fileStorePath=D:\\kcscUploadFiles -Globals.addedOptions=false \ No newline at end of file diff --git a/kcsc-back-end/src/main/resources/application-prod.properties b/kcsc-back-end/src/main/resources/application-prod.properties index f83f0aa..4c0c55c 100644 --- a/kcsc-back-end/src/main/resources/application-prod.properties +++ b/kcsc-back-end/src/main/resources/application-prod.properties @@ -1,3 +1,4 @@ +# ??? ? ?? ?? properties ?? ?? ? ?? ??. # Access-Control-Allow-Origin Globals.Allow.Origin = https://back.dbnt.co.kr @@ -34,5 +35,7 @@ logging.level.com.atoz_develop.mybatissample.repository=info # File Config Globals.posblAtchFileSize=5242880 -Globals.fileStorePath=D:\\kcscUploadFiles +Globals.fileStorePath=/kcscUploadFiles Globals.addedOptions=false + +kcsc.opensearch.url=http://192.168.0.89:8090 \ No newline at end of file diff --git a/kcsc-back-end/src/main/resources/application-test.properties b/kcsc-back-end/src/main/resources/application-test.properties index 806fec5..4d6c377 100644 --- a/kcsc-back-end/src/main/resources/application-test.properties +++ b/kcsc-back-end/src/main/resources/application-test.properties @@ -1,8 +1,9 @@ +# dbnt ?? ??? ?? properties # Access-Control-Allow-Origin -Globals.Allow.Origin = http://118.219.150.34:50590/ +Globals.Allow.Origin = https://back.dbnt.co.kr -server.port=8088 +server.port=8080 spring.devtools.livereload.enabled=false server.error.path=/errors @@ -16,8 +17,8 @@ spring.sql.init.encoding=utf-8 spring.datasource.hikari.maximum-pool-size=4 #postgresql spring.datasource.driverClassName=org.postgresql.Driver -spring.datasource.url=jdbc:postgresql://localhost/kcsc -spring.datasource.username=kcsc +spring.datasource.url=jdbc:postgresql://118.219.150.34:50503/kcsc +spring.datasource.username=dbnt0031 spring.datasource.password=dbnt0928! #jpa @@ -34,5 +35,7 @@ logging.level.com.atoz_develop.mybatissample.repository=info # File Config Globals.posblAtchFileSize=5242880 -Globals.fileStorePath=D:\\kcscUploadFiles -Globals.addedOptions=false \ No newline at end of file +Globals.fileStorePath=/kcscUploadFiles +Globals.addedOptions=false + +kcsc.opensearch.url=http://192.168.0.89:8090 diff --git a/kcsc-back-end/src/main/resources/application.properties b/kcsc-back-end/src/main/resources/application.properties index 96c2e7e..27d335f 100644 --- a/kcsc-back-end/src/main/resources/application.properties +++ b/kcsc-back-end/src/main/resources/application.properties @@ -6,10 +6,6 @@ spring.mvc.pathmatch.matching-strategy=ant_path_matcher Globals.pageUnit=10 Globals.pageSize=10 -#JWT -# redisConfig -spring.redis.host=localhost -spring.redis.port=6379 # secret key Globals.jwt.secret = qWwMroux3QtiIJcPSIZARNTZEBBnWVH0jZ2Lx7tfFChCYi0ViZllo1bekZdiU0B3FRjJI7g90n0ha120dwlz8JZU8rOkmNCe9Uq0 diff --git a/kcsc-back-end/src/main/resources/mybatisMapper/AdminBoardsMapper.xml b/kcsc-back-end/src/main/resources/mybatisMapper/AdminBoardsMapper.xml new file mode 100644 index 0000000..c61ac04 --- /dev/null +++ b/kcsc-back-end/src/main/resources/mybatisMapper/AdminBoardsMapper.xml @@ -0,0 +1,57 @@ + + + + + + + + + + + + and fixed_yn = #{fixedYn} + + + and bbs_seq = #{bbsSeq} + + + and bbs_cont_title like '%'||#{searchKeyword}||'%' + + + + \ No newline at end of file diff --git a/kcsc-back-end/src/main/resources/mybatisMapper/AdminUsersMapper.xml b/kcsc-back-end/src/main/resources/mybatisMapper/AdminUsersMapper.xml index 73a369e..4530426 100644 --- a/kcsc-back-end/src/main/resources/mybatisMapper/AdminUsersMapper.xml +++ b/kcsc-back-end/src/main/resources/mybatisMapper/AdminUsersMapper.xml @@ -12,10 +12,13 @@ a.phone_num, a.user_role, a.status, - c.item_nm as status_value + c.item_nm as status_value, + a.cmt_org, + d.cmt_nm as cmt_org_nm from user_info a 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 + left outer join tn_cmt_org d on a.cmt_org = d.cmt_seq order by user_seq desc limit #{rowCnt} offset #{firstIndex} diff --git a/kcsc-back-end/src/main/resources/mybatisMapper/TcMenuMapper.xml b/kcsc-back-end/src/main/resources/mybatisMapper/TcMenuMapper.xml index 8db1fc4..4639d22 100644 --- a/kcsc-back-end/src/main/resources/mybatisMapper/TcMenuMapper.xml +++ b/kcsc-back-end/src/main/resources/mybatisMapper/TcMenuMapper.xml @@ -28,6 +28,7 @@ select a.menu_id , a.menu_title , a.menu_group , + a.menu_url, coalesce(b.role_cd, '') as menu_auth from tc_menu a left outer join ( @@ -36,6 +37,26 @@ group by menu_id ) b on a.menu_id = b.menu_id where a.use_yn = 'Y' - order by a.menu_id asc + order by a.menu_type_cd desc, a.menu_id asc + + + \ No newline at end of file diff --git a/kcsc-opensearch/.gitignore b/kcsc-opensearch/.gitignore new file mode 100644 index 0000000..c2065bc --- /dev/null +++ b/kcsc-opensearch/.gitignore @@ -0,0 +1,37 @@ +HELP.md +.gradle +build/ +!gradle/wrapper/gradle-wrapper.jar +!**/src/main/**/build/ +!**/src/test/**/build/ + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache +bin/ +!**/src/main/**/bin/ +!**/src/test/**/bin/ + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr +out/ +!**/src/main/**/out/ +!**/src/test/**/out/ + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ + +### VS Code ### +.vscode/ diff --git a/kcsc-opensearch/build.gradle b/kcsc-opensearch/build.gradle new file mode 100644 index 0000000..ce37ea5 --- /dev/null +++ b/kcsc-opensearch/build.gradle @@ -0,0 +1,35 @@ +plugins { + id 'java' + id 'org.springframework.boot' version '3.2.4' + id 'io.spring.dependency-management' version '1.1.4' +} + +group = 'com.dbnt' +version = '0.0.1-SNAPSHOT' + +java { + sourceCompatibility = '17' +} + +repositories { + mavenCentral() +} + +dependencies { + compileOnly 'org.projectlombok:lombok:1.18.24' + annotationProcessor 'org.projectlombok:lombok:1.18.24' + annotationProcessor 'org.springframework.boot:spring-boot-configuration-processor' + + implementation 'org.springframework.boot:spring-boot-starter' + implementation 'org.springframework.boot:spring-boot-starter-web' + implementation 'org.springframework.boot:spring-boot-starter-data-jpa' + implementation 'org.springframework.boot:spring-boot-starter-actuator' + + // https://mvnrepository.com/artifact/org.opensearch.client/spring-data-opensearch-starter + implementation (group: 'org.opensearch.client', name: 'spring-data-opensearch-starter', version: '1.3.0'){ + exclude group: 'org.opensearch.client', module: 'opensearch-rest-client-sniffer' + } + + runtimeOnly 'org.postgresql:postgresql:42.3.6' + +} diff --git a/kcsc-opensearch/gradle/wrapper/gradle-wrapper.jar b/kcsc-opensearch/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000..e644113 Binary files /dev/null and b/kcsc-opensearch/gradle/wrapper/gradle-wrapper.jar differ diff --git a/kcsc-opensearch/gradle/wrapper/gradle-wrapper.properties b/kcsc-opensearch/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..b82aa23 --- /dev/null +++ b/kcsc-opensearch/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,7 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +networkTimeout=10000 +validateDistributionUrl=true +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/kcsc-opensearch/gradlew b/kcsc-opensearch/gradlew new file mode 100644 index 0000000..1aa94a4 --- /dev/null +++ b/kcsc-opensearch/gradlew @@ -0,0 +1,249 @@ +#!/bin/sh + +# +# Copyright © 2015-2021 the original authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +############################################################################## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# +############################################################################## + +# Attempt to set APP_HOME + +# Resolve links: $0 may be a link +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac +done + +# This is normally unused +# shellcheck disable=SC2034 +APP_BASE_NAME=${0##*/} +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) +APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD=maximum + +warn () { + echo "$*" +} >&2 + +die () { + echo + echo "$*" + echo + exit 1 +} >&2 + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD=$JAVA_HOME/jre/sh/java + else + JAVACMD=$JAVA_HOME/bin/java + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD=java + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +fi + +# Increase the maximum file descriptors if we can. +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac +fi + +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done +fi + + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + org.gradle.wrapper.GradleWrapperMain \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + +exec "$JAVACMD" "$@" diff --git a/kcsc-opensearch/gradlew.bat b/kcsc-opensearch/gradlew.bat new file mode 100644 index 0000000..25da30d --- /dev/null +++ b/kcsc-opensearch/gradlew.bat @@ -0,0 +1,92 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%"=="" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if %ERRORLEVEL% equ 0 goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if %ERRORLEVEL% equ 0 goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/kcsc-opensearch/settings.gradle b/kcsc-opensearch/settings.gradle new file mode 100644 index 0000000..6cb0f71 --- /dev/null +++ b/kcsc-opensearch/settings.gradle @@ -0,0 +1 @@ +rootProject.name = 'kcsc-opensearch' diff --git a/kcsc-opensearch/src/main/java/com/dbnt/kcscopensearch/KcscOpensearchApplication.java b/kcsc-opensearch/src/main/java/com/dbnt/kcscopensearch/KcscOpensearchApplication.java new file mode 100644 index 0000000..361e108 --- /dev/null +++ b/kcsc-opensearch/src/main/java/com/dbnt/kcscopensearch/KcscOpensearchApplication.java @@ -0,0 +1,16 @@ +package com.dbnt.kcscopensearch; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchDataAutoConfiguration; +import org.springframework.scheduling.annotation.EnableScheduling; + +@EnableScheduling +@SpringBootApplication(exclude = ElasticsearchDataAutoConfiguration.class) +public class KcscOpensearchApplication { + + public static void main(String[] args) { + SpringApplication.run(KcscOpensearchApplication.class, args); + } + +} diff --git a/kcsc-opensearch/src/main/java/com/dbnt/kcscopensearch/config/KcscDatabaseConfig.java b/kcsc-opensearch/src/main/java/com/dbnt/kcscopensearch/config/KcscDatabaseConfig.java new file mode 100644 index 0000000..ac4e0b5 --- /dev/null +++ b/kcsc-opensearch/src/main/java/com/dbnt/kcscopensearch/config/KcscDatabaseConfig.java @@ -0,0 +1,61 @@ +package com.dbnt.kcscopensearch.config; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.boot.jdbc.DataSourceBuilder; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Primary; +import org.springframework.data.jpa.repository.config.EnableJpaRepositories; +import org.springframework.orm.jpa.JpaTransactionManager; +import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; +import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter; +import org.springframework.transaction.PlatformTransactionManager; + +import javax.sql.DataSource; +import java.util.HashMap; + +@Configuration +@EnableJpaRepositories( + basePackages = "com.dbnt.kcscopensearch.kcsc.**.repository", + entityManagerFactoryRef = "kcscEntityManager", + transactionManagerRef = "kcscTransactionManager" +) +@ComponentScan(basePackageClasses = KcscDatabaseConfig.class) +public class KcscDatabaseConfig { + + @Bean + public LocalContainerEntityManagerFactoryBean kcscEntityManager(){ + LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean(); + em.setDataSource(kcscDataSource()); + + //Entity 패키지 경로 + em.setPackagesToScan(new String[] { "com.dbnt.kcscopensearch.kcsc.**.model" }); + + HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter(); + em.setJpaVendorAdapter(vendorAdapter); + + //Hibernate 설정 + HashMap properties = new HashMap<>(); + properties.put("hibernate.hbm2ddl.auto", "none"); + properties.put("hibernate.dialect", "org.hibernate.dialect.PostgreSQLDialect"); + em.setJpaPropertyMap(properties); + return em; + } + + @Primary + @Bean + @ConfigurationProperties(prefix="spring.datasource-kcsc") + public DataSource kcscDataSource() { + return DataSourceBuilder.create().build(); + } + + @Primary + @Bean + public PlatformTransactionManager kcscTransactionManager() { + JpaTransactionManager transactionManager = new JpaTransactionManager(); + transactionManager.setEntityManagerFactory(kcscEntityManager().getObject()); + return transactionManager; + } + +} diff --git a/kcsc-opensearch/src/main/java/com/dbnt/kcscopensearch/config/OpensearchConfig.java b/kcsc-opensearch/src/main/java/com/dbnt/kcscopensearch/config/OpensearchConfig.java new file mode 100644 index 0000000..1b77b1a --- /dev/null +++ b/kcsc-opensearch/src/main/java/com/dbnt/kcscopensearch/config/OpensearchConfig.java @@ -0,0 +1,43 @@ +package com.dbnt.kcscopensearch.config; + +import org.apache.http.conn.ssl.TrustSelfSignedStrategy; +import org.apache.http.impl.nio.client.HttpAsyncClientBuilder; +import org.apache.http.ssl.SSLContextBuilder; +import org.opensearch.client.RestClientBuilder; +import org.opensearch.spring.boot.autoconfigure.RestClientBuilderCustomizer; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories; + +import java.security.KeyManagementException; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; + +@Configuration +@EnableElasticsearchRepositories( + basePackages = "com.dbnt.kcscopensearch.opensearch.**.repository" +) +@ComponentScan(basePackageClasses = OpensearchConfig.class) +public class OpensearchConfig { + + @Bean + RestClientBuilderCustomizer customizer(){ + return new RestClientBuilderCustomizer() { + @Override + public void customize(HttpAsyncClientBuilder builder){ + try { + builder.setSSLContext(new SSLContextBuilder() + .loadTrustMaterial(null, new TrustSelfSignedStrategy()) + .build()); + } catch (final KeyManagementException | NoSuchAlgorithmException | KeyStoreException ex) { + throw new RuntimeException("Failed to initialize SSL Context instance", ex); + } + } + @Override + public void customize(RestClientBuilder builder) { + + } + }; + } +} diff --git a/kcsc-opensearch/src/main/java/com/dbnt/kcscopensearch/indexing/IndexingController.java b/kcsc-opensearch/src/main/java/com/dbnt/kcscopensearch/indexing/IndexingController.java new file mode 100644 index 0000000..66759bb --- /dev/null +++ b/kcsc-opensearch/src/main/java/com/dbnt/kcscopensearch/indexing/IndexingController.java @@ -0,0 +1,59 @@ +package com.dbnt.kcscopensearch.indexing; + +import com.dbnt.kcscopensearch.kcsc.docView.model.DocContentView; +import com.dbnt.kcscopensearch.kcsc.docView.model.DocIndexView; +import com.dbnt.kcscopensearch.kcsc.docView.model.DocTitleView; +import com.dbnt.kcscopensearch.kcsc.docView.service.DocViewService; +import com.dbnt.kcscopensearch.opensearch.docSearch.model.DocContent; +import com.dbnt.kcscopensearch.opensearch.docSearch.model.DocIndex; +import com.dbnt.kcscopensearch.opensearch.docSearch.model.DocTitle; +import com.dbnt.kcscopensearch.opensearch.docSearch.service.DocSearchService; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.ArrayList; +import java.util.List; + +@RestController +@RequiredArgsConstructor +@RequestMapping("/indexing") +public class IndexingController { + private final DocViewService docViewService; + private final DocSearchService docSearchService; + + @GetMapping("/doc-title") + public String getTitleIndexing(){ + List titleViewList = docViewService.selectAllDocTitle(); + List titleList = new ArrayList<>(); + for(DocTitleView view: titleViewList){ + titleList.add(new DocTitle(view)); + } + docSearchService.saveDocTitle(titleList); + return "OK"; + } + + @GetMapping("/doc-index") + public String getIndexIndexing(){ + List indexViewList = docViewService.selectAllDocIndex(); + List indexList = new ArrayList<>(); + for(DocIndexView view: indexViewList){ + indexList.add(new DocIndex(view)); + } + docSearchService.saveDocIndex(indexList); + return "OK"; + } + + @GetMapping("/doc-content") + public String getContentIndexing(){ + List contentViewList = docViewService.selectAllDocContent(); + List contentList = new ArrayList<>(); + for(DocContentView view: contentViewList){ + contentList.add(new DocContent(view)); + } + docSearchService.saveDocContent(contentList); + return "OK"; + } + +} diff --git a/kcsc-opensearch/src/main/java/com/dbnt/kcscopensearch/kcsc/docView/model/DocContentView.java b/kcsc-opensearch/src/main/java/com/dbnt/kcscopensearch/kcsc/docView/model/DocContentView.java new file mode 100644 index 0000000..b9a37c5 --- /dev/null +++ b/kcsc-opensearch/src/main/java/com/dbnt/kcscopensearch/kcsc/docView/model/DocContentView.java @@ -0,0 +1,30 @@ +package com.dbnt.kcscopensearch.kcsc.docView.model; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.Table; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.hibernate.annotations.Immutable; + +@Data +@Entity +@Immutable +@NoArgsConstructor +@Table(name = "doc_content") +public class DocContentView { + @Id + @Column(name = "content_id") + private Integer contentId; + @Column(name = "kcsc_cd") + private String kcscCd; + @Column(name = "doc_nm") + private String docNm; + @Column(name = "doc_yr") + private String docYr; + @Column(name = "group_title") + private String groupTitle; + @Column(name = "table_content") + private String tableContent; +} diff --git a/kcsc-opensearch/src/main/java/com/dbnt/kcscopensearch/kcsc/docView/model/DocIndexView.java b/kcsc-opensearch/src/main/java/com/dbnt/kcscopensearch/kcsc/docView/model/DocIndexView.java new file mode 100644 index 0000000..bf902b3 --- /dev/null +++ b/kcsc-opensearch/src/main/java/com/dbnt/kcscopensearch/kcsc/docView/model/DocIndexView.java @@ -0,0 +1,28 @@ +package com.dbnt.kcscopensearch.kcsc.docView.model; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.Table; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.hibernate.annotations.Immutable; + +@Data +@Entity +@Immutable +@NoArgsConstructor +@Table(name = "doc_index") +public class DocIndexView { + @Id + @Column(name = "index_id") + private Integer indexId; + @Column(name = "kcsc_cd") + private String kcscCd; + @Column(name = "doc_nm") + private String docNm; + @Column(name = "doc_yr") + private String docYr; + @Column(name = "group_title") + private String groupTitle; +} diff --git a/kcsc-opensearch/src/main/java/com/dbnt/kcscopensearch/kcsc/docView/model/DocTitleView.java b/kcsc-opensearch/src/main/java/com/dbnt/kcscopensearch/kcsc/docView/model/DocTitleView.java new file mode 100644 index 0000000..73329aa --- /dev/null +++ b/kcsc-opensearch/src/main/java/com/dbnt/kcscopensearch/kcsc/docView/model/DocTitleView.java @@ -0,0 +1,22 @@ +package com.dbnt.kcscopensearch.kcsc.docView.model; + +import jakarta.persistence.*; +import lombok.*; +import org.hibernate.annotations.Immutable; + +@Data +@Entity +@Immutable +@NoArgsConstructor +@Table(name = "doc_title") +public class DocTitleView { + @Id + @Column(name = "title_id") + private Integer titleId; + @Column(name = "kcsc_cd") + private String kcscCd; + @Column(name = "doc_nm") + private String docNm; + @Column(name = "doc_yr") + private String docYr; +} diff --git a/kcsc-opensearch/src/main/java/com/dbnt/kcscopensearch/kcsc/docView/repository/DocContentViewRepository.java b/kcsc-opensearch/src/main/java/com/dbnt/kcscopensearch/kcsc/docView/repository/DocContentViewRepository.java new file mode 100644 index 0000000..81a8cc4 --- /dev/null +++ b/kcsc-opensearch/src/main/java/com/dbnt/kcscopensearch/kcsc/docView/repository/DocContentViewRepository.java @@ -0,0 +1,10 @@ +package com.dbnt.kcscopensearch.kcsc.docView.repository; + +import com.dbnt.kcscopensearch.kcsc.docView.model.DocContentView; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface DocContentViewRepository extends JpaRepository { + +} diff --git a/kcsc-opensearch/src/main/java/com/dbnt/kcscopensearch/kcsc/docView/repository/DocIndexViewRepository.java b/kcsc-opensearch/src/main/java/com/dbnt/kcscopensearch/kcsc/docView/repository/DocIndexViewRepository.java new file mode 100644 index 0000000..02029d1 --- /dev/null +++ b/kcsc-opensearch/src/main/java/com/dbnt/kcscopensearch/kcsc/docView/repository/DocIndexViewRepository.java @@ -0,0 +1,10 @@ +package com.dbnt.kcscopensearch.kcsc.docView.repository; + +import com.dbnt.kcscopensearch.kcsc.docView.model.DocIndexView; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface DocIndexViewRepository extends JpaRepository { + +} diff --git a/kcsc-opensearch/src/main/java/com/dbnt/kcscopensearch/kcsc/docView/repository/DocTitleViewRepository.java b/kcsc-opensearch/src/main/java/com/dbnt/kcscopensearch/kcsc/docView/repository/DocTitleViewRepository.java new file mode 100644 index 0000000..b3c60f7 --- /dev/null +++ b/kcsc-opensearch/src/main/java/com/dbnt/kcscopensearch/kcsc/docView/repository/DocTitleViewRepository.java @@ -0,0 +1,10 @@ +package com.dbnt.kcscopensearch.kcsc.docView.repository; + +import com.dbnt.kcscopensearch.kcsc.docView.model.DocTitleView; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface DocTitleViewRepository extends JpaRepository { + +} diff --git a/kcsc-opensearch/src/main/java/com/dbnt/kcscopensearch/kcsc/docView/service/DocViewService.java b/kcsc-opensearch/src/main/java/com/dbnt/kcscopensearch/kcsc/docView/service/DocViewService.java new file mode 100644 index 0000000..292291c --- /dev/null +++ b/kcsc-opensearch/src/main/java/com/dbnt/kcscopensearch/kcsc/docView/service/DocViewService.java @@ -0,0 +1,42 @@ +package com.dbnt.kcscopensearch.kcsc.docView.service; + +import com.dbnt.kcscopensearch.kcsc.docView.model.DocContentView; +import com.dbnt.kcscopensearch.kcsc.docView.model.DocIndexView; +import com.dbnt.kcscopensearch.kcsc.docView.model.DocTitleView; +import com.dbnt.kcscopensearch.kcsc.docView.repository.DocContentViewRepository; +import com.dbnt.kcscopensearch.kcsc.docView.repository.DocIndexViewRepository; +import com.dbnt.kcscopensearch.kcsc.docView.repository.DocTitleViewRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +@Service +@RequiredArgsConstructor +public class DocViewService { + private final DocTitleViewRepository titleRepository; + private final DocIndexViewRepository indexRepository; + private final DocContentViewRepository contentRepository; + + public Map> selectAllView(){ + Map> viewDataMap = new HashMap<>(); + viewDataMap.put("docTitle", titleRepository.findAll()); + viewDataMap.put("docIndex", indexRepository.findAll()); + viewDataMap.put("docContent", contentRepository.findAll()); + return viewDataMap; + } + + public List selectAllDocTitle(){ + return titleRepository.findAll(); + } + + public List selectAllDocIndex(){ + return indexRepository.findAll(); + } + + public List selectAllDocContent(){ + return contentRepository.findAll(); + } +} diff --git a/kcsc-opensearch/src/main/java/com/dbnt/kcscopensearch/kcsc/tnDocumentGroup/model/TnDocumentGroup.java b/kcsc-opensearch/src/main/java/com/dbnt/kcscopensearch/kcsc/tnDocumentGroup/model/TnDocumentGroup.java new file mode 100644 index 0000000..f2269d0 --- /dev/null +++ b/kcsc-opensearch/src/main/java/com/dbnt/kcscopensearch/kcsc/tnDocumentGroup/model/TnDocumentGroup.java @@ -0,0 +1,61 @@ +package com.dbnt.kcscopensearch.kcsc.tnDocumentGroup.model; + +import jakarta.persistence.*; +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 java.time.LocalDateTime; + +@Getter +@Setter +@Entity +@NoArgsConstructor +@DynamicInsert +@DynamicUpdate +@Table(name = "tn_document_group") +public class TnDocumentGroup { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "group_seq") + private Integer groupSeq; + @Column(name = "group_full_cd") + private String groupFullCd; + @Column(name = "kcsc_cd") + private String kcscCd; + @Column(name = "group_cur_cd") + private String groupCurCd; + @Column(name = "group_nm") + private String groupNm; + @Column(name = "group_type") + private String groupType; + @Column(name = "item_cd") + private String itemCd; + @Column(name = "doc_type") + private Integer docType; + @Column(name = "doc_level") + private Integer docLevel; + @Column(name = "doc_order") + private Integer docOrder; + @Column(name = "parent_group_seq") + private Integer parentGroupSeq; + @Column(name = "rvsn_remark") + private String rvsnRemark; + @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; + @Column(name = "old_seq") + private Integer oldSeq; +} diff --git a/kcsc-opensearch/src/main/java/com/dbnt/kcscopensearch/kcsc/tnDocumentGroup/repository/TnDocumentGroupRepository.java b/kcsc-opensearch/src/main/java/com/dbnt/kcscopensearch/kcsc/tnDocumentGroup/repository/TnDocumentGroupRepository.java new file mode 100644 index 0000000..0490058 --- /dev/null +++ b/kcsc-opensearch/src/main/java/com/dbnt/kcscopensearch/kcsc/tnDocumentGroup/repository/TnDocumentGroupRepository.java @@ -0,0 +1,16 @@ +package com.dbnt.kcscopensearch.kcsc.tnDocumentGroup.repository; + +import com.dbnt.kcscopensearch.kcsc.tnDocumentGroup.model.TnDocumentGroup; +import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +import java.util.List; + +@Repository +public interface TnDocumentGroupRepository extends JpaRepository { + + Integer countBy(); + List findByOrderByGroupSeqAsc(Pageable pageable); + +} diff --git a/kcsc-opensearch/src/main/java/com/dbnt/kcscopensearch/kcsc/tnDocumentGroup/service/TnDocumentGroupService.java b/kcsc-opensearch/src/main/java/com/dbnt/kcscopensearch/kcsc/tnDocumentGroup/service/TnDocumentGroupService.java new file mode 100644 index 0000000..c8da89c --- /dev/null +++ b/kcsc-opensearch/src/main/java/com/dbnt/kcscopensearch/kcsc/tnDocumentGroup/service/TnDocumentGroupService.java @@ -0,0 +1,27 @@ +package com.dbnt.kcscopensearch.kcsc.tnDocumentGroup.service; + +import com.dbnt.kcscopensearch.kcsc.tnDocumentGroup.repository.TnDocumentGroupRepository; +import com.dbnt.kcscopensearch.kcsc.tnDocumentGroup.model.TnDocumentGroup; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +import java.util.List; + +@Service +@RequiredArgsConstructor +public class TnDocumentGroupService { + private final TnDocumentGroupRepository tnDocumentGroupRepository; + + public List selectAll(){ + /*List documentGroupList = new ArrayList<>(); + Integer totalCnt = tnDocumentGroupRepository.countBy(); + Integer pageCnt = 0; + while (pageCnt < totalCnt){ + List temp = tnDocumentGroupRepository.findByOrderByGroupSeqAsc(PageRequest.of(pageCnt, pageCnt+100)); + documentGroupList.addAll(temp); + pageCnt += 100; + } + return documentGroupList;*/ + return tnDocumentGroupRepository.findAll(); + } +} diff --git a/kcsc-opensearch/src/main/java/com/dbnt/kcscopensearch/opensearch/docSearch/DocSearchController.java b/kcsc-opensearch/src/main/java/com/dbnt/kcscopensearch/opensearch/docSearch/DocSearchController.java new file mode 100644 index 0000000..52ebf0d --- /dev/null +++ b/kcsc-opensearch/src/main/java/com/dbnt/kcscopensearch/opensearch/docSearch/DocSearchController.java @@ -0,0 +1,43 @@ +package com.dbnt.kcscopensearch.opensearch.docSearch; + +import com.dbnt.kcscopensearch.opensearch.docSearch.model.DocContent; +import com.dbnt.kcscopensearch.opensearch.docSearch.model.DocIndex; +import com.dbnt.kcscopensearch.opensearch.docSearch.model.DocTitle; +import com.dbnt.kcscopensearch.opensearch.docSearch.service.DocSearchService; +import lombok.RequiredArgsConstructor; +import org.springframework.http.MediaType; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import java.util.List; + +@RestController +@RequiredArgsConstructor +@RequestMapping("/doc-search") +public class DocSearchController { + private final DocSearchService docSearchService; + + @GetMapping(value="/doc-title", produces = MediaType.APPLICATION_JSON_VALUE) + public List searchTitle ( + @RequestParam(value="searchText", required = true) String text, + @RequestParam(value="pageNum", required = false, defaultValue = "1") Integer pageNum, + @RequestParam(value="pageSize", required = false, defaultValue = "15") Integer pageSize){ + return docSearchService.selectDocTitle(text, pageNum, pageSize); + } + @GetMapping(value="/doc-index", produces = MediaType.APPLICATION_JSON_VALUE) + public List searchIndex ( + @RequestParam(value="searchText", required = true) String text, + @RequestParam(value="pageNum", required = false, defaultValue = "1") Integer pageNum, + @RequestParam(value="pageSize", required = false, defaultValue = "15") Integer pageSize){ + return docSearchService.selectDocIndex(text, pageNum, pageSize); + } + @GetMapping(value="/doc-content", produces = MediaType.APPLICATION_JSON_VALUE) + public List searchContent ( + @RequestParam(value="searchText", required = true) String text, + @RequestParam(value="pageNum", required = false, defaultValue = "1") Integer pageNum, + @RequestParam(value="pageSize", required = false, defaultValue = "15") Integer pageSize){ + return docSearchService.selectDocContent(text, pageNum, pageSize); + } +} diff --git a/kcsc-opensearch/src/main/java/com/dbnt/kcscopensearch/opensearch/docSearch/model/DocContent.java b/kcsc-opensearch/src/main/java/com/dbnt/kcscopensearch/opensearch/docSearch/model/DocContent.java new file mode 100644 index 0000000..2fa74ac --- /dev/null +++ b/kcsc-opensearch/src/main/java/com/dbnt/kcscopensearch/opensearch/docSearch/model/DocContent.java @@ -0,0 +1,39 @@ +package com.dbnt.kcscopensearch.opensearch.docSearch.model; + +import com.dbnt.kcscopensearch.kcsc.docView.model.DocContentView; +import jakarta.persistence.Id; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import org.springframework.data.elasticsearch.annotations.Document; +import org.springframework.data.elasticsearch.annotations.Field; +import org.springframework.data.elasticsearch.annotations.FieldType; + +@Getter +@Setter +@NoArgsConstructor +@Document(indexName = "doc_content") +public class DocContent { + @Id + private Integer id; + + @Field(type = FieldType.Text, name = "kcsc_cd") + private String kcscCd; + @Field(type = FieldType.Text, name = "doc_nm") + private String docNm; + @Field(type = FieldType.Text, name = "doc_yr") + private String docYr; + @Field(type = FieldType.Text, name = "group_title") + private String groupTitle; + @Field(type = FieldType.Text, name = "table_content") + private String tableContent; + + public DocContent(DocContentView view){ + this.id = view.getContentId(); + this.kcscCd = view.getKcscCd(); + this.docNm = view.getDocNm(); + this.docYr = view.getDocYr(); + this.groupTitle = view.getGroupTitle(); + this.tableContent = view.getTableContent(); + } +} diff --git a/kcsc-opensearch/src/main/java/com/dbnt/kcscopensearch/opensearch/docSearch/model/DocIndex.java b/kcsc-opensearch/src/main/java/com/dbnt/kcscopensearch/opensearch/docSearch/model/DocIndex.java new file mode 100644 index 0000000..284e3a9 --- /dev/null +++ b/kcsc-opensearch/src/main/java/com/dbnt/kcscopensearch/opensearch/docSearch/model/DocIndex.java @@ -0,0 +1,36 @@ +package com.dbnt.kcscopensearch.opensearch.docSearch.model; + +import com.dbnt.kcscopensearch.kcsc.docView.model.DocIndexView; +import jakarta.persistence.Id; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import org.springframework.data.elasticsearch.annotations.Document; +import org.springframework.data.elasticsearch.annotations.Field; +import org.springframework.data.elasticsearch.annotations.FieldType; + +@Getter +@Setter +@NoArgsConstructor +@Document(indexName = "doc_index") +public class DocIndex { + @Id + private Integer id; + + @Field(type = FieldType.Text, name = "kcsc_cd") + private String kcscCd; + @Field(type = FieldType.Text, name = "doc_nm") + private String docNm; + @Field(type = FieldType.Text, name = "doc_yr") + private String docYr; + @Field(type = FieldType.Text, name = "group_title") + private String groupTitle; + + public DocIndex(DocIndexView view){ + this.id = view.getIndexId(); + this.kcscCd = view.getKcscCd(); + this.docNm = view.getDocNm(); + this.docYr = view.getDocYr(); + this.groupTitle = view.getGroupTitle(); + } +} diff --git a/kcsc-opensearch/src/main/java/com/dbnt/kcscopensearch/opensearch/docSearch/model/DocTitle.java b/kcsc-opensearch/src/main/java/com/dbnt/kcscopensearch/opensearch/docSearch/model/DocTitle.java new file mode 100644 index 0000000..c7fc96f --- /dev/null +++ b/kcsc-opensearch/src/main/java/com/dbnt/kcscopensearch/opensearch/docSearch/model/DocTitle.java @@ -0,0 +1,33 @@ +package com.dbnt.kcscopensearch.opensearch.docSearch.model; + +import com.dbnt.kcscopensearch.kcsc.docView.model.DocTitleView; +import jakarta.persistence.*; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import org.springframework.data.elasticsearch.annotations.Document; +import org.springframework.data.elasticsearch.annotations.Field; +import org.springframework.data.elasticsearch.annotations.FieldType; + +@Getter +@Setter +@NoArgsConstructor +@Document(indexName = "doc_title") +public class DocTitle { + @Id + private Integer id; + + @Field(type = FieldType.Text, name = "kcsc_cd") + private String kcscCd; + @Field(type = FieldType.Text, name = "doc_nm") + private String docNm; + @Field(type = FieldType.Text, name = "doc_yr") + private String docYr; + + public DocTitle(DocTitleView view){ + this.id= view.getTitleId(); + this.kcscCd = view.getKcscCd(); + this.docNm = view.getDocNm(); + this.docYr = view.getDocYr(); + } +} diff --git a/kcsc-opensearch/src/main/java/com/dbnt/kcscopensearch/opensearch/docSearch/repository/DocContentRepository.java b/kcsc-opensearch/src/main/java/com/dbnt/kcscopensearch/opensearch/docSearch/repository/DocContentRepository.java new file mode 100644 index 0000000..688ce7c --- /dev/null +++ b/kcsc-opensearch/src/main/java/com/dbnt/kcscopensearch/opensearch/docSearch/repository/DocContentRepository.java @@ -0,0 +1,14 @@ +package com.dbnt.kcscopensearch.opensearch.docSearch.repository; + +import com.dbnt.kcscopensearch.opensearch.docSearch.model.DocContent; +import org.springframework.data.domain.Pageable; +import org.springframework.data.elasticsearch.repository.ElasticsearchRepository; +import org.springframework.stereotype.Repository; + +import java.util.List; + +@Repository +public interface DocContentRepository extends ElasticsearchRepository { + + List findByTableContentContains(String text, Pageable pageable); +} diff --git a/kcsc-opensearch/src/main/java/com/dbnt/kcscopensearch/opensearch/docSearch/repository/DocIndexRepository.java b/kcsc-opensearch/src/main/java/com/dbnt/kcscopensearch/opensearch/docSearch/repository/DocIndexRepository.java new file mode 100644 index 0000000..f2b5641 --- /dev/null +++ b/kcsc-opensearch/src/main/java/com/dbnt/kcscopensearch/opensearch/docSearch/repository/DocIndexRepository.java @@ -0,0 +1,14 @@ +package com.dbnt.kcscopensearch.opensearch.docSearch.repository; + +import com.dbnt.kcscopensearch.opensearch.docSearch.model.DocIndex; +import org.springframework.data.domain.Pageable; +import org.springframework.data.elasticsearch.repository.ElasticsearchRepository; +import org.springframework.stereotype.Repository; + +import java.util.List; + +@Repository +public interface DocIndexRepository extends ElasticsearchRepository { + + List findByGroupTitleContains(String text, Pageable pageable); +} diff --git a/kcsc-opensearch/src/main/java/com/dbnt/kcscopensearch/opensearch/docSearch/repository/DocTitleRepository.java b/kcsc-opensearch/src/main/java/com/dbnt/kcscopensearch/opensearch/docSearch/repository/DocTitleRepository.java new file mode 100644 index 0000000..8f70978 --- /dev/null +++ b/kcsc-opensearch/src/main/java/com/dbnt/kcscopensearch/opensearch/docSearch/repository/DocTitleRepository.java @@ -0,0 +1,14 @@ +package com.dbnt.kcscopensearch.opensearch.docSearch.repository; + +import com.dbnt.kcscopensearch.opensearch.docSearch.model.DocTitle; +import org.springframework.data.domain.Pageable; +import org.springframework.data.elasticsearch.repository.ElasticsearchRepository; +import org.springframework.stereotype.Repository; + +import java.util.List; + +@Repository +public interface DocTitleRepository extends ElasticsearchRepository { + + List findByDocNmContains(String text, Pageable pageable); +} diff --git a/kcsc-opensearch/src/main/java/com/dbnt/kcscopensearch/opensearch/docSearch/service/DocSearchService.java b/kcsc-opensearch/src/main/java/com/dbnt/kcscopensearch/opensearch/docSearch/service/DocSearchService.java new file mode 100644 index 0000000..fd7e57b --- /dev/null +++ b/kcsc-opensearch/src/main/java/com/dbnt/kcscopensearch/opensearch/docSearch/service/DocSearchService.java @@ -0,0 +1,137 @@ +package com.dbnt.kcscopensearch.opensearch.docSearch.service; + +import com.dbnt.kcscopensearch.opensearch.docSearch.model.DocContent; +import com.dbnt.kcscopensearch.opensearch.docSearch.model.DocIndex; +import com.dbnt.kcscopensearch.opensearch.docSearch.model.DocTitle; +import com.dbnt.kcscopensearch.opensearch.docSearch.repository.DocContentRepository; +import com.dbnt.kcscopensearch.opensearch.docSearch.repository.DocIndexRepository; +import com.dbnt.kcscopensearch.opensearch.docSearch.repository.DocTitleRepository; +import lombok.RequiredArgsConstructor; +import org.slf4j.LoggerFactory; +import org.slf4j.Logger; +import org.springframework.data.domain.PageRequest; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +@Service +@RequiredArgsConstructor +public class DocSearchService { + + private final DocTitleRepository titleRepository; + private final DocIndexRepository indexRepository; + private final DocContentRepository contentRepository; + private final Logger log = LoggerFactory.getLogger(this.getClass().getSimpleName()); + + @Transactional + public void save(Map> indexingDataMap){ + Iterator keys = indexingDataMap.keySet().iterator(); + while(keys.hasNext()) { + int i = 0; + String key = keys.next(); + List dataList = indexingDataMap.get(key); + if (!dataList.isEmpty()) { + switch (key) { + case "docTitle": + List titleList = (List) dataList; + while (i<=titleList.size()){ + int endNum = i+1000; + if(endNum>titleList.size()){ + endNum = titleList.size(); + } + titleRepository.saveAll(titleList.subList(i, endNum)); + i+=1000; + } + break; + case "docIndex": + List indexList = (List) dataList; + while (i<=indexList.size()){ + int endNum = i+1000; + if(endNum>indexList.size()){ + endNum = indexList.size(); + } + indexRepository.saveAll(indexList.subList(i, endNum)); + i+=1000; + } + break; + case "docContent": + List contentList = (List) dataList; + while (i<=contentList.size()){ + int endNum = i+1000; + if(endNum>contentList.size()){ + endNum = contentList.size(); + } + contentRepository.saveAll(contentList.subList(i, endNum)); + i+=1000; + } + break; + } + } + } + System.out.println("indexing end"); + } + + + @Transactional + public void saveDocTitle(List titleList) { + log.info("title indexing start listSize: "+titleList.size()); + int i = 0; + while (i<=titleList.size()){ + int endNum = i+1000; + if(endNum>titleList.size()){ + endNum = titleList.size(); + } + log.info("startNUm: "+i+" , endNum: "+endNum); + titleRepository.saveAll(titleList.subList(i, endNum)); + i+=1000; + } + log.info("titleIndexing end"); + } + + @Transactional + public void saveDocIndex(List indexList) { + log.info("index indexing start listSize: "+indexList.size()); + int i = 0; + while (i<=indexList.size()){ + int endNum = i+1000; + if(endNum>indexList.size()){ + endNum = indexList.size(); + } + log.info("startNUm: "+i+" , endNum: "+endNum); + indexRepository.saveAll(indexList.subList(i, endNum)); + i+=1000; + } + log.info("indexIndexing end"); + } + + @Transactional + public void saveDocContent(List contentList) { + log.info("content indexing start listSize: "+contentList.size()); + int i = 0; + while (i<=contentList.size()){ + int endNum = i+1000; + if(endNum>contentList.size()){ + endNum = contentList.size(); + } + log.info("startNUm: "+i+" , endNum: "+endNum); + contentRepository.saveAll(contentList.subList(i, endNum)); + i+=1000; + } + log.info("contentIndexing end"); + } + + public List selectDocTitle(String text, Integer pageNum, Integer pageSize) { + return titleRepository.findByDocNmContains(text, PageRequest.of(pageNum, pageSize)); + } + + public List selectDocIndex(String text, Integer pageNum, Integer pageSize){ + return indexRepository.findByGroupTitleContains(text, PageRequest.of(pageNum, pageSize)); + } + + public List selectDocContent(String text, Integer pageNum, Integer pageSize){ + return contentRepository.findByTableContentContains(text, PageRequest.of(pageNum, pageSize)); + } +} diff --git a/kcsc-opensearch/src/main/java/com/dbnt/kcscopensearch/opensearch/documentGroup/DocumentGroupController.java b/kcsc-opensearch/src/main/java/com/dbnt/kcscopensearch/opensearch/documentGroup/DocumentGroupController.java new file mode 100644 index 0000000..5eafee4 --- /dev/null +++ b/kcsc-opensearch/src/main/java/com/dbnt/kcscopensearch/opensearch/documentGroup/DocumentGroupController.java @@ -0,0 +1,26 @@ +package com.dbnt.kcscopensearch.opensearch.documentGroup; + +import com.dbnt.kcscopensearch.opensearch.documentGroup.model.DocumentGroup; +import com.dbnt.kcscopensearch.opensearch.documentGroup.service.DocumentGroupService; +import lombok.RequiredArgsConstructor; +import org.springframework.http.MediaType; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import java.util.List; + +@RestController +@RequiredArgsConstructor +@RequestMapping("/documentGroup") +public class DocumentGroupController { + + private final DocumentGroupService documentGroupService; + + /*@GetMapping(value = "/search", produces = MediaType.APPLICATION_JSON_VALUE) + public List search(@RequestParam(value="groupNm", required = true) String groupNm){ + return documentGroupService.search(groupNm); + }*/ + +} diff --git a/kcsc-opensearch/src/main/java/com/dbnt/kcscopensearch/opensearch/documentGroup/model/DocumentGroup.java b/kcsc-opensearch/src/main/java/com/dbnt/kcscopensearch/opensearch/documentGroup/model/DocumentGroup.java new file mode 100644 index 0000000..86ad44d --- /dev/null +++ b/kcsc-opensearch/src/main/java/com/dbnt/kcscopensearch/opensearch/documentGroup/model/DocumentGroup.java @@ -0,0 +1,87 @@ +package com.dbnt.kcscopensearch.opensearch.documentGroup.model; + +import com.dbnt.kcscopensearch.kcsc.tnDocumentGroup.model.TnDocumentGroup; +import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import org.springframework.data.annotation.Id; +import org.springframework.data.elasticsearch.annotations.Document; +import org.springframework.data.elasticsearch.annotations.Field; +import org.springframework.data.elasticsearch.annotations.FieldType; +import org.springframework.format.annotation.DateTimeFormat; + +import java.time.LocalDateTime; + +@Getter +@Setter +@NoArgsConstructor +@Document(indexName = "document_group") +public class DocumentGroup { + + @Id + private Integer id; + + @Field(type = FieldType.Integer, name = "group_seq") + private Integer groupSeq; + @Field(type = FieldType.Text, name = "group_full_cd") + private String groupFullCd; + @Field(type = FieldType.Text, name = "kcsc_cd") + private String kcscCd; + @Field(type = FieldType.Text, name = "group_cur_cd") + private String groupCurCd; + @Field(type = FieldType.Text, name = "group_nm") + private String groupNm; + @Field(type = FieldType.Text, name = "group_type") + private String groupType; + @Field(type = FieldType.Text, name = "item_cd") + private String itemCd; + @Field(type = FieldType.Integer, name = "doc_type") + private Integer docType; + @Field(type = FieldType.Integer, name = "doc_level") + private Integer docLevel; + @Field(type = FieldType.Integer, name = "doc_order") + private Integer docOrder; + @Field(type = FieldType.Integer, name = "parent_group_seq") + private Integer parentGroupSeq; + @Field(type = FieldType.Text, name = "rvsn_remark") + private String rvsnRemark; + @Field(type = FieldType.Text, name = "frst_crt_id") + private String frstCrtId; + @Field(type = FieldType.Date, name = "frst_crt_dt") + @DateTimeFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss.SSS") + @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSS", timezone = "Asia/Seoul") + private LocalDateTime frstCrtDt; + @Field(type = FieldType.Text, name = "last_chg_id") + private String lastChgId; + @Field(type = FieldType.Date, name = "last_chg_dt") + @DateTimeFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss.SSS") + @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSS", timezone = "Asia/Seoul") + private LocalDateTime lastChgDt; + @Field(type = FieldType.Text, name = "use_yn") + private String useYn; + @Field(type = FieldType.Integer, name = "old_seq") + private Integer oldSeq; + + public DocumentGroup(TnDocumentGroup documentGroup){ + this.id = documentGroup.getGroupSeq(); + this.groupSeq = documentGroup.getGroupSeq(); + this.groupFullCd = documentGroup.getGroupCurCd(); + this.kcscCd = documentGroup.getKcscCd(); + this.groupCurCd = documentGroup.getGroupCurCd(); + this.groupNm = documentGroup.getGroupNm(); + this.groupType = documentGroup.getGroupNm(); + this.itemCd = documentGroup.getItemCd(); + this.docType = documentGroup.getDocType(); + this.docLevel = documentGroup.getDocLevel(); + this.docOrder = documentGroup.getDocOrder(); + this.parentGroupSeq = documentGroup.getParentGroupSeq(); + this.rvsnRemark = documentGroup.getRvsnRemark(); + this.frstCrtId = documentGroup.getFrstCrtId(); + this.frstCrtDt = documentGroup.getFrstCrtDt(); + this.lastChgId = documentGroup.getLastChgId(); + this.lastChgDt = documentGroup.getLastChgDt(); + this.useYn = documentGroup.getUseYn(); + this.oldSeq = documentGroup.getOldSeq(); + } +} diff --git a/kcsc-opensearch/src/main/java/com/dbnt/kcscopensearch/opensearch/documentGroup/repository/DocumentGroupRepository.java b/kcsc-opensearch/src/main/java/com/dbnt/kcscopensearch/opensearch/documentGroup/repository/DocumentGroupRepository.java new file mode 100644 index 0000000..b45ff30 --- /dev/null +++ b/kcsc-opensearch/src/main/java/com/dbnt/kcscopensearch/opensearch/documentGroup/repository/DocumentGroupRepository.java @@ -0,0 +1,13 @@ +package com.dbnt.kcscopensearch.opensearch.documentGroup.repository; + +import com.dbnt.kcscopensearch.opensearch.documentGroup.model.DocumentGroup; +import org.springframework.data.elasticsearch.repository.ElasticsearchRepository; +import org.springframework.stereotype.Repository; + +import java.util.List; + +@Repository +public interface DocumentGroupRepository extends ElasticsearchRepository { + List findByGroupNmLike(String groupNm); + +} diff --git a/kcsc-opensearch/src/main/java/com/dbnt/kcscopensearch/opensearch/documentGroup/service/DocumentGroupService.java b/kcsc-opensearch/src/main/java/com/dbnt/kcscopensearch/opensearch/documentGroup/service/DocumentGroupService.java new file mode 100644 index 0000000..083cd79 --- /dev/null +++ b/kcsc-opensearch/src/main/java/com/dbnt/kcscopensearch/opensearch/documentGroup/service/DocumentGroupService.java @@ -0,0 +1,25 @@ +package com.dbnt.kcscopensearch.opensearch.documentGroup.service; + +import com.dbnt.kcscopensearch.opensearch.documentGroup.model.DocumentGroup; +import com.dbnt.kcscopensearch.opensearch.documentGroup.repository.DocumentGroupRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; + +@Service +@RequiredArgsConstructor +public class DocumentGroupService { + + private final DocumentGroupRepository documentGroupRepository; + + public List search(String groupNm){ + return documentGroupRepository.findByGroupNmLike(groupNm); + } + + @Transactional + public void save(List documentGroupList) { + documentGroupRepository.saveAll(documentGroupList); + } +} diff --git a/kcsc-opensearch/src/main/java/com/dbnt/kcscopensearch/scheduler/IndexingScheduler.java b/kcsc-opensearch/src/main/java/com/dbnt/kcscopensearch/scheduler/IndexingScheduler.java new file mode 100644 index 0000000..9b1df76 --- /dev/null +++ b/kcsc-opensearch/src/main/java/com/dbnt/kcscopensearch/scheduler/IndexingScheduler.java @@ -0,0 +1,89 @@ +package com.dbnt.kcscopensearch.scheduler; + +import com.dbnt.kcscopensearch.kcsc.docView.model.DocContentView; +import com.dbnt.kcscopensearch.kcsc.docView.model.DocIndexView; +import com.dbnt.kcscopensearch.kcsc.docView.model.DocTitleView; +import com.dbnt.kcscopensearch.opensearch.docSearch.model.DocContent; +import com.dbnt.kcscopensearch.opensearch.docSearch.model.DocIndex; +import com.dbnt.kcscopensearch.opensearch.docSearch.model.DocTitle; +import com.dbnt.kcscopensearch.opensearch.docSearch.service.DocSearchService; +import com.dbnt.kcscopensearch.kcsc.docView.service.DocViewService; +import lombok.RequiredArgsConstructor; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; + +import java.util.*; + +@Component +@RequiredArgsConstructor +public class IndexingScheduler { + + private final DocViewService docViewService; + private final DocSearchService docSearchService; + + /*@Scheduled(cron = "40 18 23 * * *") + public void viewIndexing(){ + Map> viewDataMap = docViewService.selectAllView(); + Map> indexingDataMap = new HashMap<>(); + Iterator keys = viewDataMap.keySet().iterator(); + while(keys.hasNext()){ + String key = keys.next(); + List viewDataList = viewDataMap.get(key); + if(!viewDataList.isEmpty()){ + switch (key){ + case "docTitle": + List titleList = new ArrayList<>(); + for(Object obj: viewDataList){ + titleList.add(new DocTitle((DocTitleView) obj)); + } + indexingDataMap.put("docTitle", titleList); + break; + case "docIndex": + List indexList = new ArrayList<>(); + for(Object obj: viewDataList){ + indexList.add(new DocIndex((DocIndexView) obj)); + } + indexingDataMap.put("docIndex", indexList); + break; + case "docContent": + List contentList = new ArrayList<>(); + for(Object obj: viewDataList){ + contentList.add(new DocContent((DocContentView) obj)); + } + indexingDataMap.put("docContent", contentList); + break; + } + } + } + + docSearchService.save(indexingDataMap); + }*/ + + @Scheduled(cron = "40 1 2 * * *") + public void ScheduledTitleIndexing(){ + List titleViewList = docViewService.selectAllDocTitle(); + List titleList = new ArrayList<>(); + for(DocTitleView view: titleViewList){ + titleList.add(new DocTitle(view)); + } + docSearchService.saveDocTitle(titleList); + } + @Scheduled(cron = "40 2 2 * * *") + public void ScheduledIndexIndexing(){ + List indexViewList = docViewService.selectAllDocIndex(); + List indexList = new ArrayList<>(); + for(DocIndexView view: indexViewList){ + indexList.add(new DocIndex(view)); + } + docSearchService.saveDocIndex(indexList); + } + @Scheduled(cron = "40 7 2 * * *") + public void ScheduledContentIndexing(){ + List contentViewList = docViewService.selectAllDocContent(); + List contentList = new ArrayList<>(); + for(DocContentView view: contentViewList){ + contentList.add(new DocContent(view)); + } + docSearchService.saveDocContent(contentList); + } +} diff --git a/kcsc-opensearch/src/main/resources/application.properties b/kcsc-opensearch/src/main/resources/application.properties new file mode 100644 index 0000000..dd21969 --- /dev/null +++ b/kcsc-opensearch/src/main/resources/application.properties @@ -0,0 +1,17 @@ +spring.application.name=kcsc-opensearch +server.port=8090 + +opensearch.uris=https://localhost:9200 +opensearch.username=admin +opensearch.password=kpbP7ECsaTlgvfmaGNBtORH75QHf7TmJhHZdW7Z7 + +spring.datasource-kcsc.driverClassName=org.postgresql.Driver +spring.datasource-kcsc.jdbcUrl=jdbc:postgresql://118.219.150.34:50503/kcsc +spring.datasource-kcsc.username=dbnt0031 +spring.datasource-kcsc.password=dbnt0928! + +spring.jpa.show-sql=true +spring.jpa.generate-ddl=false +spring.jpa.hibernate.naming.physical-strategy = org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl + +spring.jackson.serialization.INDENT_OUTPUT=true \ No newline at end of file