메뉴 관리 작업 완료.

메뉴 권한 관리 작업중.
thkim
강석 최 2024-01-18 17:48:55 +09:00
parent f7ba2ef68b
commit e23f997e8d
9 changed files with 342 additions and 27 deletions

View File

@ -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;}

View File

@ -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(
<div className={"list_item"} key={"userListDiv_"+index}>
<div>{item.menuId}</div>
<div>{item.menuTitle}</div>
<div>{item.menuGroup}</div>
<div>{item.menuLevel}</div>
<div>{item.menuSort}</div>
<div>{item.menuUrl}</div>
<div>{item.menuTypeValue}</div>
<div>
<button className={"btn btn_blue_h31 px-1"} onClick={()=>{editMenu(item)}}>수정</button>
</div>
</div>
);
});
if(!mutListTag.length) mutListTag.push(<p className="no_data" key="0">검색된 결과가 없습니다.</p>); //
setListTag(mutListTag);
},
function (resp) {
console.log("err response : ", resp);
}
);
},[]);
function editMenu(menu){
}
useEffect(()=>{
/*retrieveList();*/
}, [])
return (
<div className="container">
MenuAuthMgt
<div className="c_wrap">
<div className="location">
<ul>
<li><Link to={URL.MAIN} className="home">Home</Link></li>
<li>사이트관리</li>
<li>환경설정</li>
<li><Link to={URL.ADMIN_MENU_AUTH}>메뉴 권한 관리</Link></li>
</ul>
</div>
<div className="layout">
{/* <!-- Navigation --> */}
<EgovLeftNav/>
<div className="contents NOTICE_LIST" id="contents">
{/* <!-- 본문 --> */}
<div className="top_tit">
<h1 className="tit_1">메뉴 관리</h1>
</div>
<h2 className="tit_2"></h2>
<div className="board_list menuList">
<div className="head">
<span>메뉴 코드</span>
<span>메뉴 이름</span>
<span>부모 메뉴</span>
<span>레벨1</span>
<span>레벨2</span>
<span>레벨3</span>
<span>레벨4</span>
<span>레벨5</span>
<span></span>
</div>
<div className="result">
{listTag}
</div>
</div>
</div>
</div>
</div>
</div>
);
}

View File

@ -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({}) {
<div>{item.menuLevel}</div>
<div>{item.menuSort}</div>
<div>{item.menuUrl}</div>
<div>{item.menuTypeCd}</div>
<div>{item.menuTypeValue}</div>
<div>
<button className={"btn btn_blue_h31 px-1"} onClick={()=>{editMenu(item)}}>수정</button>
</div>
@ -56,7 +57,7 @@ function MenuMgt({}) {
function editMenu(menu){
handleShow();
setModalBody(<MenuModal savedInfo={menu}/>)
setModalBody(<MenuModal savedInfo={menu} reloadFunction={retrieveList}/>)
}
useEffect(()=>{
@ -71,7 +72,7 @@ function MenuMgt({}) {
<li><Link to={URL.MAIN} className="home">Home</Link></li>
<li>사이트관리</li>
<li>환경설정</li>
<li><Link to={URL.ADMIN__USERS__LIST}>메뉴 관리</Link></li>
<li><Link to={URL.ADMIN_MENU}>메뉴 관리</Link></li>
</ul>
</div>
<div className="layout">
@ -87,9 +88,9 @@ function MenuMgt({}) {
<div className="board_list menuList">
<div className="head">
<span>아이디</span>
<span>이름</span>
<span>그룹</span>
<span>메뉴 코드</span>
<span>메뉴 이름</span>
<span>부모 메뉴</span>
<span>레벨</span>
<span>정렬</span>
<span>URI</span>

View File

@ -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}){
<Form onSubmit={(e) =>{editMenu(e)}} noValidate>
<Form.Group as={Row} className="mb-3">
<Form.Label column sm={3}>
아이디
메뉴 코드
</Form.Label>
<Col sm={9}>
<Form.Control type="text" name="menuId" placeholder="아이디" required defaultValue={savedInfo?.menuId}/>
<Form.Control type="text" name="menuId" placeholder="아이디" required defaultValue={savedInfo?.menuId} readOnly={savedInfo!==undefined}/>
</Col>
</Form.Group>
<Form.Group as={Row} className="mb-3">
<Form.Label column sm={3}>
이름
메뉴 이름
</Form.Label>
<Col sm={9}>
<Form.Control type="text" name="menuTitle" placeholder="이름" required defaultValue={savedInfo?.menuTitle} />
@ -42,7 +96,7 @@ function MenuModal({savedInfo}){
</Form.Group>
<Form.Group as={Row} className="mb-3">
<Form.Label column sm={3}>
그룹
부모 메뉴
</Form.Label>
<Col sm={9}>
<Form.Control type="email" name="menuGroup" placeholder="그룹" required defaultValue={savedInfo?.menuGroup} />
@ -53,7 +107,7 @@ function MenuModal({savedInfo}){
레벨
</Form.Label>
<Col sm={9}>
<Form.Control type="text" name="menuLevel" placeholder="레벨" required defaultValue={savedInfo?.menuLevel} />
<Form.Control type="number" min={"0"} name="menuLevel" placeholder="레벨" required defaultValue={savedInfo!==undefined?savedInfo.menuLevel:0} />
</Col>
</Form.Group>
<Form.Group as={Row} className="mb-3">
@ -61,7 +115,7 @@ function MenuModal({savedInfo}){
정렬
</Form.Label>
<Col sm={9}>
<Form.Control type="text" name="menuSort" placeholder="정렬" required defaultValue={savedInfo?.menuSort} />
<Form.Control type="number" min={"0"} name="menuSort" placeholder="정렬" required defaultValue={savedInfo!==undefined?savedInfo.menuSort:0} />
</Col>
</Form.Group>
<Form.Group as={Row} className="mb-3">
@ -77,7 +131,7 @@ function MenuModal({savedInfo}){
타입
</Form.Label>
<Col sm={9}>
<Form.Control type="text" name="menuTypeCd" placeholder="타입" required defaultValue={savedInfo?.menuTypeCd} />
<SelectOption name={"menuTypeCd"} grpCd={"MNU_TYPE"} selectedValue={savedInfo?.menuTypeCd}/>
</Col>
</Form.Group>
<Row className="mb-3">

View File

@ -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;
}
}

View File

@ -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;
}

View File

@ -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<TcMenu> selectMenuList();
}

View File

@ -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<TcCodeGrp> selectCodeGrpList(){
return codeGrpRepository.findByUseYn("Y");
@ -100,6 +103,41 @@ public class AdminConfigService extends EgovAbstractServiceImpl {
}
public List<TcMenu> 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;
}
}
}

View File

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.dbnt.kcscbackend.admin.config.mapper.TcMenuMapper">
<select id="selectMenuList" resultType="TcMenu">
select a.menu_id,
a.menu_title,
a.role_grp_id,
a.menu_group,
a.menu_level,
a.menu_sort,
a.menu_url,
a.menu_type_cd,
a.use_yn,
a.frst_crt_id,
a.frst_crt_dt,
a.last_chg_id,
a.last_chg_dt,
b.item_nm as menu_type_value
from tc_menu a
inner join tc_code_item b on a.menu_type_cd = b.item_cd
where a.use_yn = 'Y'
order by menu_id asc
</select>
</mapper>