사용자 목록 페이지 검색기능 추가.

thkim
강석 최 2024-01-15 16:18:06 +09:00
parent ebdecf4b62
commit 881f4fc080
7 changed files with 89 additions and 91 deletions

View File

@ -10,6 +10,16 @@ export function getQueryString(params){
return `?${Object.entries(params).map(e => e.join('=')).join('&') }`
}
export function convParams(params){
let str = "?"
for(let key in params){
if(params[key]){
str = str+key+"="+params[key]+"&";
}
}
return str;
}
export function requestFetch(url, requestOptions, handler, errorHandler) {
console.groupCollapsed("requestFetch");
console.log("requestFetch [URL] : ", SERVER_URL + url);

View File

@ -2,7 +2,7 @@ import React, {useCallback, useEffect, useState} from "react";
import Form from "react-bootstrap/Form";
import * as EgovNet from "api/egovFetch";
function CheckBox({name, grpCd}){
function CheckBox({name, grpCd, selectedValue}){
const [checkBox, setCheckBox] = useState();
@ -10,6 +10,15 @@ function CheckBox({name, grpCd}){
getCodeItemList()
}, []);
useEffect(() => {
if(selectedValue){
const itemCdAry = selectedValue.split(',');
itemCdAry.forEach(function(itemCd){
document.querySelector(`#chkBox_${itemCd}`).checked = true;
})
}
}, [selectedValue]);
function getCodeItemList() {
EgovNet.requestFetch(
'/commonCode/code-item?grpCd='+grpCd,
@ -25,8 +34,7 @@ function CheckBox({name, grpCd}){
id={`chkBox_${item.itemCd}`}
key={`chkBox_${item.itemCd}_${index}`}
name={name}
defaultValue={item.itemCd}
onChange={()=>{}}
value={item.itemCd}
/>
);
});

View File

@ -5,10 +5,14 @@ import * as EgovNet from "api/egovFetch";
function SelectOption({name, grpCd, selectedValue}){
const [options, setOptions] = useState();
const [value, setValue] = useState(selectedValue)
useEffect(() => {
getCodeItemList()
}, []);
useEffect(() => {
setValue(selectedValue)
}, [selectedValue]);
function getCodeItemList(){
EgovNet.requestFetch(
@ -33,7 +37,7 @@ function SelectOption({name, grpCd, selectedValue}){
}
return (
<Form.Select name={name} value={selectedValue} onChange={()=>{}}>
<Form.Select name={name} value={value} onChange={(e)=>{setValue(e.target.value)}}>
{options}
</Form.Select>
)

View File

@ -1,27 +1,27 @@
import React, {useCallback, useEffect, useRef, useState} from 'react';
import {Link, useLocation} from "react-router-dom";
import React, {useCallback, useEffect, useState} from 'react';
import {Link} from "react-router-dom";
import URL from "constants/url";
import { default as EgovLeftNav } from 'components/leftmenu/EgovLeftNavAdmin';
import EgovPaging from "components/EgovPaging";
import * as EgovNet from "api/egovFetch";
import {itemIdxByPage} from "utils/calc";
import Modal from "react-bootstrap/Modal";
import UserInfoModal from "./UserInfoModal";
import CODE from "../../../constants/code";
function List(props) {
function List({}) {
const location = useLocation();
const [searchCondition, setSearchCondition] = useState({
pageIndex: 1,
userSe: '',
searchCondition: 'id',
searchKeyword: ''
});
const [searchCondition, setSearchCondition] = useState(location.state?.searchCondition || { pageIndex: 1, searchCnd: '0', searchWrd: '' });// ||
const [listTag, setListTag] = useState([]);
const [paginationInfo, setPaginationInfo] = useState({});
const cndRef = useRef();
const wrdRef = useRef();
const [show, setShow] = useState(false);
const [modalBody, setModalBody] = useState();
@ -29,7 +29,7 @@ function List(props) {
const handleShow = () => setShow(true);
const retrieveList = useCallback((searchCondition) => {
const params = "?";
const params = EgovNet.convParams(searchCondition);
EgovNet.requestFetch(
'/admin/users/list'+params,
{
@ -37,19 +37,11 @@ function List(props) {
},
(resp) => {
setPaginationInfo(resp.result.paginationInfo);
let mutListTag = [];
const resultCnt = parseInt(resp.result.contentCnt);
const currentPageNo = resp.result.paginationInfo.pageIndex;
const pageSize = resp.result.paginationInfo.rowCnt;
setListTag([]);
//
resp.result.userList.forEach(function (item, index) {
const listIdx = itemIdxByPage(resultCnt , currentPageNo, pageSize, index);
mutListTag.push(
<div className={"list_item"} key={"userListDiv_"+index}>
<div>{item.userSe}</div>
@ -75,12 +67,20 @@ function List(props) {
retrieveList(searchCondition);
}, []);
useEffect(() => {
retrieveList(searchCondition);
}, [searchCondition.pageIndex]);
const movePage = useCallback((passedPage) => {
setSearchCondition({...searchCondition, pageIndex: passedPage})
});
function userInfoModal(userSeq){
handleShow()
setModalBody(<UserInfoModal userSeq={userSeq}></UserInfoModal>)
setModalBody(<UserInfoModal userSeq={userSeq} reloadFunction={retrieveList}></UserInfoModal>)
}
function removeUserInfo(seq){
const removeUserInfo = useCallback((seq)=>{
if(window.confirm("삭제하시겠습니까?\n복구할 수 없습니다.")){
EgovNet.requestFetch(
'/admin/users/info',
@ -94,13 +94,14 @@ function List(props) {
(resp) => {
if (Number(resp.resultCode) === Number(CODE.RCV_SUCCESS)) {
alert("삭제되었습니다.")
retrieveList(searchCondition)
}else{
alert("삭제를 실패하였습니다.")
}
}
)
}
}
});
return (
<div className="container">
@ -128,18 +129,19 @@ function List(props) {
<ul>
<li className="third_1 L">
<label className="f_select" htmlFor="sel1">
<select id="sel1" title="조건" defaultValue={searchCondition.searchCnd} ref={cndRef}
onChange={e => {cndRef.current.value = e.target.value;}}>
<option value="0">전체</option>
<option value="1">일반사용자</option>
<option value="2">관리자</option>
<select id="sel1" title="구분" defaultValue={searchCondition.userSe}
onChange={(e) => {setSearchCondition({...searchCondition, userSe: e.target.value})}}>
<option value="">전체</option>
<option value="ACC_TP01">관리자</option>
<option value="ACC_TP02">일반사용자</option>
</select>
</label>
</li>
<li className="third_1 L">
<label className="f_select" htmlFor="sel1">
<select id="sel1" title="조건" defaultValue={searchCondition.searchCnd} ref={cndRef}
onChange={e => {cndRef.current.value = e.target.value;}}>
<select id="sel1" title="조건" defaultValue={searchCondition.searchCondition}
onChange={(e) => {setSearchCondition({...searchCondition, searchCondition: e.target.value})}}>
<option value="id">아이디</option>
<option value="name">이름</option>
<option value="email">이메일</option>
@ -149,15 +151,9 @@ function List(props) {
</li>
<li className="third_2 R">
<span className="f_search w_500">
<input type="text" name="" defaultValue={searchCondition.searchWrd} placeholder="" ref={wrdRef}
onChange={e => {
wrdRef.current.value = e.target.value;
}}
/>
<button type="button"
onClick={() => {
retrieveList({ ...searchCondition, pageIndex: 1, searchCnd: cndRef.current.value, searchWrd: wrdRef.current.value });
}}>조회</button>
<input type="text" name="" defaultValue={searchCondition.searchKeyword} placeholder=""
onChange={(e) => {setSearchCondition({...searchCondition, searchKeyword: e.target.value})}}/>
<button type="button" onClick={() => {retrieveList(searchCondition)}}>조회</button>
</span>
</li>
</ul>
@ -179,15 +175,7 @@ function List(props) {
</div>
<div className="board_bot">
<EgovPaging pagination={paginationInfo}
moveToPage={passedPage => {
retrieveList({
...searchCondition,
pageIndex: passedPage,
searchCnd: cndRef.current.value,
searchWrd: wrdRef.current.value
})
}} />
<EgovPaging pagination={paginationInfo} moveToPage={passedPage => {movePage(passedPage)}} />
</div>
</div>
</div>

View File

@ -9,7 +9,7 @@ import SelectOption from "components/commonCode/SelectOption";
import CheckBox from "components/commonCode/CheckBox";
import CODE from "../../../constants/code";
function UserInfoModal({userSeq}){
function UserInfoModal({userSeq, reloadFunction}){
const [userInfo, setUserInfo] = useState({ userSeq: '', userId: '', password: '', passwordChk: '', userNm: '', email: '', phoneNum: '', userSe:'', userRole:'', status:''});
@ -78,6 +78,7 @@ function UserInfoModal({userSeq}){
(resp) => {
if (Number(resp.resultCode) === Number(CODE.RCV_SUCCESS)) {
alert("저장되었습니다.")
reloadFunction();
}else if(Number(resp.resultCode) === Number(CODE.RCV_ERROR_AUTH)){
console.log("토큰 갱신중.")
}else{
@ -91,19 +92,6 @@ function UserInfoModal({userSeq}){
getModalContent();
}, []);
useEffect(()=>{
const checkBoxDiv = document.querySelector("#ROLE_checkBoxDiv")
const userRole = userInfo.userRole;
if(userRole){
checkBoxDiv.childNodes.forEach(function (div){
const input = div.children[0];
if(userRole.includes(input.value)){
input.checked = true;
}
})
}
}, [userInfo]);
return (
<>
<Modal.Header closeButton>
@ -175,7 +163,7 @@ function UserInfoModal({userSeq}){
사용자 권한
</Form.Label>
<Col sm={9}>
<CheckBox name={"userRole"} grpCd={"ROLE"} />
<CheckBox name={"userRole"} grpCd={"ROLE"} selectedValue={userInfo?.userRole} />
</Col>
</Form.Group>
<Form.Group as={Row} className="mb-3">

View File

@ -85,37 +85,35 @@ public class AdminUsersController extends BaseController {
@RequestMapping(method = RequestMethod.PUT, value = "/info")
public ResultVO modifyUserInfo(@RequestBody @Valid UserInfo info, Errors errors, @AuthenticationPrincipal LoginVO user) throws Exception{
ResultVO resultVO = new ResultVO();
Map<String, Object> resultMap = new HashMap<>();
if(errors.hasErrors()){
StringBuilder msg = new StringBuilder();
for(FieldError error: errors.getFieldErrors()){
msg.append(error.getDefaultMessage());
msg.append("\n");
}
resultMap.put("resultCode", ResponseCode.INPUT_CHECK_ERROR.getCode());
resultMap.put("resultMessage", msg.toString());
resultVO.setResultCode(ResponseCode.INPUT_CHECK_ERROR.getCode());
resultVO.setResultMessage(msg.toString());
}else if(!info.getPassword().equals(info.getPasswordChk())){
resultMap.put("resultCode", ResponseCode.SAVE_ERROR.getCode());
resultMap.put("resultMessage", "비밀번호 확인이 잘못 입력되었습니다.");
resultVO.setResultCode(ResponseCode.SAVE_ERROR.getCode());
resultVO.setResultMessage("비밀번호 확인이 잘못 입력되었습니다.");
}else {
Integer insertResult = adminUsersService.updateUserInfo(info, user.getId());
if(insertResult!=null){
if(insertResult==-1){
resultMap.put("resultCode", ResponseCode.SAVE_ERROR.getCode());
resultMap.put("resultMessage", "수정 대상이 존재하지 않습니다.");
resultVO.setResultCode(ResponseCode.SAVE_ERROR.getCode());
resultVO.setResultMessage("수정 대상이 존재하지 않습니다.");
}else if(insertResult==-2){
resultMap.put("resultCode", ResponseCode.SAVE_ERROR.getCode());
resultMap.put("resultMessage", "가입된 이메일입니다.");
resultVO.setResultCode(ResponseCode.SAVE_ERROR.getCode());
resultVO.setResultMessage("가입된 이메일입니다.");
}else{
resultMap.put("resultCode", ResponseCode.SUCCESS.getCode());
resultMap.put("resultMessage", "저장 되었습니다.");
resultVO.setResultCode(ResponseCode.SUCCESS.getCode());
resultVO.setResultMessage("저장 되었습니다.");
}
}else{
resultMap.put("resultCode", ResponseCode.SAVE_ERROR.getCode());
resultMap.put("resultMessage", "저장에 실패하였습니다.");
resultVO.setResultCode(ResponseCode.SAVE_ERROR.getCode());
resultVO.setResultMessage("저장에 실패하였습니다.");
}
}
resultVO.setResult(resultMap);
return resultVO;
}
@ -129,7 +127,7 @@ public class AdminUsersController extends BaseController {
@ApiResponse(responseCode = "403", description = "인가된 사용자가 아님")
})
@RequestMapping(method = RequestMethod.DELETE, value = "/info", consumes = MediaType.APPLICATION_JSON_VALUE)
public ResultVO deleteUserInfo(UserInfo info) throws Exception{
public ResultVO deleteUserInfo(@RequestBody UserInfo info) throws Exception{
ResultVO resultVO = new ResultVO();
adminUsersService.deleteUserInfo(info.getUserSeq());
resultVO.setResultCode(ResponseCode.SUCCESS.getCode());

View File

@ -31,17 +31,19 @@
<if test='userSe != null and userSe != ""'>
and user_se = #{userSe}
</if>
<if test='searchCondition == "id"'>
and user_id like '%'||#{searchKeyword}||'%'
</if>
<if test='searchCondition == "name"'>
and user_nm like '%'||#{searchKeyword}||'%'
</if>
<if test='searchCondition == "email"'>
and email like '%'||#{searchKeyword}||'%'
</if>
<if test='searchCondition == "phoneNum"'>
and phone_num like '%'||#{searchKeyword}||'%'
<if test='searchKeyword != null and searchKeyword != ""'>
<if test='searchCondition == "id"'>
and user_id like '%'||#{searchKeyword}||'%'
</if>
<if test='searchCondition == "name"'>
and user_nm like '%'||#{searchKeyword}||'%'
</if>
<if test='searchCondition == "email"'>
and email like '%'||#{searchKeyword}||'%'
</if>
<if test='searchCondition == "phoneNum"'>
and phone_num like '%'||#{searchKeyword}||'%'
</if>
</if>
</where>
</sql>