diff --git a/egovframe-template-simple-react-contribution/src/css/page.css b/egovframe-template-simple-react-contribution/src/css/page.css index a1a2616..54ec026 100644 --- a/egovframe-template-simple-react-contribution/src/css/page.css +++ b/egovframe-template-simple-react-contribution/src/css/page.css @@ -187,6 +187,26 @@ .menuList .result .list_item > div:nth-child(7) {width: 100px;} .menuList .result .list_item > div:nth-child(8) {width: 100px;} + /* 사이트관리 > 환경설정 > 메뉴관리 */ + .menuList .head > span:nth-child(1) {width: 100px;} + .menuList .head > span:nth-child(2) {width: 150px;} + .menuList .head > span:nth-child(3) {width: 100px;} + .menuList .head > span:nth-child(4) {width: 60px;} + .menuList .head > span:nth-child(5) {width: 60px;} + .menuList .head > span:nth-child(6) {width: 60px;} + .menuList .head > span:nth-child(7) {width: 60px;} + .menuList .head > span:nth-child(8) {width: 60px;} + .menuList .head > span:nth-child(9) {width: 100px;} + .menuList .result .list_item > div:nth-child(1) {width: 100px;} + .menuList .result .list_item > div:nth-child(2) {width: 150px;} + .menuList .result .list_item > div:nth-child(3) {width: 100px;} + .menuList .result .list_item > div:nth-child(4) {width: 60px;} + .menuList .result .list_item > div:nth-child(5) {width: 60px;} + .menuList .result .list_item > div:nth-child(6) {width: 60px;} + .menuList .result .list_item > div:nth-child(7) {width: 60px;} + .menuList .result .list_item > div:nth-child(8) {width: 60px;} + .menuList .result .list_item > div:nth-child(9) {width: 100px;} + /* 사이트소개 */ .SITE_INTRO .ds_1 .t_1 {margin-top: 52px; color: #000; font-size: 26px; font-weight: 500; text-align: center;} .SITE_INTRO .ds_1 .li_1 {position: relative; margin-top: 34px; font-size: 0; text-align: center;} 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 bed7be2..97791e7 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 @@ -1,11 +1,98 @@ -import React from 'react'; +import React, {useCallback, useEffect, useState} from 'react'; +import { default as EgovLeftNav } from 'components/leftmenu/EgovLeftNavAdmin'; +import {Link} from "react-router-dom"; +import URL from "constants/url"; +import * as EgovNet from "api/egovFetch"; function MenuAuthMgt(props) { + const [listTag, setListTag] = useState([]); + + const retrieveList = useCallback(() => { + EgovNet.requestFetch( + '/admin/config/menu-auth-mgt', + { + method: "GET" + }, + (resp) => { + let mutListTag = []; + + setListTag([]); + // 리스트 항목 구성 + resp.result.menuList.forEach(function (item, index) { + mutListTag.push( +
+
{item.menuId}
+
{item.menuTitle}
+
{item.menuGroup}
+
{item.menuLevel}
+
{item.menuSort}
+
{item.menuUrl}
+
{item.menuTypeValue}
+
+ +
+
+ ); + }); + if(!mutListTag.length) mutListTag.push(

검색된 결과가 없습니다.

); // 게시판 목록 초기값 + setListTag(mutListTag); + }, + function (resp) { + console.log("err response : ", resp); + } + ); + },[]); + + function editMenu(menu){ + + } + + useEffect(()=>{ + /*retrieveList();*/ + }, []) return (
- MenuAuthMgt +
+
+
    +
  • Home
  • +
  • 사이트관리
  • +
  • 환경설정
  • +
  • 메뉴 권한 관리
  • +
+
+
+ {/* */} + +
+ {/* */} + +
+

메뉴 관리

+
+

