관리자 관리 CRUD Sample 추가

This commit is contained in:
geonhos 2024-05-10 09:48:21 +09:00
parent e3c4fa132f
commit 2edb4c831f
25 changed files with 720 additions and 59 deletions

View File

@ -16,7 +16,10 @@ repositories {
}
dependencies {
// spring
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-validation'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
// thymeleaf
@ -24,8 +27,11 @@ dependencies {
implementation 'org.thymeleaf.extras:thymeleaf-extras-springsecurity6'
implementation 'nz.net.ultraq.thymeleaf:thymeleaf-layout-dialect:3.3.0'
// jpa
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
//querydsl
implementation "com.querydsl:querydsl-jpa:${dependencyManagement.importedProperties['querydsl.version']}:jakarta"
annotationProcessor "com.querydsl:querydsl-apt:${dependencyManagement.importedProperties['querydsl.version']}:jakarta"
annotationProcessor "jakarta.persistence:jakarta.persistence-api"
annotationProcessor "jakarta.annotation:jakarta.annotation-api"
// security
implementation 'org.springframework.boot:spring-boot-starter-security'

View File

@ -1,9 +1,10 @@
package com.bpgroup.poc.admin.app.login;
import com.bpgroup.poc.admin.app.login.exception.AdministratorNotFoundException;
import com.bpgroup.poc.admin.app.login.exception.DoNotHaveAnyMenuException;
import com.bpgroup.poc.admin.app.login.exception.InvalidPasswordException;
import com.bpgroup.poc.admin.domain.admin.Administrator;
import com.bpgroup.poc.admin.domain.admin.AdministratorRepository;
import com.bpgroup.poc.admin.domain.admin.entity.Administrator;
import com.bpgroup.poc.admin.domain.admin.entity.AdministratorRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
@ -22,7 +23,7 @@ public class LoginService {
private final AdministratorRepository loginRepository;
private final PasswordEncoder passwordEncoder;
public LoginResult login(String loginId, String pwd) throws AdministratorNotFoundException, InvalidPasswordException {
public LoginResult login(String loginId, String pwd) throws AdministratorNotFoundException, InvalidPasswordException, DoNotHaveAnyMenuException {
Optional<Administrator> administrator = loginRepository.findByLoginId(loginId);
if (administrator.isEmpty()) {
@ -42,7 +43,8 @@ public class LoginService {
);
}
private static LinkedHashSet<LoginResult.MenuInfo> getMenus(Administrator administrator) {
private static LinkedHashSet<LoginResult.MenuInfo> getMenus(Administrator administrator) throws DoNotHaveAnyMenuException {
try {
return administrator.getAdministratorRole().getRole().getRoleMenus().stream()
.map(roleMenu -> LoginResult.MenuInfo.of(
roleMenu.getMenu().getMenuGroup().getUri(),
@ -58,6 +60,9 @@ public class LoginService {
.thenComparingInt(LoginResult.MenuInfo::getMenuSortOrder)
)
.collect(Collectors.toCollection(LinkedHashSet::new));
} catch (NullPointerException e) {
throw new DoNotHaveAnyMenuException();
}
}
}

View File

@ -0,0 +1,7 @@
package com.bpgroup.poc.admin.app.login.exception;
public class DoNotHaveAnyMenuException extends Exception {
public DoNotHaveAnyMenuException() {
super();
}
}

View File

@ -0,0 +1,19 @@
package com.bpgroup.poc.admin.config;
import com.querydsl.jpa.impl.JPAQueryFactory;
import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class QuerydslConfig {
@PersistenceContext
private EntityManager entityManager;
@Bean
public JPAQueryFactory jpaQueryFactory() {
return new JPAQueryFactory(entityManager);
}
}

View File

@ -0,0 +1,7 @@
package com.bpgroup.poc.admin.domain;
public class DomainException extends RuntimeException {
public DomainException() {
super();
}
}

View File

@ -39,4 +39,10 @@ public class Administrator extends BaseEntity {
return administrator;
}
public void update(Administrator administrator) {
this.password = administrator.password;
this.email = administrator.email;
this.name = administrator.name;
}
}

View File

@ -0,0 +1,42 @@
package com.bpgroup.poc.admin.domain.admin.service;
import com.bpgroup.poc.admin.domain.admin.entity.Administrator;
import jakarta.validation.constraints.NotBlank;
import lombok.Getter;
import lombok.ToString;
@Getter
@ToString
public class AdministratorCreateCommand {
@NotBlank
private String loginId;
@NotBlank
private String password;
@NotBlank
private String email;
@NotBlank
private String name;
public static AdministratorCreateCommand of(String loginId, String password, String email, String name) {
AdministratorCreateCommand command = new AdministratorCreateCommand();
command.loginId = loginId;
command.password = password;
command.email = email;
command.name = name;
return command;
}
public Administrator toEntity() {
return Administrator.builder()
.loginId(loginId)
.password(password)
.email(email)
.name(name)
.build();
}
}

View File

@ -0,0 +1,51 @@
package com.bpgroup.poc.admin.domain.admin.service;
import com.bpgroup.poc.admin.domain.admin.entity.Administrator;
import com.bpgroup.poc.admin.domain.admin.entity.AdministratorRepository;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotNull;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import java.util.Optional;
@Service
@RequiredArgsConstructor
@Validated
@Transactional
public class AdministratorService {
private final AdministratorRepository administratorRepository;
public Long create(
@NotNull @Valid AdministratorCreateCommand command
) {
// 대소문자 구별이 필요한 경우 인증 부분과 유효성 검사 부분 모두 변경이 필요하다.
Optional<Administrator> administrator = administratorRepository.findByLoginId(command.getLoginId());
if (administrator.isPresent()) {
throw new DuplicationAdministratorException(command.getLoginId());
}
Administrator createAdministrator = administratorRepository.save(command.toEntity());
return createAdministrator.getId();
}
public void update(
@NotNull @Valid AdministratorUpdateCommand command
) {
Optional<Administrator> administrator = administratorRepository.findById(command.getId());
if (administrator.isEmpty()) {
throw new NotFoundAdministratorException();
}
administrator.get().update(command.toEntity());
}
public void delete(
@NotNull Long id
) {
administratorRepository.deleteById(id);
}
}

View File

@ -0,0 +1,42 @@
package com.bpgroup.poc.admin.domain.admin.service;
import com.bpgroup.poc.admin.domain.admin.entity.Administrator;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.Getter;
import lombok.ToString;
@Getter
@ToString
public class AdministratorUpdateCommand {
@NotNull
private Long id;
@NotBlank
private String password;
@NotBlank
private String email;
@NotBlank
private String name;
public static AdministratorUpdateCommand of(Long id, String password, String email, String name) {
AdministratorUpdateCommand command = new AdministratorUpdateCommand();
command.id = id;
command.password = password;
command.email = email;
command.name = name;
return command;
}
public Administrator toEntity() {
return Administrator.builder()
.password(password)
.email(email)
.name(name)
.build();
}
}

View File

@ -0,0 +1,7 @@
package com.bpgroup.poc.admin.domain.admin.service;
public class DuplicationAdministratorException extends RuntimeException {
public DuplicationAdministratorException(String loginId) {
super("이미 존재하는 아이디 입니다. : " + loginId);
}
}

View File

@ -0,0 +1,9 @@
package com.bpgroup.poc.admin.domain.admin.service;
import com.bpgroup.poc.admin.domain.DomainException;
public class NotFoundAdministratorException extends DomainException {
public NotFoundAdministratorException() {
super();
}
}

View File

@ -37,12 +37,11 @@ public class SecurityConfig {
}).addFilterAfter(new CsrfCookieFilter(), BasicAuthenticationFilter.class); // 로그인이 완료된 CSRF Filter 실행
// 인증 설정
http.authorizeHttpRequests(c -> {
c.requestMatchers("/css/**", "/images/**", "/js/**").permitAll()
http.authorizeHttpRequests(c -> c
.requestMatchers("/css/**", "/images/**", "/js/**").permitAll()
.requestMatchers("/common/modal/**").permitAll()
.requestMatchers(LOGIN_PATH, LOGOUT_PATH, ERROR_PATH).permitAll()
.anyRequest().authenticated();
});
.anyRequest().authenticated());
http.formLogin(c -> c
.loginPage(LOGIN_PATH)

View File

@ -1,6 +1,7 @@
package com.bpgroup.poc.admin.security.authentication;
import com.bpgroup.poc.admin.app.login.exception.AdministratorNotFoundException;
import com.bpgroup.poc.admin.app.login.exception.DoNotHaveAnyMenuException;
import com.bpgroup.poc.admin.app.login.exception.InvalidPasswordException;
import lombok.extern.slf4j.Slf4j;
@ -8,11 +9,14 @@ import lombok.extern.slf4j.Slf4j;
public enum AuthenticationFailReason {
WRONG_LOGIN_ID,
WRONG_PASSWORD,
HAVE_NO_MENU,
INTERNAL_ERROR;
public static AuthenticationFailReason from(Exception e) {
if (e instanceof AdministratorNotFoundException || e instanceof InvalidPasswordException) {
return WRONG_LOGIN_ID;
} else if (e instanceof DoNotHaveAnyMenuException) {
return HAVE_NO_MENU;
} else {
return INTERNAL_ERROR;
}

View File

@ -0,0 +1,8 @@
package com.bpgroup.poc.admin.web.common;
public class CommonResponse {
protected String resultCode;
protected String resultMessage;
}

View File

@ -26,7 +26,8 @@ public class LoginController {
private String getMessage(AuthenticationFailReason error) {
return switch (error) {
case WRONG_LOGIN_ID, WRONG_PASSWORD -> "아이디 또는 비밀번호가 일치하지 않습니다.";
case INTERNAL_ERROR -> "서버에 오류가 발생했습니다.";
case HAVE_NO_MENU -> "등록된 메뉴가 없습니다.\n 메뉴 등록 후 이용해주세요.";
default -> "서버에 오류가 발생했습니다.";
};
}

View File

@ -0,0 +1,40 @@
package com.bpgroup.poc.admin.web.main.admin.management;
import com.bpgroup.poc.admin.web.main.admin.management.reqres.AdministratorFind;
import com.querydsl.core.types.Projections;
import com.querydsl.jpa.impl.JPAQueryFactory;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Repository;
import java.util.List;
import static com.bpgroup.poc.admin.domain.admin.entity.QAdministrator.administrator;
@Repository
@RequiredArgsConstructor
public class AdministratorManagementQueryRepository {
private final JPAQueryFactory queryFactory;
public List<AdministratorFind.Response> findAll() {
return queryFactory.select(Projections.fields(AdministratorFind.Response.class,
administrator.id,
administrator.loginId,
administrator.email,
administrator.name))
.from(administrator)
.fetch();
}
public AdministratorFind.Response findByLoginId(String loginId) {
return queryFactory.select(Projections.fields(AdministratorFind.Response.class,
administrator.id,
administrator.loginId,
administrator.email,
administrator.name))
.from(administrator)
.where(administrator.loginId.eq(loginId))
.fetchOne();
}
}

View File

@ -0,0 +1,83 @@
package com.bpgroup.poc.admin.web.main.admin.management;
import com.bpgroup.poc.admin.web.main.admin.management.reqres.AdministratorCreate;
import com.bpgroup.poc.admin.web.main.admin.management.reqres.AdministratorDelete;
import com.bpgroup.poc.admin.web.main.admin.management.reqres.AdministratorFind;
import com.bpgroup.poc.admin.web.main.admin.management.reqres.AdministratorUpdate;
import jakarta.validation.constraints.NotBlank;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequiredArgsConstructor
@RequestMapping("/admin/management")
public class AdministratorManagementRestController {
private final AdministratorManagementWebService administratorManagementWebService;
/**
* 전체 조회
* @return 응답
*/
@GetMapping("/list")
public ResponseEntity<?> getAdministrators() {
List<AdministratorFind.Response> response = administratorManagementWebService.findAll();
return ResponseEntity.ok(response);
}
/**
* 조회
* @param loginId 관리자 ID
* @return 응답
*/
@GetMapping("/{loginId}")
public ResponseEntity<?> getAdministrator(@PathVariable @NotBlank String loginId) {
AdministratorFind.Response response = administratorManagementWebService.find(loginId);
return ResponseEntity.ok(response);
}
/**
* 관리자 등록
* @param request 요청
* @param bindingResult Validation 결과
* @return 응답
*/
@PostMapping("/create")
public ResponseEntity<?> createAdministrator(
@RequestBody @Validated AdministratorCreate.Request request,
BindingResult bindingResult
) {
AdministratorCreate.Response response = administratorManagementWebService.create(request);
return ResponseEntity.ok(response);
}
@PostMapping("/update")
public ResponseEntity<?> updateAdministrator(
@RequestBody @Validated AdministratorUpdate.Request request,
BindingResult bindingResult
) {
administratorManagementWebService.update(request);
return ResponseEntity.ok().build();
}
/**
* 관리자 삭제
* @param request 요청
* @param bindingResult Validation 결과
* @return 응답
*/
@PostMapping("/delete")
public ResponseEntity<?> deleteAdministrator(
@RequestBody @Validated AdministratorDelete.Request request,
BindingResult bindingResult
) {
administratorManagementWebService.delete(request);
return ResponseEntity.ok().build();
}
}

View File

@ -0,0 +1,61 @@
package com.bpgroup.poc.admin.web.main.admin.management;
import com.bpgroup.poc.admin.domain.admin.service.AdministratorCreateCommand;
import com.bpgroup.poc.admin.domain.admin.service.AdministratorService;
import com.bpgroup.poc.admin.domain.admin.service.AdministratorUpdateCommand;
import com.bpgroup.poc.admin.web.main.admin.management.reqres.AdministratorCreate;
import com.bpgroup.poc.admin.web.main.admin.management.reqres.AdministratorDelete;
import com.bpgroup.poc.admin.web.main.admin.management.reqres.AdministratorFind;
import com.bpgroup.poc.admin.web.main.admin.management.reqres.AdministratorUpdate;
import jakarta.validation.constraints.NotBlank;
import lombok.RequiredArgsConstructor;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
@Service
@RequiredArgsConstructor
@Transactional
public class AdministratorManagementWebService {
private final PasswordEncoder passwordEncoder;
private final AdministratorService administratorService;
private final AdministratorManagementQueryRepository administratorManagementQueryRepository;
public AdministratorCreate.Response create(AdministratorCreate.Request request) {
Long id = administratorService.create(AdministratorCreateCommand.of(
request.getLoginId(),
passwordEncoder.encode(request.getPassword()),
request.getEmail(),
request.getName()
));
return AdministratorCreate.Response.builder()
.id(id)
.build();
}
public AdministratorFind.Response find(@NotBlank String loginId) {
return administratorManagementQueryRepository.findByLoginId(loginId);
}
public void delete(AdministratorDelete.Request request) {
administratorService.delete(request.getId());
}
public void update(AdministratorUpdate.Request request) {
administratorService.update(AdministratorUpdateCommand.of(
request.getId(),
passwordEncoder.encode(request.getPassword()),
request.getEmail(),
request.getName()
));
}
public List<AdministratorFind.Response> findAll() {
return administratorManagementQueryRepository.findAll();
}
}

View File

@ -0,0 +1,51 @@
package com.bpgroup.poc.admin.web.main.admin.management.reqres;
import com.bpgroup.poc.admin.web.common.CommonResponse;
import jakarta.validation.constraints.NotBlank;
import lombok.Builder;
import lombok.Data;
import lombok.Getter;
import lombok.ToString;
public class AdministratorCreate {
@Data
public static class Request {
@NotBlank
private String loginId;
@NotBlank
private String password;
@NotBlank
private String email;
@NotBlank
private String name;
}
@Getter
@ToString
public static class Response extends CommonResponse {
private Long id;
@Builder
public static Response success(Long id) {
Response response = new Response();
response.resultCode = "0000";
response.resultMessage = "Success";
response.id = id;
return response;
}
@Builder
public static Response fail() {
Response response = new Response();
response.resultCode = "9999";
response.resultMessage = "Fail";
return response;
}
}
}

View File

@ -0,0 +1,14 @@
package com.bpgroup.poc.admin.web.main.admin.management.reqres;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
public class AdministratorDelete {
@Data
public static class Request {
@NotNull
private Long id;
}
}

View File

@ -0,0 +1,17 @@
package com.bpgroup.poc.admin.web.main.admin.management.reqres;
import lombok.Getter;
import lombok.ToString;
public class AdministratorFind {
@Getter
@ToString
public static class Response {
private Long id;
private String loginId;
private String email;
private String name;
}
}

View File

@ -0,0 +1,27 @@
package com.bpgroup.poc.admin.web.main.admin.management.reqres;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
public class AdministratorUpdate {
@Data
public static class Request {
@NotNull
private Long id;
@NotBlank
private String username;
@NotBlank
private String password;
@NotBlank
private String email;
@NotBlank
private String name;
}
}

View File

@ -17,39 +17,17 @@ VALUES ('/admin', '관리자 관리', 2, CURDATE(), CURDATE()),
INSERT INTO `menu` (`uri`, `name`, `sort_order`, `menu_group_id`, `create_date`, `update_date`)
VALUES ('/admin/management', '관리자 관리', 1, 1, CURDATE(), CURDATE()),
('/admin/role', '권한 관리', 2, 1, CURDATE(), CURDATE()),
('/admin/temp01', '관리자 임시 1', 4, 1, CURDATE(), CURDATE()),
('/admin/temp02', '관리자 임시 2', 3, 1, CURDATE(), CURDATE())
('/admin/role', '권한 관리', 2, 1, CURDATE(), CURDATE())
;
INSERT INTO `menu` (`uri`, `name`, `sort_order`, `menu_group_id`, `create_date`, `update_date`)
VALUES ('/temp/temp01', '임시 01', 4, 3, CURDATE(), CURDATE()),
('/temp/temp02', '임시 02', 2, 3, CURDATE(), CURDATE()),
('/temp/temp03', '임시 03', 1, 3, CURDATE(), CURDATE()),
('/temp/temp04', '임시 04', 3, 3, CURDATE(), CURDATE())
;
INSERT INTO `menu` (`uri`, `name`, `sort_order`, `menu_group_id`, `create_date`, `update_date`)
VALUES ('/settings/code', '코드 관리', 1, 2, CURDATE(), CURDATE()),
('/settings/component', '컴포넌트', 1, 2, CURDATE(), CURDATE()),
('/settings/temp01', '세팅 임시 1', 4, 2, CURDATE(), CURDATE()),
('/settings/temp02', '세팅 임시 2', 3, 2, CURDATE(), CURDATE())
VALUES ('/settings/code', '코드 관리', 1, 2, CURDATE(), CURDATE())
;
INSERT INTO `role_menu` (`role_id`, `menu_id`, `create_date`, `update_date`)
VALUES ('1', '1', CURDATE(), CURDATE()),
('1', '2', CURDATE(), CURDATE()),
('1', '3', CURDATE(), CURDATE()),
('1', '4', CURDATE(), CURDATE()),
('1', '5', CURDATE(), CURDATE()),
('1', '6', CURDATE(), CURDATE()),
('1', '7', CURDATE(), CURDATE()),
('1', '8', CURDATE(), CURDATE()),
('1', '9', CURDATE(), CURDATE()),
('1', '10', CURDATE(), CURDATE()),
('1', '11', CURDATE(), CURDATE()),
('1', '12', CURDATE(), CURDATE())
('1', '3', CURDATE(), CURDATE())
;

View File

@ -5,15 +5,31 @@
<meta name="_csrf_header" th:content="${_csrf.headerName}"/>
<meta name="_csrf" th:content="${_csrf.token}"/>
<script th:inline="javascript">
// 모든 AJAX 요청에 자동으로 CSRF 토큰이 포함
// CSRF 토큰
// fetch ajax 사용 시 헤더에 추가 필요
const csrfToken = $('meta[name="_csrf"]').attr('content');
const csrfHeader = $('meta[name="_csrf_header"]').attr('content');
$.ajaxSetup({
beforeSend: function (xhr) {
xhr.setRequestHeader(csrfHeader, csrfToken);
function fetchPost(requestUri, body) {
return fetch(requestUri, {
method: 'POST',
headers: {
[csrfHeader]: csrfToken,
'Content-Type': 'application/json',
},
body: JSON.stringify(body)
});
}
function fetchGet(requestUri) {
return fetch(requestUri, {
method: 'GET',
headers: {
[csrfHeader]: csrfToken,
'Content-Type': 'application/json',
}
});
}
</script>
</th:block>
</body>

View File

@ -4,10 +4,171 @@
layout:decorate="~{main/admin/management/root.html}">
<body>
<th:block layout:fragment="innerContents">
<div class="table_wrap mt-20">
<h4>관리자 등록</h4>
<div class="tb_wrapper">
<label for="iptCreateLoginId">아이디: </label><input type="text" id="iptCreateLoginId" name="loginId">
<label for="iptCreatePassword">비밀번호: </label><input type="password" id="iptCreatePassword" name="password">
<label for="iptCreateEmail">이메일: </label><input type="text" id="iptCreateEmail" name="email">
<label for="iptCreateNAme">이름: </label><input type="text" id="iptCreateNAme" name="name">
<button type="button" id="btnCreate" class="btn_confirm" data-bs-dismiss="modal">등록</button>
<button type="button" id="btnCheckDuplication" class="btn_confirm" data-bs-dismiss="modal">아이디 중복체크</button>
</div>
<h4>관리자 조회</h4>
<div class="tb_wrapper">
<label for="selAdministrator">관리자: </label>
<select id="selAdministrator" class="table_select_box">
<option value="">선택</option>
</select>
<button type="button" id="btnFindAll" class="btn_confirm" data-bs-dismiss="modal">조회</button>
</div>
<h4>관리자 수정</h4>
<div class="tb_wrapper">
<input type="hidden" id="iptUpdateId" name="id">
<label for="iptUpdateLoginId">아이디: </label><input type="text" id="iptUpdateLoginId" name="loginId" readonly>
<label for="iptUpdatePassword">비밀번호: </label ><input type="password" id="iptUpdatePassword" name="password">
<label for="iptUpdateEmail">이메일: </label><input type="text" id="iptUpdateEmail" name="email">
<label for="iptUpdateName">이름: </label><input type="text" id="iptUpdateName" name="name">
<button type="button" id="btnUpdate" class="btn_confirm" data-bs-dismiss="modal">수정</button>
</div>
<h4>관리자 삭제</h4>
<div class="tb_wrapper">
<input type="hidden" id="iptDeleteId" name="id">
<label for="iptUpdateLoginId">아이디: </label><input type="text" id="iptDeleteLoginId" name="loginId" readonly>
<button type="button" id="btnDelete" class="btn_confirm" data-bs-dismiss="modal">삭제</button>
</div>
</div>
</th:block>
<th:block layout:fragment="innerScript">
<script th:inline="javascript">
function clearInput() {
document.getElementById('iptCreateLoginId').value = '';
document.getElementById('iptCreatePassword').value = '';
document.getElementById('iptCreateEmail').value = '';
document.getElementById('iptCreateNAme').value = '';
document.getElementById('iptUpdateId').value = '';
document.getElementById('iptUpdateLoginId').value = '';
document.getElementById('iptUpdatePassword').value = '';
document.getElementById('iptUpdateEmail').value = '';
document.getElementById('iptUpdateName').value = '';
document.getElementById('iptDeleteId').value = '';
document.getElementById('iptDeleteLoginId').value = '';
document.getElementById('selAdministrator').innerHTML = '<option value="">선택</option>';
}
/**
* 아이디 중복 체크
*/
document.getElementById('btnCheckDuplication').addEventListener(('click'), function () {
const loginId = document.getElementById('iptCreateLoginId').value;
const requestUri = /*[[@{/admin/management}]]*/ '';
fetchGet(requestUri.concat('/', loginId))
.then(response => {
if (response.ok) {
return response.text().then(text => text ? JSON.parse(text) : null);
} else {
PageHelper.showErrorModal('데이터 조회에 실패했습니다.');
}
})
.then((data) => {
if (!data) {
PageHelper.showAlertModal({title: '아이디 중복', message: '사용 가능한 아이디입니다.'});
} else {
PageHelper.showAlertModal({title: '아이디 중복', message: '사용할 수 없는 아이디입니다.'});
}
});
});
/**
* 관리자 등록
*/
document.getElementById('btnCreate').addEventListener(('click'), function () {
const requestUri = /*[[@{/admin/management/create}]]*/ '';
fetchPost(requestUri, {
loginId: document.getElementById('iptCreateLoginId').value,
password: document.getElementById('iptCreatePassword').value,
email: document.getElementById('iptCreateEmail').value,
name: document.getElementById('iptCreateEmail').value
}).then(response => {
if (response.ok) {
PageHelper.showAlertModal({title: '등록 완료', message: '등록이 완료되었습니다.'});
clearInput();
} else {
PageHelper.showErrorModal('등록에 실패했습니다.');
}
});
});
/**
* 전체 조회
*/
document.getElementById('btnFindAll').addEventListener(('click'), function () {
const requestUri = /*[[@{/admin/management/list}]]*/ '';
fetchGet(requestUri)
.then(response => {
if (response.ok) {
return response.json();
} else {
PageHelper.showErrorModal('데이터 조회에 실패했습니다.');
}
})
.then((data) => {
const selAdministrator = document.getElementById('selAdministrator');
selAdministrator.innerHTML = '<option value="">선택</option>';
data.forEach(item => {
const option = document.createElement('option');
option.value = item.id;
option.text = item.loginId;
selAdministrator.appendChild(option);
});
});
});
document.getElementById('selAdministrator').addEventListener(('change'), function () {
document.getElementById('iptUpdateId').value = this.value;
document.getElementById('iptUpdateLoginId').value = this.options[this.selectedIndex].text;
document.getElementById('iptDeleteId').value = this.value;
document.getElementById('iptDeleteLoginId').value = this.options[this.selectedIndex].text;
});
document.getElementById('btnUpdate').addEventListener(('click'), function () {
const requestUri = /*[[@{/admin/management/update}]]*/ '';
fetchPost(requestUri, {
id: document.getElementById('iptUpdateId').value,
password: document.getElementById('iptUpdatePassword').value,
email: document.getElementById('iptUpdateEmail').value,
name: document.getElementById('iptUpdateEmail').value
}).then(response => {
if (response.ok) {
PageHelper.showAlertModal({title: '수정 완료', message: '수정이 완료되었습니다.'});
} else {
PageHelper.showErrorModal('수정에 실패했습니다.');
}
});
});
document.getElementById('btnDelete').addEventListener(('click'), function () {
const requestUri = /*[[@{/admin/management/delete}]]*/ '';
fetchPost(requestUri, {
id: document.getElementById('iptDeleteId').value
}).then(response => {
if (response.ok) {
PageHelper.showAlertModal({title: '삭제 완료', message: '삭제가 완료되었습니다.'});
clearInput();
} else {
PageHelper.showErrorModal('삭제에 실패했습니다.');
}
});
});
</script>
</th:block>
</body>