게시판관리 추가/수정 모달

thkim
유민형 2024-02-05 14:51:06 +09:00
parent 64e4b07953
commit 1cd9cf8202
4 changed files with 169 additions and 272 deletions

View File

@ -1,5 +1,6 @@
import React, {useState, useEffect, useRef} from 'react'; import React, {useState, useEffect, useRef} from 'react';
import { Link, useNavigate, useLocation } from 'react-router-dom'; import {Link, useNavigate, useLocation, useParams} from 'react-router-dom';
import Modal from "react-bootstrap/Modal";
import * as EgovNet from 'api/egovFetch'; import * as EgovNet from 'api/egovFetch';
import URL from 'constants/url'; import URL from 'constants/url';
@ -25,55 +26,35 @@ function EgovAdminBoardEdit(props) {
const bbsTyCodeOptions = [{value: "", label: "선택"}, {value: "BBST01", label: "일반게시판"}, {value: "BBST03", label: "공지게시판"}]; const bbsTyCodeOptions = [{value: "", label: "선택"}, {value: "BBST01", label: "일반게시판"}, {value: "BBST03", label: "공지게시판"}];
const bbsAttrbCodeOptions = [{value: "", label: "선택"}, {value: "BBSA02", label: "갤러리"}, {value: "BBSA03", label: "일반게시판"}]; const bbsAttrbCodeOptions = [{value: "", label: "선택"}, {value: "BBSA02", label: "갤러리"}, {value: "BBSA03", label: "일반게시판"}];
const posblAtchFileNumberOptions = [{value: 0, label: "선택하세요"}, {value: 1, label: "1개"}, {value: 2, label: "2개"}, {value: 3, label: "3개"}]; const posblAtchFileNumberOptions = [{value: 0, label: "선택하세요"}, {value: 1, label: "1개"}, {value: 2, label: "2개"}, {value: 3, label: "3개"}];
const bbsId = location.state?.bbsId || "";
const [modeInfo, setModeInfo] = useState({ mode: props.mode }); let item = null;
item = props.props;
console.log("@@@ item : " + JSON.stringify(item));
const [modeInfo, setModeInfo] = useState(item != null ? {mode: props.props.mode} : {mode: CODE.MODE_CREATE});
const [boardDetail, setBoardDetail] = useState({}); const [boardDetail, setBoardDetail] = useState({});
console.log("@@@ mode : " + modeInfo.mode);
const initMode = () => { const initMode = () => {
switch (props.mode) {
case CODE.MODE_CREATE:
setModeInfo({
...modeInfo,
modeTitle: "등록",
editURL: '/cop/bbs/insertBBSMasterInfAPI.do'
});
break;
case CODE.MODE_MODIFY:
setModeInfo({
...modeInfo,
modeTitle: "수정",
editURL: `/cop/bbs/updateBBSMasterInfAPI/${bbsId}.do`
});
break;
default:
navigate({pathname: URL.ERROR}, {state: {msg : ""}});
}
retrieveDetail(); retrieveDetail();
} }
const retrieveDetail = () => { const retrieveDetail = () => {
if (modeInfo.mode === CODE.MODE_CREATE) {// / if (modeInfo.mode === CODE.MODE_CREATE) {// /
setBoardDetail({
tmplatId: "TMPLAT_BOARD_DEFAULT", //Template
replyPosblAt: "Y", //
fileAtchPosblAt: "Y" //
});
return; return;
} }
const retrieveDetailURL = '/cop/bbs/selectBBSMasterInfAPI.do';
const retrieveDetailURL = '/admin/boards/board';
const requestOptions = { const requestOptions = {
method: "POST", method: "GET",
headers: { headers: {
'Content-type': 'application/json', 'Content-type': 'application/json',
}, }
body: JSON.stringify({
bbsId: bbsId
})
} }
EgovNet.requestFetch(retrieveDetailURL, EgovNet.requestFetch(retrieveDetailURL,
@ -81,18 +62,18 @@ function EgovAdminBoardEdit(props) {
function (resp) { function (resp) {
// //
if (modeInfo.mode === CODE.MODE_MODIFY) { if (modeInfo.mode === CODE.MODE_MODIFY) {
setBoardDetail(resp.result.boardMasterVO); setBoardDetail(item);
} }
} }
); );
} }
const formValidator = (formData) => { const formValidator = (formData) => {
if (formData.get('bbsNm') === null || formData.get('bbsNm') === "") { if (formData.get('bbsTitle') === null || formData.get('bbsTitle') === "") {
alert("게시판명은 필수 값입니다."); alert("게시판명은 필수 값입니다.");
return false; return false;
} }
if (formData.get('bbsIntrcn') === null || formData.get('bbsIntrcn') === "") { if (formData.get('bbsDesc') === null || formData.get('bbsDesc') === "") {
alert("게시판 소개는 필수 값입니다."); alert("게시판 소개는 필수 값입니다.");
return false; return false;
} }
@ -146,9 +127,7 @@ function EgovAdminBoardEdit(props) {
requestOptions = { requestOptions = {
method: modeStr, method: modeStr,
headers: { headers: {},
},
body: formData body: formData
} }
@ -162,7 +141,8 @@ function EgovAdminBoardEdit(props) {
} }
} }
); );
}; }
;
} else { } else {
if (formObjValidator(checkRef)) { if (formObjValidator(checkRef)) {
@ -232,183 +212,57 @@ function EgovAdminBoardEdit(props) {
console.groupEnd("EgovAdminBoardEdit"); console.groupEnd("EgovAdminBoardEdit");
return ( return (
<div className="container"> <>
<div className="c_wrap">
{/* <!-- Location --> */}
<div className="location">
<ul>
<li><Link to={URL.MAIN} className="home">Home</Link></li>
<li><Link to={URL.ADMIN}>사이트관리</Link></li>
<li>게시판생성 관리</li>
</ul>
</div>
{/* <!--// Location --> */}
<div className="layout">
{/* <!-- Navigation --> */}
<EgovLeftNav></EgovLeftNav>
{/* <!--// Navigation --> */}
<div className="contents BOARD_CREATE_REG" id="contents">
{/* <!-- 본문 --> */} {/* <!-- 본문 --> */}
<Modal.Header>
<Modal.Title>
{modeInfo.mode === CODE.MODE_CREATE && '게시판 생성'}
{modeInfo.mode === CODE.MODE_MODIFY && '게시판 수정'}
</Modal.Title>
</Modal.Header>
<div className="top_tit"> <Modal.Body>
<h1 className="tit_1">사이트관리</h1>
</div>
{modeInfo.mode === CODE.MODE_CREATE &&
<h2 className="tit_2">게시판 생성</h2>
}
{modeInfo.mode === CODE.MODE_MODIFY &&
<h2 className="tit_2">게시판 수정</h2>
}
<div className="board_view2"> <div className="board_view2">
<dl> <dl>
<dt><label htmlFor="bbsNm">게시판명</label><span className="req">필수</span></dt> <dt><label htmlFor="bbsId">게시판ID</label><span className="req">필수</span></dt>
<dd> <dd>
<input className="f_input2 w_full" type="text" name="bbsNm" title="" id="bbsNm" placeholder="" <input className="f_input2 w_full" type="text" name="bbsId" title="" id="bbsId" placeholder=""
defaultValue={boardDetail.bbsNm} defaultValue={boardDetail?.bbsId}
onChange={e => setBoardDetail({ ...boardDetail, bbsNm: e.target.value })} onChange={e => setBoardDetail({...boardDetail, bbsId: e.target.value})}
ref={el => (checkRef.current[0] = el)} ref={el => (checkRef.current[0] = el)}
/> />
</dd> </dd>
</dl> </dl>
<dl> <dl>
<dt><label htmlFor="bbsIntrcn">게시판 소개</label><span className="req">필수</span></dt> <dt><label htmlFor="bbsTitle">게시판명</label><span className="req">필수</span></dt>
<dd> <dd>
<textarea className="f_txtar w_full h_100" name="bbsIntrcn" id="bbsIntrcn" cols="30" rows="10" placeholder="" <input className="f_input2 w_full" type="text" name="bbsTitle" title="" id="bbsTitle" placeholder=""
defaultValue={boardDetail.bbsIntrcn} defaultValue={boardDetail?.bbsTitle}
onChange={e => setBoardDetail({ ...boardDetail, bbsIntrcn: e.target.value })} onChange={e => setBoardDetail({...boardDetail, bbsTitle: e.target.value})}
ref={el => (checkRef.current[0] = el)}
/>
</dd>
</dl>
<dl>
<dt><label htmlFor="bbsDesc">게시판 소개</label><span className="req">필수</span></dt>
<dd>
<textarea className="f_txtar w_full h_100" name="bbsDesc" id="bbsDesc" cols="30" rows="10" placeholder=""
defaultValue={boardDetail?.bbsDesc}
onChange={e => setBoardDetail({...boardDetail, bbsDesc: e.target.value})}
ref={el => (checkRef.current[1] = el)} ref={el => (checkRef.current[1] = el)}
></textarea> ></textarea>
</dd> </dd>
</dl> </dl>
<dl>
<dt>게시판 유형<span className="req">필수</span></dt>
<dd>
{/* 수정/조회 일때 변경 불가 */}
{modeInfo.mode === CODE.MODE_CREATE &&
<label className="f_select w_130" htmlFor="bbsTyCode">
<select
id="bbsTyCode"
name="bbsTyCode"
title="게시판유형선택"
onChange={(e) => setBoardDetail({ ...boardDetail, bbsTyCode: e.target.value })}
value={boardDetail.bbsTyCode}
>
{bbsTyCodeOptions.map((option, i) => {
return (
<option value={option.value} key={option.value}>
{option.label}
</option>
)
})}
</select>
</label>
}
{modeInfo.mode === CODE.MODE_MODIFY &&
<span>
{boardDetail.bbsTyCode && getSelectedLabel(bbsTyCodeOptions, boardDetail.bbsTyCode)}
</span>
}
</dd>
</dl>
<dl>
<dt>게시판 속성<span className="req">필수</span></dt>
<dd>
{/* 등록 일때 변경 가능 */}
{modeInfo.mode === CODE.MODE_CREATE &&
<label className="f_select w_130" htmlFor="bbsAttrbCode">
<select
id="bbsAttrbCode"
name="bbsAttrbCode"
title="게시판속성선택"
onChange={(e) => setBoardDetail({ ...boardDetail, bbsAttrbCode: e.target.value })}
value={boardDetail.bbsAttrbCode}
>
{bbsAttrbCodeOptions.map((option, i) => {
return (
<option value={option.value} key={option.value}>
{option.label}
</option>
)
})}
</select>
</label>
}
{/* 수정/조회 일때 변경 불가 */}
{modeInfo.mode === CODE.MODE_MODIFY &&
<span>
{boardDetail.bbsAttrbCode && getSelectedLabel(bbsAttrbCodeOptions, boardDetail.bbsAttrbCode)}
</span>
}
</dd>
</dl>
<dl>
<dt>답장가능여부<span className="req">필수</span></dt>
<dd>
{/* 등록 일때 변경 가능 */}
{modeInfo.mode === CODE.MODE_CREATE &&
<EgovRadioButtonGroup
name="replyPosblAt"
radioGroup={replyPosblAtRadioGroup}
setValue={boardDetail.replyPosblAt}
setter={(v) => setBoardDetail({ ...boardDetail, replyPosblAt: v })} />
}
{/* 수정/조회 일때 변경 불가 */}
{modeInfo.mode === CODE.MODE_MODIFY &&
<span>
{boardDetail.replyPosblAt && getSelectedLabel(replyPosblAtRadioGroup, boardDetail.replyPosblAt)}
</span>
}
</dd>
</dl>
<dl>
<dt>파일첨부가능여부<span className="req">필수</span></dt>
<dd>
<EgovRadioButtonGroup
name="fileAtchPosblAt"
radioGroup={fileAtchPosblAtRadioGroup}
setValue={boardDetail.fileAtchPosblAt}
setter={(v) => setBoardDetail({ ...boardDetail, fileAtchPosblAt: v })} />
</dd>
</dl>
<dl>
<dt><label htmlFor="schdulDeptName">첨부파일가능파일 숫자</label><span className="req">필수</span></dt>
<dd>
<label className="f_select " htmlFor="posblAtchFileNumber">
<select
id="posblAtchFileNumber"
name="posblAtchFileNumber"
title="첨부가능파일 숫자선택"
onChange={(e) => setBoardDetail({ ...boardDetail, posblAtchFileNumber: e.target.value })}
value={boardDetail.posblAtchFileNumber}
ref={el => (checkRef.current[2] = el)}
>
{posblAtchFileNumberOptions.map((option, i) => {
return (
<option value={option.value} key={option.value}>
{option.label}
</option>
)
})}
</select>
</label>
</dd>
</dl>
{/* <!-- 버튼영역 --> */} {/* <!-- 버튼영역 --> */}
<div className="board_btn_area"> <div className="board_btn_area">
<div className="left_col btn1"> <div className="left_col btn1">
<button className="btn btn_skyblue_h46 w_100" <button className="btn btn_skyblue_h46 w_100"
onClick={() => updateBoard()}>저장</button> onClick={() => updateBoard()}>저장
</button>
{modeInfo.mode === CODE.MODE_MODIFY && {modeInfo.mode === CODE.MODE_MODIFY &&
<button className="btn btn_skyblue_h46 w_100" onClick={() => { <button className="btn btn_skyblue_h46 w_100" onClick={() => {
deleteBoardArticle(boardDetail.bbsId); deleteBoardArticle(boardDetail?.bbsId);
}}>삭제</button> }}>삭제</button>
} }
</div> </div>
@ -419,12 +273,8 @@ function EgovAdminBoardEdit(props) {
</div> </div>
{/* <!--// 버튼영역 --> */} {/* <!--// 버튼영역 --> */}
</div> </div>
</Modal.Body>
{/* <!--// 본문 --> */} </>
</div>
</div>
</div>
</div>
); );
} }

View File

@ -3,11 +3,15 @@ import { Link, useLocation } from 'react-router-dom';
import * as EgovNet from 'api/egovFetch'; import * as EgovNet from 'api/egovFetch';
import URL from 'constants/url'; import URL from 'constants/url';
import CODE from 'constants/code';
import { default as EgovLeftNav } from 'components/leftmenu/EgovLeftNavAdmin'; import { default as EgovLeftNav } from 'components/leftmenu/EgovLeftNavAdmin';
import EgovPaging from 'components/EgovPaging'; import EgovPaging from 'components/EgovPaging';
import { itemIdxByPage } from 'utils/calc'; import { itemIdxByPage } from 'utils/calc';
import MenuModal from "../config/menuMgt/MenuModal";
import Modal from "react-bootstrap/Modal";
import EgovAdminBoardEdit from "../board/EgovAdminBoardEdit";
function EgovAdminBoardList(props) { function EgovAdminBoardList(props) {
console.group("EgovAdminBoardList"); console.group("EgovAdminBoardList");
@ -20,10 +24,15 @@ function EgovAdminBoardList(props) {
// eslint-disable-next-line no-unused-vars // 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', searchWrd: '' });// ||
const [paginationInfo, setPaginationInfo] = useState({}); const [paginationInfo, setPaginationInfo] = useState({});
const [listTag, setListTag] = 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(() => { const retrieveList = useCallback(() => {
handleClose();
console.groupCollapsed("AdminBoardList.retrieveList()"); console.groupCollapsed("AdminBoardList.retrieveList()");
const retrieveListURL = '/admin/boards/board-list'; const retrieveListURL = '/admin/boards/board-list';
@ -49,14 +58,15 @@ function EgovAdminBoardList(props) {
if (index === 0) mutListTag = []; // if (index === 0) mutListTag = []; //
mutListTag.push( mutListTag.push(
<Link className="list_item"> <div className="list_item">
<div>{item.bbsSeq}</div> <div>{item.bbsSeq}</div>
<div>{item.bbsId}</div> <div>{item.bbsId}</div>
<div>{item.bbsTitle}</div> <div>{item.bbsTitle}</div>
<div>{item.frstCrtId}</div> <div>{item.frstCrtId}</div>
<div>{item.frstCrtDt}</div> <div>{item.frstCrtDt}</div>
<div>{item.lastChgDt}</div> <div>{item.lastChgDt}</div>
</Link> <div><button className={"btn btn_blue_h31 px-1"} onClick={()=>{editBoard(item)}}>수정</button></div>
</div>
); );
}); });
@ -75,6 +85,14 @@ function EgovAdminBoardList(props) {
// eslint-disable-next-line react-hooks/exhaustive-deps // eslint-disable-next-line react-hooks/exhaustive-deps
}, []); }, []);
function editBoard(item){
handleShow();
if(item != undefined) {
item.mode = CODE.MODE_MODIFY;
}
setModalBody(<EgovAdminBoardEdit props={item}/>)
}
console.log("------------------------------EgovAdminBoardList [End]"); console.log("------------------------------EgovAdminBoardList [End]");
console.groupEnd("EgovAdminBoardList"); console.groupEnd("EgovAdminBoardList");
return ( return (
@ -150,6 +168,7 @@ function EgovAdminBoardList(props) {
<span>작성자</span> <span>작성자</span>
<span>작성일</span> <span>작성일</span>
<span>수정일</span> <span>수정일</span>
<span><button className={"btn btn_blue_h31 px-1"} onClick={()=>{editBoard(undefined)}}>추가</button></span>
</div> </div>
<div className="result"> <div className="result">
{listTag} {listTag}
@ -169,6 +188,9 @@ function EgovAdminBoardList(props) {
</div> </div>
</div> </div>
</div> </div>
<Modal show={show} onHide={handleClose} keyboard={false}>
{modalBody}
</Modal>
</div> </div>

View File

@ -1,5 +1,6 @@
package com.dbnt.kcscbackend.admin.boards; package com.dbnt.kcscbackend.admin.boards;
import com.dbnt.kcscbackend.admin.boards.entity.TnBbs;
import com.dbnt.kcscbackend.admin.boards.service.AdminBoardsService; import com.dbnt.kcscbackend.admin.boards.service.AdminBoardsService;
import com.dbnt.kcscbackend.config.common.BaseController; import com.dbnt.kcscbackend.config.common.BaseController;
import com.dbnt.kcscbackend.config.common.ResultVO; import com.dbnt.kcscbackend.config.common.ResultVO;
@ -42,4 +43,25 @@ public class AdminBoardsController extends BaseController {
resultVO.setResult(resultMap); resultVO.setResult(resultMap);
return resultVO; return resultVO;
} }
@Operation(
summary = "게시판 단건 조회",
description = "게시판 단건 조회",
tags = {"AdminBoardsController"}
)
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "조회 성공"),
@ApiResponse(responseCode = "403", description = "인가된 사용자가 아님")
})
@RequestMapping(method = RequestMethod.GET, value = "/board", consumes = MediaType.APPLICATION_JSON_VALUE)
public ResultVO getBoard(TnBbs tnBbs) throws Exception {
ResultVO resultVO = new ResultVO();
Map<String, Object> resultMap = new HashMap<>();
System.out.println("@@@ : " + tnBbs.getBbsSeq());
resultMap.put("board", adminBoardsService.selectBoard(tnBbs.getBbsSeq()));
resultVO.setResult(resultMap);
return resultVO;
}
} }

View File

@ -7,6 +7,7 @@ import org.egovframe.rte.fdl.cmmn.EgovAbstractServiceImpl;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.util.List; import java.util.List;
import java.util.Optional;
@Service @Service
@RequiredArgsConstructor @RequiredArgsConstructor
@ -16,4 +17,6 @@ public class AdminBoardsService extends EgovAbstractServiceImpl {
public List<TnBbs> selectBoardList() { return tnBbsRepository.findAll(); } public List<TnBbs> selectBoardList() { return tnBbsRepository.findAll(); }
public Optional<TnBbs> selectBoard(Long bbsSeq) { return tnBbsRepository.findById(bbsSeq); }
} }