+ +
+
+ 메뉴 코드 + 메뉴 이름 + 부모 메뉴 + 레벨1 + 레벨2 + 레벨3 + 레벨4 + 레벨5 + +
+
+ {listTag} +
+
+
+
+
); } diff --git a/egovframe-template-simple-react-contribution/src/pages/admin/config/MenuMgt.jsx b/egovframe-template-simple-react-contribution/src/pages/admin/config/MenuMgt.jsx index b499f2a..78d62b7 100644 --- a/egovframe-template-simple-react-contribution/src/pages/admin/config/MenuMgt.jsx +++ b/egovframe-template-simple-react-contribution/src/pages/admin/config/MenuMgt.jsx @@ -19,6 +19,7 @@ function MenuMgt({}) { const handleShow = () => setShow(true); const retrieveList = useCallback(() => { + handleClose() EgovNet.requestFetch( '/admin/config/menu-mgt', { @@ -38,7 +39,7 @@ function MenuMgt({}) {
{item.menuLevel}
{item.menuSort}
{item.menuUrl}
-
{item.menuTypeCd}
+
{item.menuTypeValue}
@@ -56,7 +57,7 @@ function MenuMgt({}) { function editMenu(menu){ handleShow(); - setModalBody() + setModalBody() } useEffect(()=>{ @@ -71,7 +72,7 @@ function MenuMgt({}) {
  • Home
  • 사이트관리
  • 환경설정
  • -
  • 메뉴 관리
  • +
  • 메뉴 관리
  • @@ -87,9 +88,9 @@ function MenuMgt({}) {
    - 아이디 - 이름 - 그룹 + 메뉴 코드 + 메뉴 이름 + 부모 메뉴 레벨 정렬 URI diff --git a/egovframe-template-simple-react-contribution/src/pages/admin/config/menuMgt/MenuModal.jsx b/egovframe-template-simple-react-contribution/src/pages/admin/config/menuMgt/MenuModal.jsx index 1aa7ba7..55087f8 100644 --- a/egovframe-template-simple-react-contribution/src/pages/admin/config/menuMgt/MenuModal.jsx +++ b/egovframe-template-simple-react-contribution/src/pages/admin/config/menuMgt/MenuModal.jsx @@ -1,18 +1,72 @@ -import react from "react" +import React from "react"; import Modal from "react-bootstrap/Modal"; import Form from "react-bootstrap/Form"; import Row from "react-bootstrap/Row"; import Col from "react-bootstrap/Col"; -import React from "react"; +import SelectOption from "components/commonCode/SelectOption"; +import * as EgovNet from "api/egovFetch"; +import CODE from "constants/code"; -function MenuModal({savedInfo}){ +function MenuModal({savedInfo, reloadFunction}){ function editMenu(e){ - + e.preventDefault(); + e.stopPropagation(); + const form = e.target; + const info = { + menuId: form.menuId.value, + menuTitle: form.menuTitle.value, + menuGroup: form.menuGroup.value, + menuLevel: form.menuLevel.value, + menuSort: form.menuSort.value, + menuUrl: form.menuUrl.value, + menuTypeCd: form.menuTypeCd.value, + } + EgovNet.requestFetch( + '/admin/config/menu-mgt', + { + method: "PUT", + headers: { + 'Content-type': 'application/json' + }, + body: JSON.stringify(info) + }, + (resp) => { + if (Number(resp.resultCode) === Number(CODE.RCV_SUCCESS)) { + alert("저장되었습니다.") + reloadFunction(); + }else if(Number(resp.resultCode) === Number(CODE.RCV_ERROR_AUTH)){ + console.log("토큰 갱신중.") + }else{ + alert(resp.result.resultMessage) + } + } + ) } function deleteMenu(menuId){ - + if(window.confirm("삭제하시겠습니까?")) { + EgovNet.requestFetch( + '/admin/config/menu-mgt', + { + method: "DELETE", + headers: { + 'Content-type': 'application/json' + }, + body: JSON.stringify({menuId: menuId}) + }, + (resp) => { + if (Number(resp.resultCode) === Number(CODE.RCV_SUCCESS)) { + alert("삭제되었습니다.") + reloadFunction(); + } else if (Number(resp.resultCode) === Number(CODE.RCV_ERROR_AUTH)) { + console.log("토큰 갱신중.") + } else { + alert(resp.result.resultMessage) + } + } + ) + } } return ( @@ -26,15 +80,15 @@ function MenuModal({savedInfo}){
    {editMenu(e)}} noValidate> - 아이디 + 메뉴 코드 - + - 이름 + 메뉴 이름 @@ -42,7 +96,7 @@ function MenuModal({savedInfo}){ - 그룹 + 부모 메뉴 @@ -53,7 +107,7 @@ function MenuModal({savedInfo}){ 레벨 - + @@ -61,7 +115,7 @@ function MenuModal({savedInfo}){ 정렬 - + @@ -77,7 +131,7 @@ function MenuModal({savedInfo}){ 타입 - + 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 9868803..c0cbc28 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 @@ -1,5 +1,6 @@ package com.dbnt.kcscbackend.admin.config; +import com.dbnt.kcscbackend.admin.config.entity.TcMenu; import com.dbnt.kcscbackend.commonCode.entity.TcCodeGrp; import com.dbnt.kcscbackend.commonCode.entity.TcCodeItem; import com.dbnt.kcscbackend.admin.config.service.AdminConfigService; @@ -14,11 +15,14 @@ import io.swagger.v3.oas.annotations.tags.Tag; import lombok.RequiredArgsConstructor; import org.springframework.http.MediaType; import org.springframework.security.core.annotation.AuthenticationPrincipal; +import org.springframework.validation.Errors; +import org.springframework.validation.FieldError; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; +import javax.validation.Valid; import java.time.LocalDateTime; import java.util.HashMap; import java.util.Map; @@ -232,4 +236,70 @@ public class AdminConfigController extends BaseController { resultVO.setResult(resultMap); return resultVO; } + + @Operation( + summary = "메뉴 저장", + description = "메뉴 저장", + tags = {"AdminConfigController"} + ) + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "저장 성공"), + @ApiResponse(responseCode = "403", description = "인가된 사용자가 아님") + }) + @RequestMapping(method = RequestMethod.PUT, value = "/menu-mgt") + public ResultVO saveMenuMgt(@RequestBody @Valid TcMenu menu, Errors errors, @AuthenticationPrincipal LoginVO user){ + ResultVO resultVO = new ResultVO(); + if(user == null){ + resultVO.setResultCode(ResponseCode.TOKEN_EXPIRED.getCode()); + }else { + menu.setRoleGrpId(menu.getMenuTypeCd().equals("MNU_0000")?"ADMIN_USER":"ALL_USER"); + if(errors.hasErrors()){ + StringBuilder msg = new StringBuilder(); + for(FieldError error: errors.getFieldErrors()){ + msg.append(error.getDefaultMessage()); + msg.append("\n"); + } + resultVO.setResultCode(ResponseCode.INPUT_CHECK_ERROR.getCode()); + resultVO.setResultMessage(msg.toString()); + }else if (!user.getUserSe().equals("ACC_TP01")) { + resultVO.setResultCode(ResponseCode.AUTH_ERROR.getCode()); + resultVO.setResultMessage(ResponseCode.AUTH_ERROR.getMessage()); + } else { + adminConfigService.saveMenu(menu, user.getId()); + resultVO.setResultCode(ResponseCode.SUCCESS.getCode()); + } + } + return resultVO; + } + + @Operation( + summary = "메뉴 삭제", + description = "메뉴 삭제", + tags = {"AdminConfigController"} + ) + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "삭제 성공"), + @ApiResponse(responseCode = "403", description = "인가된 사용자가 아님") + }) + @RequestMapping(method = RequestMethod.DELETE, value = "/menu-mgt") + public ResultVO removeMenuMgt(@RequestBody TcMenu menu, @AuthenticationPrincipal LoginVO user){ + ResultVO resultVO = new ResultVO(); + if(user == null){ + resultVO.setResultCode(ResponseCode.TOKEN_EXPIRED.getCode()); + }else { + if (!user.getUserSe().equals("ACC_TP01")) { + resultVO.setResultCode(ResponseCode.AUTH_ERROR.getCode()); + resultVO.setResultMessage(ResponseCode.AUTH_ERROR.getMessage()); + } else { + String result = adminConfigService.deleteMenu(menu.getMenuId(), user.getId()); + if(result==null){ + resultVO.setResultCode(ResponseCode.SUCCESS.getCode()); + }else if(result.equals("notFind")){ + resultVO.setResultCode(ResponseCode.SAVE_ERROR.getCode()); + resultVO.setResultMessage("대상이 존재하지 않습니다."); + } + } + } + return resultVO; + } } 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 754939b..90a3733 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 @@ -7,10 +7,8 @@ import org.hibernate.annotations.DynamicInsert; import org.hibernate.annotations.DynamicUpdate; import org.springframework.format.annotation.DateTimeFormat; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.Id; -import javax.persistence.Table; +import javax.persistence.*; +import javax.validation.constraints.NotBlank; import java.time.LocalDateTime; @Getter @@ -23,20 +21,24 @@ import java.time.LocalDateTime; public class TcMenu { @Id @Column(name = "menu_id") + @NotBlank(message = "메뉴코드를 입력해주세요.") private String menuId; @Column(name = "role_grp_id") private String roleGrpId; @Column(name = "menu_title") + @NotBlank(message = "메뉴이름을 입력해주세요.") private String menuTitle; @Column(name = "menu_group") private String menuGroup; @Column(name = "menu_level") - private String menuLevel; + private Integer menuLevel; @Column(name = "menu_sort") - private String menuSort; + private Integer menuSort; @Column(name = "menu_url") + @NotBlank(message = "메뉴URI를 입력해주세요.") private String menuUrl; @Column(name = "menu_type_cd") + @NotBlank(message = "타입을 선택해주세요.") private String menuTypeCd; @Column(name = "frst_crt_id") private String frstCrtId; @@ -50,4 +52,7 @@ public class TcMenu { private LocalDateTime lastChgDt; @Column(name = "use_yn") private String useYn; + + @Transient + private String menuTypeValue; } 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 new file mode 100644 index 0000000..e8dd179 --- /dev/null +++ b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/config/mapper/TcMenuMapper.java @@ -0,0 +1,13 @@ +package com.dbnt.kcscbackend.admin.config.mapper; + +import com.dbnt.kcscbackend.admin.config.entity.TcMenu; +import org.apache.ibatis.annotations.Mapper; + +import java.util.List; + +@Mapper +public interface TcMenuMapper { + + List selectMenuList(); + +} 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/AdminConfigService.java index 9e25549..2f58a45 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/AdminConfigService.java @@ -1,6 +1,7 @@ package com.dbnt.kcscbackend.admin.config.service; import com.dbnt.kcscbackend.admin.config.entity.TcMenu; +import com.dbnt.kcscbackend.admin.config.mapper.TcMenuMapper; import com.dbnt.kcscbackend.admin.config.repository.TcMenuRepository; import com.dbnt.kcscbackend.commonCode.entity.TcCodeGrp; import com.dbnt.kcscbackend.commonCode.entity.TcCodeItem; @@ -11,6 +12,7 @@ import org.egovframe.rte.fdl.cmmn.EgovAbstractServiceImpl; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import java.time.LocalDateTime; import java.util.List; @Service @@ -20,6 +22,7 @@ public class AdminConfigService extends EgovAbstractServiceImpl { private final TcCodeGrpRepository codeGrpRepository; private final TcCodeItemRepository codeItemRepository; private final TcMenuRepository menuRepository; + private final TcMenuMapper menuMapper; public List selectCodeGrpList(){ return codeGrpRepository.findByUseYn("Y"); @@ -100,6 +103,41 @@ public class AdminConfigService extends EgovAbstractServiceImpl { } public List selectMenuList() { - return menuRepository.findByUseYnOrderByMenuIdAsc("Y"); + return menuMapper.selectMenuList(); + } + + @Transactional + public void saveMenu(TcMenu menu, String userId) { + TcMenu savedMenu = menuRepository.findById(menu.getMenuId()).orElse(null); + if(savedMenu==null){ + menu.setFrstCrtDt(LocalDateTime.now()); + menu.setFrstCrtId(userId); + menu.setUseYn("Y"); + menuRepository.save(menu); + }else{ + savedMenu.setMenuTitle(menu.getMenuTitle()); + savedMenu.setMenuGroup(menu.getMenuGroup()); + savedMenu.setMenuLevel(menu.getMenuLevel()); + savedMenu.setMenuSort(menu.getMenuSort()); + savedMenu.setMenuUrl(menu.getMenuUrl()); + savedMenu.setMenuTypeCd(menu.getMenuTypeCd()); + savedMenu.setUseYn("Y"); + savedMenu.setLastChgId(userId); + savedMenu.setLastChgDt(LocalDateTime.now()); + menuRepository.save(savedMenu); + } + } + + @Transactional + public String deleteMenu(String menuId, String userId) { + TcMenu savedMenu = menuRepository.findById(menuId).orElse(null); + if(savedMenu==null){ + return "notFind"; + }else{ + savedMenu.setUseYn("N"); + savedMenu.setLastChgDt(LocalDateTime.now()); + savedMenu.setLastChgId(userId); + return null; + } } } diff --git a/kcsc-back-end/src/main/resources/mybatisMapper/TcMenuMapper.xml b/kcsc-back-end/src/main/resources/mybatisMapper/TcMenuMapper.xml new file mode 100644 index 0000000..9258f88 --- /dev/null +++ b/kcsc-back-end/src/main/resources/mybatisMapper/TcMenuMapper.xml @@ -0,0 +1,27 @@ + + + + + + + \ No newline at end of file