외사경찰관리 작업중.

TaehunPark 2022-08-30 11:57:53 +09:00
parent 9e362320eb
commit c1403f0e51
11 changed files with 440 additions and 4 deletions

View File

@ -30,7 +30,13 @@ public class CodeMgt {
@Transient
private String status;
@Embeddable
@Override
public String toString() {
return "CodeMgt [categoryCd=" + categoryCd + ", itemCd=" + itemCd + ", itemValue=" + itemValue + ", useChk="
+ useChk + ", status=" + status + "]";
}
@Embeddable
@Data
@NoArgsConstructor
@AllArgsConstructor

View File

@ -60,7 +60,7 @@ public class SecurityConfig{
protected SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.authorizeRequests() // 페이지 권한 설정
.antMatchers("/dashboard", "/refreshSession").hasRole(Role.USER.name()) // USER, ADMIN 접근 허용
.antMatchers("/codeMgt/**", "/menuMgt/**", "/authMgt/**").hasRole(Role.ADMIN.name()) // ADMIN만 접근 허용
.antMatchers("/codeMgt/**", "/menuMgt/**", "/authMgt/**","/userMgt/**").hasRole(Role.ADMIN.name()) // ADMIN만 접근 허용
.antMatchers("/login").permitAll() // 로그인 페이지는 권한 없이 접근 허용
.and() // 로그인 설정
.formLogin() .loginPage("/login") // Custom login form 사용

View File

@ -0,0 +1,58 @@
package com.dbnt.faisp.controller;
import com.dbnt.faisp.authMgt.AuthMgtService;
import com.dbnt.faisp.codeMgt.CodeMgtService;
import com.dbnt.faisp.menuMgt.MenuMgtService;
import com.dbnt.faisp.menuMgt.model.MenuMgt;
import com.dbnt.faisp.userInfo.UserInfoService;
import com.dbnt.faisp.userInfo.model.UserInfo;
import lombok.RequiredArgsConstructor;
import java.util.List;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;
@RestController
@RequiredArgsConstructor
@RequestMapping("/userMgt")
public class userMgtController {
private final MenuMgtService menuMgtService;
private final UserInfoService userInfoService;
private final AuthMgtService authMgtService;
private final CodeMgtService codeMgtService;
@GetMapping("/userMgtPage")
public ModelAndView codeMgtPage(UserInfo userInfo) {
ModelAndView mav = new ModelAndView("adminPage/userMgt/userMgt");
userInfo.setQueryInfo();
if(userInfo.getUserStatus() == "" || userInfo.getUserStatus() == null) {
userInfo.setUserStatus("USC003");
}
mav.addObject("userInfoList", userInfoService.selectUserInfoList(userInfo));
userInfo.setContentCnt(userInfoService.selectUserInfoListCnt(userInfo));
userInfo.setPaginationInfo();
mav.addObject("searchParams", userInfo);
System.out.println("@@"+userInfo);
return mav;
}
@GetMapping("/userEditModal")
public ModelAndView menuEditModal(UserInfo userInfo){
ModelAndView mav = new ModelAndView("adminPage/userMgt/userEditModal");
mav.addObject("OgList", codeMgtService.selectCodeMgtList("OG"));
mav.addObject("OfcList", codeMgtService.selectCodeMgtList("OFC"));
mav.addObject("userInfo", userInfoService.selectUserInfo(userInfo.getUserSeq()));
return mav;
}
@PostMapping("/userApproval")
@ResponseBody
public int userApproval(@RequestBody List<UserInfo> userInfo){
int result = userInfoService.updateUserApproval(userInfo);
return result;
}
}

View File

@ -67,5 +67,19 @@ public class UserInfoService implements UserDetailsService {
public Integer selectUserInfoListCnt(UserInfo userInfo) {
return userInfoMapper.selectUserInfoListCnt(userInfo);
}
public UserInfo selectUserInfo(Integer userSeq) {
return userInfoRepository.findByUserSeq(userSeq);
}
@Transactional
public int updateUserApproval(List<UserInfo> userInfo) {
int cnt = 0;
for(UserInfo user: userInfo) {
UserInfo dbUserInfo = userInfoRepository.findById(user.getUserSeq()).orElse(null);
dbUserInfo.setUserStatus(user.getUserStatus());
cnt++;
}
return cnt;
}
}

View File

@ -93,4 +93,13 @@ public class UserInfo extends BaseModel implements UserDetails{
public boolean isEnabled() {
return userStatus.equals("USC003");
}
@Override
public String toString() {
return "UserInfo [userSeq=" + userSeq + ", userId=" + userId + ", password=" + password + ", userNm=" + userNm
+ ", ogCd=" + ogCd + ", ofcCd=" + ofcCd + ", userRole=" + userRole + ", userStatus=" + userStatus
+ ", wrtDt=" + wrtDt + ", modifyPassword=" + modifyPassword + ", positionName=" + positionName
+ ", departmentName=" + departmentName + ", accessConfigList=" + accessConfigList + ", approvalConfigList="
+ approvalConfigList + "]";
}
}

View File

@ -9,4 +9,6 @@ import java.util.Optional;
public interface UserInfoRepository extends JpaRepository<UserInfo, Integer> {
Optional<UserInfo> findByUserId(String userId);
UserInfo findByUserSeq(Integer userSeq);
}

View File

@ -15,7 +15,15 @@
ofc_cd,
wrt_dt
from user_info
where user_status != 'D'
where
<choose>
<when test="userStatus != null and userStatus != ''">
user_status = #{userStatus}
</when>
<otherwise>
user_status != 'D'
</otherwise>
</choose>
<if test="userId != null and userId != ''">
and user_id like '%'||#{userId}||'%'
</if>

View File

@ -0,0 +1,59 @@
$(document).on('click', '.userInfoTr', function (){
if($('#userStatus').val() == 'USC003'){
$.ajax({
url: '/userMgt/userEditModal',
data: {userSeq: Number($(this).find(".userSeq").val())},
type: 'GET',
dataType:"html",
success: function(html){
$("#configInfo").empty().append(html)
$("#userEditModal").modal('show');
},
error:function(){
}
});
}
})
$(document).on('click', '#logTab', function (){
location.href='/userMgt/userMgtPage?userStatus=USC002'; 
})
$(document).on('click', '#contentTab', function (){
location.href='/userMgt/userMgtPage?userStatus=USC003';
})
$(document).ready( function() {
$('#chk-all').click( function() {
$('.userInfoCheckBox').prop('checked',this.checked);
});
});
$(document).on('click', '#approvalBtn', function (){
alert("승인")
var checkArr = [];
$('input:checkbox[name=userChk]:checked').each(function (idx, el){
checkArr.push({});
const target = $(el);
checkArr[idx].userSeq = Number(target.parents('tr').find('.userSeq').val());
checkArr[idx].userStatus = "USC003"
})
console.log('@@->'+checkArr);
$.ajax({
type : 'POST',
url : "/userMgt/userApproval",
data : JSON.stringify(checkArr),
contentType: 'application/json',
beforeSend: function (xhr){
xhr.setRequestHeader($("[name='_csrf_header']").val(), $("[name='_csrf']").val());
},
success : function(data) {
},
error : function(xhr, status) {
}
})
})

View File

@ -0,0 +1,100 @@
<!DOCTYPE html>
<html lang="ko" xmlns:th="http://www.thymeleaf.org">
<div class="tab-pane fade show active" id="accessTabPanel" role="tabpanel" aria-labelledby="accessTab" tabindex="0">
<form id="userInfoInsert" action="#" th:action="@{/admin/insertUserInfo}" method="post">
<div class="mb-3 row">
<div class="mb-3 mt-3 row">
<label for="userId" class="col-sm-2 col-form-label text-center ">아이디</label>
<div class="col-sm-4">
<input type="text" class="form-control" id="userId" name="userId" th:value="${userInfo.userId}" autocomplete="off">
<label for="userId" style="font-size: 12px">6~20자 사이의 알파벳, 숫자를 입력하세요</label>
</div>
<label for="userNm" class="col-sm-2 col-form-label text-center">이름</label>
<div class="col-sm-4">
<input type="text" class=" form-control" id="userNm" name="userNm" th:value="${userInfo.userNm}" autocomplete="off">
</div>
</div>
<div class="mb-3 row">
<label for="modalPassword" class="col-sm-2 col-form-label text-center">비밀번호 변경</label>
<div class="col-sm-4">
<input type="password" class="form-control" id="modalPassword" name="password" >
<label for="userId" style="font-size: 12px">8~16자 사이의 알파벳, 숫자, 특수문자 조합</label>
</div>
<label for="passwordConfirm" class="col-sm-2 col-form-label text-center">비밀번호 확인</label>
<div class="col-sm-4">
<input type="password" class="form-control" id="passwordConfirm">
</div>
</div>
<div class="mb-3 row">
<label for="tel" class="col-sm-2 col-form-label text-center">전화번호</label>
<div class="col-sm-4">
<input type="tel" class="form-control" id="tel">
</div>
<label for="email" class="col-sm-2 col-form-label text-center">이메일</label>
<div class="col-sm-4">
<input type="email" class="form-control" id="email">
</div>
</div>
<div class="mb-3 row">
<label for="telP" class="col-sm-2 col-form-label text-center">휴대전화</label>
<div class="col-sm-4">
<input type="tel" class="form-control" id="telP">
</div>
</div>
<div class="mb-3 row">
<label for="ogCd" class="col-sm-2 col-form-label text-center">관서</label>
<div class="col-sm-4">
<select class="form-control" id="ogCd" name="ogCd">
<option value="">--선택--</option>
<option th:each="val : ${OgList}" th:value="${val?.itemCd}" th:utext="${val?.itemValue}" th:selected="${val?.itemCd} == ${userInfo.ogCd}">
</option>
</select>
</div>
<label for="ofcCd" class="col-sm-2 col-form-label text-center">부서</label>
<div class="col-sm-4">
<select class="form-control" id="ofcCd" name="ofcCd">
<option value="">--선택--</option>
<option th:each="val : ${OfcList}" th:value="${val?.itemCd}" th:utext="${val?.itemValue}" th:selected="${val?.itemCd} == ${userInfo.ofcCd}">
</option>
</select>
</div>
</div>
<div class="mb-3 row" >
<label for="address" class="col-sm-2 col-form-label text-center">주소</label>
<div class="col-sm-8">
<input type="adress" class="form-control" id="address">
</div>
<div class="col-sm-2">
<button type="button" class="btn btn-secondary" id="search">주소검색</button>
</div>
</div>
<div class="mb-3 row">
<label for="addresses" class="col-sm-2 col-form-label text-center">상세주소</label>
<div class="col-sm-10">
<input type="address" class="form-control" id="addresses">
</div>
</div>
<div class="mb-3 row">
<label for="photo" class="col-sm-2 col-form-label text-center">사진</label>
<div class="col-sm-4">
<input type="file" style="font-size: 12px" class="form-control" id="photo">
</div>
<label for="sign" class="col-sm-2 col-form-label text-center">서명</label>
<div class="col-sm-4">
<input type="file" style="font-size: 12px" class="form-control" id="sign">
</div>
</div>
<div class="mb-3 row">
<label for="tel" class="col-sm-2 col-form-label text-center">요청사항</label>
<div class="col-sm-4">
<input type="text" class="form-control" id="need">
</div>
<label for="precautions" class="col-sm-2 col-form-label text-center">주의사항</label>
<div class="col-sm-4">
<input type="text" class="form-control" id="precautions">
</div>
</div>
</div>
</form>
</div>
</html>

View File

@ -0,0 +1,180 @@
<!DOCTYPE html>
<html lang="ko" xmlns:th="http://www.thymeleaf.org"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorate="~{layout/layout}">
<th:block layout:fragment="script">
<script type="text/javascript" th:src="@{/js/userMgt/userMgt.js}"></script>
</th:block>
<div layout:fragment="content">
<main class="pt-3">
<h4>외사경찰 관리</h4>
<th:block th:if="${searchParams.userStatus == 'USC003'}">
<ul class="nav nav-tabs" id="boardTab" role="tablist">
<li class="nav-item" role="presentation">
<button class="nav-link active" id="contentTab" data-bs-toggle="tab" data-bs-target="#contentDiv" type="button" role="tab">승인목록</button>
</li>
<li class="nav-item" role="presentation">
<button class="nav-link" id="logTab" data-bs-toggle="tab" data-bs-target="#logDiv" type="button" role="tab">승인대기</button>
</li>
</ul>
</th:block>
<th:block th:unless="${searchParams.userStatus == 'USC003'}">
<ul class="nav nav-tabs" id="boardTab" role="tablist">
<li class="nav-item" role="presentation">
<button class="nav-link" id="contentTab" data-bs-toggle="tab" data-bs-target="#contentDiv" type="button" role="tab">승인목록</button>
</li>
<li class="nav-item" role="presentation">
<button class="nav-link active" id="logTab" data-bs-toggle="tab" data-bs-target="#logDiv" type="button" role="tab">승인대기</button>
</li>
</ul>
</th:block>
<input type="hidden" name="_csrf_header" th:value="${_csrf.headerName}"/>
<input type="hidden" th:name="${_csrf.parameterName}" th:value="${_csrf.token}"/>
<div class="row mx-0">
<div class="col-12 card text-center">
<div class="card-body">
<form method="get" th:action="@{/userMgt/userMgtPage}">
<input type="hidden" name="userStatus" id="userStatus" th:value="${searchParams.userStatus}">
<input type="hidden" name="pageIndex" id="pageIndex" th:value="${searchParams.pageIndex}">
<div class="row justify-content-between pe-3 py-1">
<div class="col-auto">
<select class="form-select" name="rowCnt" id="rowCnt">
<th:block th:each="num : ${#numbers.sequence(1,5)}">
<option th:value="${num*10}" th:text="${num*10}" th:selected="${searchParams.rowCnt==num*10}"></option>
</th:block>
</select>
</div>
<div class="col-auto">
<div class="row justify-content-end">
<div class="col-auto">
<select class="form-select form-select-sm" name="ogCd">
<option value="">관서 선택</option>
<th:block th:each="commonCode:${session.commonCodeList}">
<th:block th:if="${commonCode.categoryCd=='OG'}">
<option th:value="${commonCode.itemCd}" th:text="${commonCode.itemValue}" th:selected="${searchParams.ogCd==commonCode.itemCd}"></option>
</th:block>
</th:block>
</select>
</div>
<div class="col-auto">
<select class="form-select form-select-sm" name="ofcCd">
<option value="">부서 선택</option>
<th:block th:each="commonCode:${session.commonCodeList}">
<th:block th:if="${commonCode.categoryCd=='OFC'}">
<option th:value="${commonCode.itemCd}" th:text="${commonCode.itemValue}" th:selected="${searchParams.ofcCd==commonCode.itemCd}"></option>
</th:block>
</th:block>
</select>
</div>
<div class="col-auto">
<input type="text" class="form-control form-control-sm" name="userNm" placeholder="사용자명" th:value="${searchParams.userNm}">
</div>
<div class="col-auto">
<input type="text" class="form-control form-control-sm" name="userId" placeholder="사용자 아이디" th:value="${searchParams.userId}">
</div>
<input type="submit" class="btn btn-sm btn-primary col-auto" id="searchBtn" value="검색">
</div>
</div>
</div>
</form>
<div class="row justify-content-start">
<div class="col-12">
<div class="card">
<div class="card-body">
<div class="row">
<table class="table table-striped">
<thead>
<tr>
<th> <input type="checkbox" id="chk-all" class="userInfoCheckBox"></th>
<th>소속</th>
<th>부서</th>
<th>계급</th>
<th>성명</th>
<th>아이디</th>
<th>등록일</th>
</tr>
</thead>
<tbody>
<tr class="userInfoTr" th:each="userInfo:${userInfoList}">
<input type="hidden" class="userSeq" th:value="${userInfo.userSeq}">
<td>
<input type="checkbox" id="userChk" name="userChk" class="userInfoCheckBox" th:value="${userInfo.userSeq}">
</td>
<th:block th:each="commonCode:${session.commonCodeList}">
<th:block th:if="${commonCode.itemCd == userInfo.ogCd}">
<td th:text="${commonCode.itemValue}"></td>
</th:block>
</th:block>
<th:block th:each="commonCode:${session.commonCodeList}">
<th:block th:if="${commonCode.itemCd == userInfo.ofcCd}">
<td th:text="${commonCode.itemValue}"></td>
</th:block>
</th:block>
<td></td>
<td th:text="${userInfo.userNm}"></td>
<td th:text="${userInfo.userId}"></td>
<td th:text="${#temporals.format(userInfo.wrtDt, 'yyyy-MM-dd HH:mm:ss')}"></td>
</tr>
</tbody>
</table>
</div>
<div class="col-auto">
<input type="button" class="btn btn-success" value="승인" id="approvalBtn">
</div>
<div class="row justify-content-center">
<div class="col-auto">
<nav aria-label="Page navigation">
<ul class="pagination">
<th:block th:if="${searchParams.pageIndex>3}">
<li class="page-item" th:data-pageindex="${(searchParams.pageIndex)-3}">
<a class="page-link" href="#" aria-label="Previous">
<span aria-hidden="true">&laquo;</span>
</a>
</li>
</th:block>
<th:block th:each="num : ${#numbers.sequence(searchParams.startNum, searchParams.endNum)}">
<li class="page-item" th:data-pageindex="${num}" th:classappend="${searchParams.pageIndex==num?'active':''}">
<a class="page-link" href="#" th:text="${num}"></a>
</li>
</th:block>
<th:block th:if="${searchParams.maxNum>searchParams.endNum+2}">
<li class="page-item" th:data-pageindex="${(searchParams.pageIndex)+3}">
<a class="page-link" href="#" aria-label="Next">
<span aria-hidden="true">&raquo;</span>
</a>
</li>
</th:block>
</ul>
</nav>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</main>
<div class="modal fade" id="userEditModal" data-bs-backdrop="static" data-bs-keyboard="false" tabindex="-1" aria-labelledby="userEditModalLabel" aria-hidden="true">
<div class="modal-dialog modal-lg modal-dialog-scrollable">
<div class="modal-content" id="userEditModalContent">
<div class="modal-header">
<h5 class="modal-title" id="menuEditModalLabel">외사경찰 등록</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<div class="tab-content border border-top-0" id="configInfo">
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">닫기</button>
<button type="button" class="btn btn-primary" id="saveAuthBtn">저장</button>
</div>
</div>
</div>
</div>
</div>
</html>

View File

@ -13,7 +13,7 @@
<ul class="nav nav-pills" sec:authorize="hasRole('ROLE_ADMIN')">
<li class="nav-item"><a href="/codeMgt/codeMgtPage" class="nav-link p-1 link-dark">코드관리</a></li>
<li class="nav-item"><a href="/menuMgt/menuMgtPage" class="nav-link p-1 link-dark">메뉴관리</a></li>
<li class="nav-item"><a href="#" class="nav-link p-1 link-dark">외사경찰관리</a></li>
<li class="nav-item"><a href="/userMgt/userMgtPage" class="nav-link p-1 link-dark">외사경찰관리</a></li>
<li class="nav-item"><a href="/authMgt/authMgtPage" class="nav-link p-1 link-dark">권한설정</a></li>
<li class="nav-item"><a href="#" class="nav-link p-1 link-dark">사용자로그</a></li>
<li class="nav-item"><a href="#" class="nav-link p-1 link-dark">접속설정</a></li>