header, footer 로고 추가.
로그인 페이지 이미지 추가. 사용자관리 개인정보 열람, 수정 기능 추가. 게시판 분류 관리 페이지 작업 후 사용자관리 페이지 권한 설정 작업 이어서 해야함.master
|
|
@ -1,23 +1,31 @@
|
|||
package com.dbnt.kcgfilemanager;
|
||||
|
||||
import com.dbnt.kcgfilemanager.model.UserInfo;
|
||||
import com.dbnt.kcgfilemanager.service.CommonCodeService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
|
||||
import javax.servlet.http.HttpSession;
|
||||
import java.security.Principal;
|
||||
|
||||
@RestController
|
||||
@RequiredArgsConstructor
|
||||
public class BaseController {
|
||||
|
||||
private final CommonCodeService commonCodeService;
|
||||
|
||||
@GetMapping("/")
|
||||
public ModelAndView loginCheck(Principal principal) {
|
||||
public ModelAndView loginCheck(Principal principal, HttpSession session) {
|
||||
ModelAndView mav = null;
|
||||
if(principal == null){
|
||||
mav = new ModelAndView("redirect:/user/login");
|
||||
}else{
|
||||
session.setAttribute("positionList", commonCodeService.selectCommonCodeValue("POSITION"));
|
||||
session.setAttribute("departmentList", commonCodeService.selectCommonCodeValue("DEPARTMENT"));
|
||||
if(((UserInfo)((UsernamePasswordAuthenticationToken) principal).getPrincipal()).getUserRole().indexOf("ADMIN")>0){
|
||||
mav = new ModelAndView("redirect:/admin/main");
|
||||
}else{
|
||||
|
|
|
|||
|
|
@ -5,16 +5,10 @@ import com.dbnt.kcgfilemanager.model.UserInfo;
|
|||
import com.dbnt.kcgfilemanager.service.CommonCodeService;
|
||||
import com.dbnt.kcgfilemanager.service.UserInfoService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@RestController
|
||||
@RequiredArgsConstructor
|
||||
|
|
@ -35,8 +29,6 @@ public class adminController {
|
|||
userInfo.setQueryInfo();
|
||||
ModelAndView mav = new ModelAndView("admin/userMgt");
|
||||
mav.addObject("userInfoList", userInfoService.selectUserInfoList(userInfo));
|
||||
mav.addObject("positionList", commonCodeService.selectCommonCodeValue("POSITION"));
|
||||
mav.addObject("departmentList", commonCodeService.selectCommonCodeValue("DEPARTMENT"));
|
||||
userInfo.setContentCnt(userInfoService.selectUserInfoListCnt(userInfo));
|
||||
userInfo.setPaginationInfo();
|
||||
mav.addObject("searchParams", userInfo);
|
||||
|
|
@ -48,6 +40,17 @@ public class adminController {
|
|||
return userInfoService.insertUserInfo(userInfo);
|
||||
}
|
||||
|
||||
@PostMapping("/updateUserInfo")
|
||||
public String updateUserInfo(UserInfo userInfo){
|
||||
return userInfoService.updateUserInfo(userInfo);
|
||||
}
|
||||
|
||||
@GetMapping("/selectUserInfo")
|
||||
public ModelAndView selectUserInfo(UserInfo userInfo){
|
||||
ModelAndView mav = new ModelAndView("admin/userInfo");
|
||||
mav.addObject("userInfo", userInfoService.selectUserInfo(userInfo));
|
||||
return mav;
|
||||
}
|
||||
@GetMapping("/modifyRequest")
|
||||
public ModelAndView modifyRequest() {
|
||||
ModelAndView mav = new ModelAndView("admin/modifyRequest");
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ public class BaseModel {
|
|||
|
||||
int pageIndex = getPageIndex();
|
||||
int startNum = pageIndex - 2;
|
||||
if(startNum < 0){
|
||||
if(startNum <= 0){
|
||||
startNum = 1;
|
||||
}
|
||||
setStartNum(startNum);
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ package com.dbnt.kcgfilemanager.model;
|
|||
import lombok.*;
|
||||
import org.hibernate.annotations.DynamicInsert;
|
||||
import org.hibernate.annotations.DynamicUpdate;
|
||||
import org.springframework.data.annotation.CreatedDate;
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
||||
import org.springframework.security.core.userdetails.UserDetails;
|
||||
|
|
@ -38,7 +39,7 @@ public class UserInfo extends BaseModel implements UserDetails{
|
|||
private int department;
|
||||
@Column(name = "USER_ROLE")
|
||||
private String userRole;
|
||||
@Column(name = "CREATE_DATE")
|
||||
@Column(name = "CREATE_DATE", updatable = false)
|
||||
private LocalDateTime createDate;
|
||||
|
||||
@Transient
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import com.dbnt.kcgfilemanager.mapper.UserInfoMapper;
|
|||
import com.dbnt.kcgfilemanager.model.UserInfo;
|
||||
import com.dbnt.kcgfilemanager.repository.UserInfoRepository;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.security.core.userdetails.User;
|
||||
import org.springframework.security.core.userdetails.UserDetails;
|
||||
import org.springframework.security.core.userdetails.UserDetailsService;
|
||||
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
||||
|
|
@ -12,6 +13,7 @@ import org.springframework.stereotype.Service;
|
|||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
|
|
@ -22,11 +24,26 @@ public class UserInfoService implements UserDetailsService {
|
|||
|
||||
@Transactional
|
||||
public String insertUserInfo(UserInfo userInfo){
|
||||
Pbkdf2PasswordEncoder passwordEncoder = new Pbkdf2PasswordEncoder();
|
||||
userInfo.setPassword(passwordEncoder.encode(userInfo.getPassword()));
|
||||
|
||||
userInfo.setPassword(convertPassword(userInfo.getPassword()));
|
||||
return userInfoRepository.save(userInfo).getUserId();
|
||||
}
|
||||
@Transactional
|
||||
public String updateUserInfo(UserInfo userInfo){
|
||||
UserInfo targetUserInfo = userInfoRepository.findById(userInfo.getUserSeq()).orElse(null);
|
||||
if(userInfo.getPassword() != null){
|
||||
targetUserInfo.setPassword(convertPassword(userInfo.getPassword()));
|
||||
}
|
||||
targetUserInfo.setName(userInfo.getName());
|
||||
targetUserInfo.setPosition(userInfo.getPosition());
|
||||
targetUserInfo.setDepartment(userInfo.getDepartment());
|
||||
targetUserInfo.setUserRole(userInfo.getUserRole());
|
||||
return targetUserInfo.getUserId();
|
||||
}
|
||||
|
||||
private String convertPassword(String password){
|
||||
Pbkdf2PasswordEncoder passwordEncoder = new Pbkdf2PasswordEncoder();
|
||||
return passwordEncoder.encode(password);
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserDetails loadUserByUsername(String userId) throws UsernameNotFoundException {
|
||||
|
|
@ -40,4 +57,8 @@ public class UserInfoService implements UserDetailsService {
|
|||
public Integer selectUserInfoListCnt(UserInfo userInfo) {
|
||||
return userInfoMapper.selectUserInfoListCnt(userInfo);
|
||||
}
|
||||
|
||||
public UserInfo selectUserInfo(UserInfo userInfo) {
|
||||
return userInfoRepository.findById(userInfo.getUserSeq()).orElse(null);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@
|
|||
AND A.CREATE_DATE <= #{endDate}
|
||||
</if>
|
||||
</where>
|
||||
ORDER BY CREATE_DATE DESC
|
||||
LIMIT #{viewCnt} OFFSET #{firstIndex}
|
||||
</select>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
|
||||
#loginPage{
|
||||
background-image: url("/img/img01.jpg");
|
||||
}
|
||||
.form-signin{
|
||||
width: 100%;
|
||||
max-width: 330px;
|
||||
|
|
|
|||
|
After Width: | Height: | Size: 2.7 KiB |
|
After Width: | Height: | Size: 9.9 KiB |
|
After Width: | Height: | Size: 3.8 KiB |
|
After Width: | Height: | Size: 2.0 MiB |
|
After Width: | Height: | Size: 1.6 MiB |
|
After Width: | Height: | Size: 9.0 KiB |
|
After Width: | Height: | Size: 1013 KiB |
|
|
@ -104,8 +104,8 @@ function getValues(category){
|
|||
data: {category: category},
|
||||
type: 'GET',
|
||||
dataType:"html",
|
||||
success: function(data){
|
||||
$("#valueDiv").empty().append(data)
|
||||
success: function(html){
|
||||
$("#valueDiv").empty().append(html)
|
||||
},
|
||||
error:function(){
|
||||
|
||||
|
|
|
|||
|
|
@ -5,6 +5,24 @@ $(function(){
|
|||
language: "ko"
|
||||
});
|
||||
})
|
||||
$(document).on('click', '.userInfoTr', function (){
|
||||
$(".userInfoCheckBox").prop('checked', false);
|
||||
const target = $(this).find(".userInfoCheckBox")[0];
|
||||
target.checked = true;
|
||||
const selectedTab = $(".nav-tabs").find(".active")[0].id;
|
||||
if(selectedTab === "infoTab"){
|
||||
getUserInfo(target.value);
|
||||
}else if(selectedTab === "categoryTab"){
|
||||
getCategoryRole(target.value);
|
||||
}
|
||||
})
|
||||
|
||||
$(document).on('click', '#infoTab', function (){
|
||||
getUserInfo(getUserSeq())
|
||||
})
|
||||
$(document).on('click', '#categoryTab', function (){
|
||||
getCategoryRole(getUserSeq())
|
||||
})
|
||||
|
||||
$(document).on('click', '.page-item', function (){
|
||||
$("#pageIndex").val($(this).attr("data-pageindex"));
|
||||
|
|
@ -14,11 +32,20 @@ $(document).on('click', '.page-item', function (){
|
|||
$(document).on('change', '#searchConditionSelector', function (){
|
||||
setSearchCondition();
|
||||
})
|
||||
|
||||
$(document).on('change', '#passwordUpdateFlag', function (){
|
||||
const passwordDiv = $(".passwordDiv");
|
||||
if(this.checked){
|
||||
passwordDiv.show();
|
||||
passwordDiv.find("input").removeAttr("disabled");
|
||||
}else{
|
||||
passwordDiv.hide();
|
||||
passwordDiv.find("input").attr("disabled", "disabled");
|
||||
}
|
||||
})
|
||||
$(document).on('click', '#saveBtn', function (){
|
||||
if(valueCheck()){
|
||||
if(valueCheck("userInfoInsert")){
|
||||
if(confirm("저장하시겠습니까?")){
|
||||
const formData = new FormData($("#userInfoForm")[0]);
|
||||
const formData = new FormData($("#userInfoInsert")[0]);
|
||||
$.ajax({
|
||||
type : 'POST',
|
||||
data : formData,
|
||||
|
|
@ -38,30 +65,72 @@ $(document).on('click', '#saveBtn', function (){
|
|||
}
|
||||
})
|
||||
|
||||
function valueCheck(){
|
||||
const password = $("#password").val();
|
||||
const passwordConfirm = $("#passwordConfirm").val();
|
||||
$(document).on('click', '#updateBtn', function (){
|
||||
if(valueCheck("userInfoUpdate")){
|
||||
if(confirm("저장하시겠습니까?")){
|
||||
const formData = new FormData($("#userInfoUpdate")[0]);
|
||||
$.ajax({
|
||||
type : 'POST',
|
||||
data : formData,
|
||||
url : "/admin/updateUserInfo",
|
||||
processData: false,
|
||||
contentType: false,
|
||||
success : function(data) {
|
||||
alert("저장되었습니다.")
|
||||
$(".userInfoCheckBox:checked").click();
|
||||
},
|
||||
error : function(xhr, status) {
|
||||
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
function valueCheck(form){
|
||||
const targetForm = $("#"+form);
|
||||
const userId = targetForm.find("#userId").val();
|
||||
const password = targetForm.find("#password");
|
||||
const passwordConfirm = targetForm.find("#passwordConfirm");
|
||||
const name = targetForm.find("#name").val()
|
||||
let returnFlag = true;
|
||||
if(!$("#userId").val()){
|
||||
|
||||
if(!userId){
|
||||
alert("아이디를 입력해주세요.");
|
||||
returnFlag = false;
|
||||
}else{
|
||||
const idReg = /^[a-z]+[a-z0-9]{5,19}$/g;
|
||||
if(!idReg.test(userId)){
|
||||
returnFlag = false;
|
||||
alert("아이디 조건이 맞지 않습니다.")
|
||||
}
|
||||
}
|
||||
if(!password){
|
||||
if(!password[0].disabled && !password.val()){
|
||||
alert("비밀번호를 입력해주세요.");
|
||||
returnFlag = false;
|
||||
}
|
||||
if(!passwordConfirm){
|
||||
if(!password[0].disabled && !passwordConfirm.val()){
|
||||
alert("비밀번호 확인을 입력해주세요.");
|
||||
returnFlag = false;
|
||||
}
|
||||
if(returnFlag && password !== passwordConfirm){
|
||||
alert("비밀번호가 같지 않습니다.");
|
||||
returnFlag = false;
|
||||
}
|
||||
if(!$("#name").val()){
|
||||
if(!name){
|
||||
alert("이름 입력해주세요.");
|
||||
returnFlag = false;
|
||||
}
|
||||
if(returnFlag){
|
||||
const passwordReg = /^(?=.*[a-zA-z])(?=.*[0-9])(?=.*[$`~!@$!%*#^?&\\(\\)\-_=+]).{8,16}$/;
|
||||
if(!password[0].disabled){
|
||||
if(!passwordReg.test(password.val())){
|
||||
alert("비밀번호 조건이 맞지 않습니다.")
|
||||
returnFlag = false;
|
||||
}else{
|
||||
if(password.val() !== passwordConfirm.val()){
|
||||
alert("비밀번호가 같지 않습니다.");
|
||||
returnFlag = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return returnFlag;
|
||||
}
|
||||
|
||||
|
|
@ -83,5 +152,42 @@ function setSearchCondition(){
|
|||
}
|
||||
}
|
||||
function formReset(){
|
||||
document.getElementById('userInfoForm').reset();
|
||||
document.getElementById('userInfoInsert').reset();
|
||||
}
|
||||
|
||||
function getUserSeq(){
|
||||
return $(".userInfoCheckBox:checked").val();
|
||||
}
|
||||
|
||||
function getUserInfo(userSeq){
|
||||
if(userSeq !== undefined){
|
||||
$.ajax({
|
||||
url: '/admin/selectUserInfo',
|
||||
data: {userSeq: userSeq},
|
||||
type: 'GET',
|
||||
dataType:"html",
|
||||
success: function(html){
|
||||
$("#userContent").empty().append(html)
|
||||
},
|
||||
error:function(){
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
function getCategoryRole(userSeq){
|
||||
if(userSeq !== undefined){
|
||||
/*$.ajax({
|
||||
url: '/admin/codeValue',
|
||||
data: {category: category},
|
||||
type: 'GET',
|
||||
dataType:"html",
|
||||
success: function(data){
|
||||
$("#valueDiv").empty().append(data)
|
||||
},
|
||||
error:function(){
|
||||
|
||||
}
|
||||
});*/
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,70 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="ko" xmlns:th="http://www.thymeleaf.org">
|
||||
<form id="userInfoUpdate" class="row-cols-auto p-3" action="#" th:action="@{/admin/updateUserInfo}" method="post">
|
||||
<input type="hidden" name="userSeq" th:value="${userInfo.userSeq}">
|
||||
<div class="mb-3 row">
|
||||
<label for="userId" class="col-sm-4 col-form-label">아이디</label>
|
||||
<div class="col-sm-6">
|
||||
<input type="text" class="form-control" id="userId" name="userId" th:value="${userInfo.userId}" readonly>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-sm-4"></div>
|
||||
<div class="col-sm-auto form-check ms-3">
|
||||
<input class="form-check-input" type="checkbox" id="passwordUpdateFlag">
|
||||
<label class="form-check-label" for="passwordUpdateFlag">비밀번호 수정</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-3 row passwordDiv" style="display: none">
|
||||
<label for="password" class="col-sm-4 col-form-label">비밀번호</label>
|
||||
<div class="col-sm-6">
|
||||
<input type="password" class="form-control" id="password" name="password" disabled>
|
||||
</div>
|
||||
<div class="col-sm-auto form-text mx-auto">
|
||||
8~16자 사이의 알파벳, 숫자, 특수문자 조합을 입력해주세요.
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-3 row passwordDiv" style="display: none">
|
||||
<label for="passwordConfirm" class="col-sm-4 col-form-label">비밀번호 확인</label>
|
||||
<div class="col-sm-6">
|
||||
<input type="password" class="form-control" id="passwordConfirm" disabled>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-3 row">
|
||||
<label for="name" class="col-sm-4 col-form-label">이름</label>
|
||||
<div class="col-sm-6">
|
||||
<input type="text" class="form-control" id="name" name="name" autocomplete="off" th:value="${userInfo.name}">
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-3 row">
|
||||
<label for="department" class="col-sm-4 col-form-label">부서</label>
|
||||
<div class="col-sm-6">
|
||||
<select class="form-select" id="department" name="department">
|
||||
<th:block th:each="commonCode:${session.departmentList}">
|
||||
<option th:value="${commonCode.codeSq}" th:text="${commonCode.value}" th:selected="${commonCode.codeSq == userInfo.department}"></option>
|
||||
</th:block>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-3 row">
|
||||
<label for="position" class="col-sm-4 col-form-label">직급</label>
|
||||
<div class="col-sm-6">
|
||||
<select class="form-select" id="position" name="position">
|
||||
<th:block th:each="commonCode:${session.positionList}">
|
||||
<option th:value="${commonCode.codeSq}" th:text="${commonCode.value}" th:selected="${commonCode.codeSq==userInfo.position}"></option>
|
||||
</th:block>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-3 row">
|
||||
<div class="col-sm-4"></div>
|
||||
<div class="col-sm-auto form-check ms-3">
|
||||
<input type="hidden" name="userRole" value="ROLE_MEMBER">
|
||||
<input class="form-check-input" type="checkbox" value="ROLE_ADMIN" id="roleAdmin" name="userRole" th:checked="${#strings.contains(userInfo.userRole,'ADMIN')}">
|
||||
<label class="form-check-label" for="roleAdmin">관리자 계정</label>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
<div class="row-cols-6 gap-2 p-3">
|
||||
<input type="button" class="btn btn-warning w-50" id="updateBtn" value="수정하기">
|
||||
</div>
|
||||
|
|
@ -8,9 +8,7 @@
|
|||
<script type="text/javascript" th:src="@{/js/admin/userMgt.js}"></script>
|
||||
</th:block>
|
||||
<div layout:fragment="content">
|
||||
<main>
|
||||
<input type="hidden" name="_csrf_header" th:value="${_csrf.headerName}"/>
|
||||
<input type="hidden" th:name="${_csrf.parameterName}" th:value="${_csrf.token}"/>
|
||||
<main class="pt-3">
|
||||
<h4>사용자 관리</h4>
|
||||
<div class="row mx-0">
|
||||
<div class="col-12 card text-center">
|
||||
|
|
@ -83,7 +81,7 @@
|
|||
<input type="checkbox" class="userInfoCheckBox" th:value="${userInfo.userSeq}">
|
||||
</td>
|
||||
<td th:text="${userInfo.userId}"></td>
|
||||
<td th:text="${userInfo.name}"></td>
|
||||
<td th:text="|${userInfo.name}${#strings.contains(userInfo.userRole,'ADMIN')?'(관리자)':''}|"></td>
|
||||
<td th:text="${userInfo.positionName}"></td>
|
||||
<td th:text="${userInfo.departmentName}"></td>
|
||||
<td th:text="${#temporals.format(userInfo.createDate, 'yyyy-MM-dd')}"></td>
|
||||
|
|
@ -104,7 +102,7 @@
|
|||
</li>
|
||||
</th:block>
|
||||
<th:block th:each="num : ${#numbers.sequence(searchParams.startNum, searchParams.endNum)}">
|
||||
<li class="page-item" th:data-pageindex="${num}">
|
||||
<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>
|
||||
|
|
@ -132,8 +130,10 @@
|
|||
<button class="nav-link" id="categoryTab" data-bs-toggle="tab" type="button" role="tab">권한</button>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="tab-content" id="userContent">
|
||||
|
||||
<div class="tab-content border border-top-0" id="userContent">
|
||||
<div class="py-5">
|
||||
<h3>왼쪽 목록에서 선택해주세요.</h3>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -150,18 +150,24 @@
|
|||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<form id="userInfoForm" action="#" th:action="@{/admin/}" method="post">
|
||||
<form id="userInfoInsert" action="#" th:action="@{/admin/insertUserInfo}" method="post">
|
||||
<div class="mb-3 row">
|
||||
<label for="userId" class="col-sm-4 col-form-label">아이디</label>
|
||||
<div class="col-sm-6">
|
||||
<input type="text" class="form-control" id="userId" name="userId" autocomplete="off">
|
||||
</div>
|
||||
<div class="col-sm-auto form-text mx-auto">
|
||||
6~20자 사이의 알파벳, 숫자를 입력해주세요.
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-3 row">
|
||||
<label for="password" class="col-sm-4 col-form-label">비밀번호</label>
|
||||
<div class="col-sm-6">
|
||||
<input type="password" class="form-control" id="password" name="password">
|
||||
</div>
|
||||
<div class="col-sm-auto form-text mx-auto">
|
||||
8~16자 사이의 알파벳, 숫자 조합을 입력해주세요.
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-3 row">
|
||||
<label for="passwordConfirm" class="col-sm-4 col-form-label">비밀번호 확인</label>
|
||||
|
|
@ -179,7 +185,7 @@
|
|||
<label for="department" class="col-sm-4 col-form-label">부서</label>
|
||||
<div class="col-sm-6">
|
||||
<select class="form-select" id="department" name="department">
|
||||
<th:block th:each="commonCode:${departmentList}">
|
||||
<th:block th:each="commonCode:${session.departmentList}">
|
||||
<option th:value="${commonCode.codeSq}" th:text="${commonCode.value}"></option>
|
||||
</th:block>
|
||||
</select>
|
||||
|
|
@ -189,12 +195,20 @@
|
|||
<label for="position" class="col-sm-4 col-form-label">직급</label>
|
||||
<div class="col-sm-6">
|
||||
<select class="form-select" id="position" name="position">
|
||||
<th:block th:each="commonCode:${positionList}">
|
||||
<th:block th:each="commonCode:${session.positionList}">
|
||||
<option th:value="${commonCode.codeSq}" th:text="${commonCode.value}"></option>
|
||||
</th:block>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-3 row">
|
||||
<div class="col-sm-4"></div>
|
||||
<div class="col-sm-auto form-check ms-3">
|
||||
<input type="hidden" name="userRole" value="ROLE_MEMBER">
|
||||
<input class="form-check-input" type="checkbox" value="ROLE_ADMIN" id="roleAdmin" name="userRole">
|
||||
<label class="form-check-label" for="roleAdmin">관리자 계정</label>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
|
|
|
|||
|
|
@ -2,15 +2,19 @@
|
|||
<html lang="ko"
|
||||
xmlns:th="http://www.thymeleaf.org"
|
||||
xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity5">
|
||||
<footer th:fragment="footerFragment" class="d-flex flex-wrap justify-content-between align-items-center py-3 mt-auto border-top">
|
||||
<ul class="col-md-8 d-flex align-items-center list-unstyled d-flex">
|
||||
<li class="ms-3"><span class="text-muted">21995 인천광역시 연수구 해돋이로 130 해양경찰청</span></li>
|
||||
<li class="ms-3"><span class="text-muted">COPYRIGHT(C)2021 MINISTRY OF REPUBLIC ADMINISTRATION AND SECURITY. ALL RIGHT RESERVED</span></li>
|
||||
</ul>
|
||||
<ul class="nav col-md-4 justify-content-end list-unstyled d-flex">
|
||||
<!--<li class="ms-3"><a class="text-muted" href="#"><svg class="bi" width="24" height="24"><use xlink:href="#twitter"></use></svg></a></li>
|
||||
<li class="ms-3"><a class="text-muted" href="#"><svg class="bi" width="24" height="24"><use xlink:href="#instagram"></use></svg></a></li>
|
||||
<li class="ms-3"><a class="text-muted" href="#"><svg class="bi" width="24" height="24"><use xlink:href="#facebook"></use></svg></a></li>-->
|
||||
</ul>
|
||||
<footer th:fragment="footerFragment" class="d-flex flex-wrap py-2 mt-auto border-top bg-dark">
|
||||
<div class="row">
|
||||
<div class="col-auto">
|
||||
<img th:src="@{/img/f_logo.png}" alt="logo" title="logo" style="height: 50px;"/>
|
||||
</div>
|
||||
<div class="col-auto row">
|
||||
<div class="col-12">
|
||||
<span class="text-muted">21995 인천광역시 연수구 해돋이로 130 해양경찰청</span>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<span class="text-muted">COPYRIGHT(C)2021 MINISTRY OF REPUBLIC ADMINISTRATION AND SECURITY. ALL RIGHT RESERVED</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
</html>
|
||||
|
|
@ -2,11 +2,11 @@
|
|||
<html lang="ko"
|
||||
xmlns:th="http://www.thymeleaf.org"
|
||||
xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity5">
|
||||
<header th:fragment="headerFragment" class="d-flex flex-wrap justify-content-center py-3 px-3 mb-4 border-bottom">
|
||||
<header th:fragment="headerFragment" class="d-flex flex-wrap justify-content-center py-1 px-3 border-bottom">
|
||||
<a href="/" class="d-flex align-items-center mb-3 mb-md-0 me-md-auto text-dark text-decoration-none">
|
||||
<span class="fs-4">해양경찰청 파일관리 시스템</span>
|
||||
<img th:src="@{/img/logo.png}" alt="logo" title="logo">
|
||||
<!--<span class="fs-4">해양경찰청 파일관리 시스템</span>-->
|
||||
</a>
|
||||
|
||||
<ul class="nav nav-pills" sec:authorize="isAuthenticated()">
|
||||
<li class="nav-item"><a href="#" class="nav-link">개인정보</a></li>
|
||||
<li class="nav-item"><a href="/logout" class="nav-link">로그아웃</a></li>
|
||||
|
|
|
|||
|
|
@ -2,10 +2,10 @@
|
|||
<html lang="ko"
|
||||
xmlns:th="http://www.thymeleaf.org"
|
||||
xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity5">
|
||||
<div class="mx-2" th:fragment="leftMenuFragment">
|
||||
<div class="mx-2 pt-3" th:fragment="leftMenuFragment">
|
||||
<div sec:authorize="hasRole('ROLE_ADMIN')">
|
||||
<div class="list-group py-2">
|
||||
<a href="#" class="list-group-item list-group-item-action disabled">게시판 분류 관리</a>
|
||||
<a href="/admin/categoryMgt" class="list-group-item list-group-item-action">게시판 분류 관리</a>
|
||||
<a href="/admin/userMgt" class="list-group-item list-group-item-action">사용자 관리</a>
|
||||
<a href="/admin/modifyRequest" class="list-group-item list-group-item-action">수정 요청</a>
|
||||
<a href="#" class="list-group-item list-group-item-action disabled">통계</a>
|
||||
|
|
|
|||
|
|
@ -4,8 +4,8 @@
|
|||
xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity5"
|
||||
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
|
||||
layout:decorate="~{layout/layout}">
|
||||
<div layout:fragment="content" class="form-signin text-center">
|
||||
<main>
|
||||
<div layout:fragment="content" class="h-100" id="loginPage">
|
||||
<div class="form-signin text-center mt-5 rounded bg-white">
|
||||
<!-- Security config의 loginPage("url")와 action url과 동일하게 작성-->
|
||||
<form action="/user/login" method="post">
|
||||
<!-- Spring Security가 적용되면 POST 방식으로 보내는 모든 데이터는 csrf 토큰 값이 필요 -->
|
||||
|
|
@ -16,7 +16,7 @@
|
|||
<!-- 파라미터명을 변경하고 싶을 경우 config class formlogin()에서 .usernameParameter("") 명시 -->
|
||||
|
||||
<!--<img class="mb-4" th:src="@{/img/}" alt="" width="72" height="57">-->
|
||||
<h1 class="h3 mb-3 fw-normal">Please sign in</h1>
|
||||
<h1 class="h3 mb-3 fw-normal">로그인</h1>
|
||||
<div class="form-floating">
|
||||
<input type="text" class="form-control" id="username" name="username" placeholder="아이디">
|
||||
<label for="username">아이디</label>
|
||||
|
|
@ -32,6 +32,6 @@
|
|||
</div>
|
||||
<button class="w-100 btn btn-lg btn-primary" type="submit">로그인</button>
|
||||
</form>
|
||||
</main>
|
||||
</div>
|
||||
</div>
|
||||
</html>
|
||||