Compare commits

..

No commits in common. "ebdecf4b62f9025e06386ee819b911bf8719220b" and "acde8223eac17128b20328286ade5899fe701e9d" have entirely different histories.

7 changed files with 35 additions and 227 deletions

View File

@ -2,13 +2,16 @@ import React, {useCallback, useEffect, useState} from "react";
import Form from "react-bootstrap/Form"; import Form from "react-bootstrap/Form";
import * as EgovNet from "api/egovFetch"; import * as EgovNet from "api/egovFetch";
function CheckBox({name, grpCd}){ function CheckBox({name, grpCd, selectedValue}){
const [checkBox, setCheckBox] = useState(); const [checkBox, setCheckBox] = useState();
useEffect(() => { useEffect(() => {
getCodeItemList() getCodeItemList()
}, []); }, []);
useEffect(() => {
setCheckedValue(selectedValue)
}, [checkBox]);
function getCodeItemList() { function getCodeItemList() {
EgovNet.requestFetch( EgovNet.requestFetch(
@ -38,6 +41,16 @@ function CheckBox({name, grpCd}){
); );
} }
function setCheckedValue(selectedValue){
debugger
const checkBoxDiv = document.querySelector("#"+grpCd+"_checkBoxDiv")
checkBoxDiv.childNodes.forEach(function (input){
if(selectedValue.includes(input.children[0].value)){
input.checked = true;
}
})
}
return ( return (
<div id={`${grpCd}_checkBoxDiv`} key={`checkBox_${grpCd}`}> <div id={`${grpCd}_checkBoxDiv`} key={`checkBox_${grpCd}`}>
{checkBox} {checkBox}

View File

@ -8,7 +8,6 @@ import * as EgovNet from "api/egovFetch";
import {itemIdxByPage} from "utils/calc"; import {itemIdxByPage} from "utils/calc";
import Modal from "react-bootstrap/Modal"; import Modal from "react-bootstrap/Modal";
import UserInfoModal from "./UserInfoModal"; import UserInfoModal from "./UserInfoModal";
import CODE from "../../../constants/code";
function List(props) { function List(props) {
@ -58,7 +57,7 @@ function List(props) {
<div>{item.email}</div> <div>{item.email}</div>
<div>{item.phoneNum}</div> <div>{item.phoneNum}</div>
<div>{item.status}</div> <div>{item.status}</div>
<div><button className={"btn btn_red_h31 px-1"} onClick={()=>{removeUserInfo(item.userSeq)}}>삭제</button></div> <div><button className={"btn btn_red_h31 px-1"}>삭제</button></div>
</div> </div>
); );
}); });
@ -79,28 +78,6 @@ function List(props) {
handleShow() handleShow()
setModalBody(<UserInfoModal userSeq={userSeq}></UserInfoModal>) setModalBody(<UserInfoModal userSeq={userSeq}></UserInfoModal>)
} }
function removeUserInfo(seq){
if(window.confirm("삭제하시겠습니까?\n복구할 수 없습니다.")){
EgovNet.requestFetch(
'/admin/users/info',
{
method: "DELETE",
headers: {
'Content-type': 'application/json'
},
body: JSON.stringify({userSeq: seq})
},
(resp) => {
if (Number(resp.resultCode) === Number(CODE.RCV_SUCCESS)) {
alert("삭제되었습니다.")
}else{
alert("삭제를 실패하였습니다.")
}
}
)
}
}
return ( return (
<div className="container"> <div className="container">

View File

@ -7,11 +7,10 @@ import Col from "react-bootstrap/Col";
import Button from "react-bootstrap/Button"; import Button from "react-bootstrap/Button";
import SelectOption from "components/commonCode/SelectOption"; import SelectOption from "components/commonCode/SelectOption";
import CheckBox from "components/commonCode/CheckBox"; import CheckBox from "components/commonCode/CheckBox";
import CODE from "../../../constants/code";
function UserInfoModal({userSeq}){ function UserInfoModal({userSeq}){
const [userInfo, setUserInfo] = useState({ userSeq: '', userId: '', password: '', passwordChk: '', userNm: '', email: '', phoneNum: '', userSe:'', userRole:'', status:''}); const [userInfo, setUserInfo] = useState({ userId: '', password: '', passwordChk: '', userNm: '', email: '', phoneNum: '', userSe:'', userRole:'', status:''});
function getModalContent(){ function getModalContent(){
EgovNet.requestFetch( EgovNet.requestFetch(
@ -20,20 +19,18 @@ function UserInfoModal({userSeq}){
method: "GET" method: "GET"
}, },
(resp) => { (resp) => {
const respInfo = resp.result.userInfo; const respInfo = {
const info = { userId: resp.result.userInfo.userId,
userSeq: respInfo.userSeq, userNm: resp.result.userInfo.userNm,
userId: respInfo.userId, email: resp.result.userInfo.email,
userNm: respInfo.userNm, phoneNum: resp.result.userInfo.phoneNum,
email: respInfo.email,
phoneNum: respInfo.phoneNum,
password: "", password: "",
passwordChk: "", passwordChk: "",
userSe: respInfo.userSe, userSe: resp.result.userInfo.userSe,
userRole: respInfo.userRole, userRole: resp.result.userInfo.userRole,
status: respInfo.status status: resp.result.userInfo.status
} }
setUserInfo(info); setUserInfo(respInfo);
}, },
(resp) => { (resp) => {
console.log("err response : ", resp); console.log("err response : ", resp);
@ -42,68 +39,13 @@ function UserInfoModal({userSeq}){
} }
function userInfoChange(e){ function userInfoChange(e){
e.preventDefault(); debugger
e.stopPropagation();
const form = e.target;
const info = {
userSeq: form.userSeq.value,
userId: form.userId.value,
password: form.password.value,
passwordChk: form.passwordChk.value,
userNm: form.userNm.value,
email: form.email.value,
phoneNum: form.phoneNum.value,
userSe: form.userSe.value,
userRole: '',
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',
{
method: "PUT",
headers: {
'Content-type': 'application/json'
},
body: JSON.stringify(info)
},
(resp) => {
if (Number(resp.resultCode) === Number(CODE.RCV_SUCCESS)) {
alert("저장되었습니다.")
}else if(Number(resp.resultCode) === Number(CODE.RCV_ERROR_AUTH)){
console.log("토큰 갱신중.")
}else{
alert(resp.result.resultMessage)
}
}
)
} }
useEffect(() => { useEffect(() => {
getModalContent(); 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 ( return (
<> <>
<Modal.Header closeButton> <Modal.Header closeButton>
@ -113,13 +55,12 @@ function UserInfoModal({userSeq}){
</Modal.Header> </Modal.Header>
<Modal.Body> <Modal.Body>
<Form onSubmit={(e) =>{userInfoChange(e)}} noValidate> <Form onSubmit={(e) =>{userInfoChange(e)}} noValidate>
<input type={"hidden"} name={"userSeq"} defaultValue={userInfo.userSeq} />
<Form.Group as={Row} className="mb-3"> <Form.Group as={Row} className="mb-3">
<Form.Label column sm={3}> <Form.Label column sm={3}>
아이디 아이디
</Form.Label> </Form.Label>
<Col sm={9}> <Col sm={9}>
<Form.Control type="text" name="userId" placeholder="아이디" required defaultValue={userInfo?.userId} readOnly/> <Form.Control type="text" name="userId" placeholder="아이디" required defaultValue={userInfo?.userId} />
</Col> </Col>
</Form.Group> </Form.Group>
<Form.Group as={Row} className="mb-3"> <Form.Group as={Row} className="mb-3">
@ -175,7 +116,7 @@ function UserInfoModal({userSeq}){
사용자 권한 사용자 권한
</Form.Label> </Form.Label>
<Col sm={9}> <Col sm={9}>
<CheckBox name={"userRole"} grpCd={"ROLE"} /> <CheckBox name={"userRole"} grpCd={"ROLE"} selectedValue={userInfo?.userRole} />
</Col> </Col>
</Form.Group> </Form.Group>
<Form.Group as={Row} className="mb-3"> <Form.Group as={Row} className="mb-3">

View File

@ -2,26 +2,18 @@ package com.dbnt.kcscbackend.admin.users;
import com.dbnt.kcscbackend.admin.users.service.AdminUsersService; import com.dbnt.kcscbackend.admin.users.service.AdminUsersService;
import com.dbnt.kcscbackend.auth.entity.LoginVO;
import com.dbnt.kcscbackend.auth.entity.UserInfo; import com.dbnt.kcscbackend.auth.entity.UserInfo;
import com.dbnt.kcscbackend.config.common.BaseController; 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.config.common.ResultVO;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses; import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor; 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.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import javax.validation.Valid;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
@ -73,67 +65,4 @@ public class AdminUsersController extends BaseController {
return resultVO; return resultVO;
} }
@Operation(
summary = "사용자 정보 수정",
description = "사용자 정보 수정",
tags = {"AdminUsersController"}
)
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "수정 성공"),
@ApiResponse(responseCode = "403", description = "인가된 사용자가 아님")
})
@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());
}else if(!info.getPassword().equals(info.getPasswordChk())){
resultMap.put("resultCode", ResponseCode.SAVE_ERROR.getCode());
resultMap.put("resultMessage", "비밀번호 확인이 잘못 입력되었습니다.");
}else {
Integer insertResult = adminUsersService.updateUserInfo(info, user.getId());
if(insertResult!=null){
if(insertResult==-1){
resultMap.put("resultCode", ResponseCode.SAVE_ERROR.getCode());
resultMap.put("resultMessage", "수정 대상이 존재하지 않습니다.");
}else if(insertResult==-2){
resultMap.put("resultCode", ResponseCode.SAVE_ERROR.getCode());
resultMap.put("resultMessage", "가입된 이메일입니다.");
}else{
resultMap.put("resultCode", ResponseCode.SUCCESS.getCode());
resultMap.put("resultMessage", "저장 되었습니다.");
}
}else{
resultMap.put("resultCode", ResponseCode.SAVE_ERROR.getCode());
resultMap.put("resultMessage", "저장에 실패하였습니다.");
}
}
resultVO.setResult(resultMap);
return resultVO;
}
@Operation(
summary = "사용자 정보 삭제",
description = "사용자 정보 삭제",
tags = {"AdminUsersController"}
)
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "삭제 성공"),
@ApiResponse(responseCode = "403", description = "인가된 사용자가 아님")
})
@RequestMapping(method = RequestMethod.DELETE, value = "/info", consumes = MediaType.APPLICATION_JSON_VALUE)
public ResultVO deleteUserInfo(UserInfo info) throws Exception{
ResultVO resultVO = new ResultVO();
adminUsersService.deleteUserInfo(info.getUserSeq());
resultVO.setResultCode(ResponseCode.SUCCESS.getCode());
return resultVO;
}
} }

View File

@ -6,9 +6,7 @@ import com.dbnt.kcscbackend.auth.repository.UserInfoRepository;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.egovframe.rte.fdl.cmmn.EgovAbstractServiceImpl; import org.egovframe.rte.fdl.cmmn.EgovAbstractServiceImpl;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDateTime;
import java.util.List; import java.util.List;
@Service @Service
@ -31,37 +29,4 @@ public class AdminUsersService extends EgovAbstractServiceImpl {
info.setPassword(null); info.setPassword(null);
return info; return info;
} }
@Transactional
public Integer updateUserInfo(UserInfo info, String updateUser) {
UserInfo savedInfo = userInfoRepository.findById(info.getUserSeq()).orElse(null);
UserInfo emailChk = userInfoRepository.findByEmail(info.getEmail()).orElse(null);
if(savedInfo==null){
return -1;
}else if(emailChk != null){
if(!emailChk.getUserSeq().equals(info.getUserSeq())){
return -2;
}
}
savedInfo.setUserNm(info.getUserNm());
if(!info.getPassword().isEmpty()){
savedInfo.setPassword(info.convertPassword(info.getPassword()));
}
savedInfo.setEmail(info.getEmail());
savedInfo.setPhoneNum(info.getPhoneNum());
savedInfo.setUserSe(info.getUserSe());
savedInfo.setUserRole(info.getUserRole());
savedInfo.setStatus(info.getStatus());
savedInfo.setLastChgId(updateUser);
savedInfo.setLastChgDt(LocalDateTime.now());
return savedInfo.getUserSeq();
}
@Transactional
public void deleteUserInfo(Integer userSeq) {
userInfoRepository.deleteById(userSeq);
}
} }

View File

@ -2,7 +2,6 @@ package com.dbnt.kcscbackend.auth.entity;
import com.dbnt.kcscbackend.config.common.BoardParams; import com.dbnt.kcscbackend.config.common.BoardParams;
import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnore;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Getter; import lombok.Getter;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import lombok.Setter; import lombok.Setter;
@ -12,12 +11,8 @@ import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.crypto.password.Pbkdf2PasswordEncoder;
import javax.persistence.*; import javax.persistence.*;
import javax.validation.constraints.Email;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Pattern;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatter;
import java.util.Collection; import java.util.Collection;
@ -37,23 +32,16 @@ public class UserInfo extends BoardParams implements UserDetails{
@Column(name = "user_seq") @Column(name = "user_seq")
private Integer userSeq; private Integer userSeq;
@Column(name = "user_id") @Column(name = "user_id")
@Pattern(regexp = "^[a-zA-Z]{1}[a-zA-Z0-9_]{4,11}$")
@NotBlank(message = "아이디를 입력해주세요.")
private String userId; private String userId;
@Column(name = "password") @Column(name = "password")
private String password; private String password;
@Column(name = "email") @Column(name = "email")
@Email(message = "이메일 형식에 맞지 않습니다.")
@Schema(description = "이메일주소")
@NotBlank(message = "이메일을 입력해주세요.")
private String email; private String email;
@Column(name = "user_se") @Column(name = "user_se")
private String userSe; private String userSe;
@Column(name = "user_nm") @Column(name = "user_nm")
@NotBlank(message = "이름을 입력해주세요.")
private String userNm; private String userNm;
@Column(name = "phone_num") @Column(name = "phone_num")
@NotBlank(message = "연락처를 입력해주세요.")
private String phoneNum; private String phoneNum;
@Column(name = "user_role") @Column(name = "user_role")
private String userRole; private String userRole;
@ -68,9 +56,6 @@ public class UserInfo extends BoardParams implements UserDetails{
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime lastChgDt; private LocalDateTime lastChgDt;
@Transient
private String passwordChk;
@Override @Override
@JsonIgnore @JsonIgnore
public Collection<? extends GrantedAuthority> getAuthorities() { public Collection<? extends GrantedAuthority> getAuthorities() {
@ -107,11 +92,4 @@ public class UserInfo extends BoardParams implements UserDetails{
return getStatus().equals("USE_ST"); return getStatus().equals("USE_ST");
} }
public String convertPassword(String password){
Pbkdf2PasswordEncoder passwordEncoder = new Pbkdf2PasswordEncoder();
return passwordEncoder.encode(password);
}
} }

View File

@ -59,7 +59,7 @@ public class EgovLoginServiceImpl extends EgovAbstractServiceImpl implements Ego
} }
UserInfo info = new UserInfo(); UserInfo info = new UserInfo();
info.setUserId(loginVO.getId()); info.setUserId(loginVO.getId());
info.setPassword(info.convertPassword(loginVO.getPassword())); info.setPassword(convertPassword(loginVO.getPassword()));
info.setUserNm(loginVO.getUserNm()); info.setUserNm(loginVO.getUserNm());
info.setEmail(loginVO.getEmail()); info.setEmail(loginVO.getEmail());
info.setPhoneNum(loginVO.getPhoneNum()); info.setPhoneNum(loginVO.getPhoneNum());
@ -85,7 +85,7 @@ public class EgovLoginServiceImpl extends EgovAbstractServiceImpl implements Ego
int rdNum = rd.nextInt(95)+33; int rdNum = rd.nextInt(95)+33;
password.append((char)rdNum); password.append((char)rdNum);
} }
user.setPassword(user.convertPassword(password.toString())); user.setPassword(convertPassword(password.toString()));
return password.toString(); return password.toString();
} }
return null; return null;
@ -184,4 +184,9 @@ public class EgovLoginServiceImpl extends EgovAbstractServiceImpl implements Ego
return result; return result;
} }
private String convertPassword(String password){
Pbkdf2PasswordEncoder passwordEncoder = new Pbkdf2PasswordEncoder();
return passwordEncoder.encode(password);
}
} }