From 2edb4c831f9247c228da1f2339c70819933e7b8b Mon Sep 17 00:00:00 2001 From: geonhos Date: Fri, 10 May 2024 09:48:21 +0900 Subject: [PATCH] =?UTF-8?q?=EA=B4=80=EB=A6=AC=EC=9E=90=20=EA=B4=80?= =?UTF-8?q?=EB=A6=AC=20CRUD=20Sample=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- poc/admin/build.gradle | 10 +- .../poc/admin/app/login/LoginService.java | 43 ++--- .../exception/DoNotHaveAnyMenuException.java | 7 + .../poc/admin/config/QuerydslConfig.java | 19 +++ .../poc/admin/domain/DomainException.java | 7 + .../domain/admin/entity/Administrator.java | 6 + .../service/AdministratorCreateCommand.java | 42 +++++ .../admin/service/AdministratorService.java | 51 ++++++ .../service/AdministratorUpdateCommand.java | 42 +++++ .../DuplicationAdministratorException.java | 7 + .../NotFoundAdministratorException.java | 9 + .../poc/admin/security/SecurityConfig.java | 11 +- .../AuthenticationFailReason.java | 4 + .../poc/admin/web/common/CommonResponse.java | 8 + .../poc/admin/web/login/LoginController.java | 3 +- ...dministratorManagementQueryRepository.java | 40 +++++ ...AdministratorManagementRestController.java | 83 +++++++++ .../AdministratorManagementWebService.java | 61 +++++++ .../reqres/AdministratorCreate.java | 51 ++++++ .../reqres/AdministratorDelete.java | 14 ++ .../management/reqres/AdministratorFind.java | 17 ++ .../reqres/AdministratorUpdate.java | 27 +++ poc/admin/src/main/resources/data.sql | 28 +-- .../templates/fragment/csrf/csrf.html | 28 ++- .../templates/main/admin/management/list.html | 161 ++++++++++++++++++ 25 files changed, 720 insertions(+), 59 deletions(-) create mode 100644 poc/admin/src/main/java/com/bpgroup/poc/admin/app/login/exception/DoNotHaveAnyMenuException.java create mode 100644 poc/admin/src/main/java/com/bpgroup/poc/admin/config/QuerydslConfig.java create mode 100644 poc/admin/src/main/java/com/bpgroup/poc/admin/domain/DomainException.java create mode 100644 poc/admin/src/main/java/com/bpgroup/poc/admin/domain/admin/service/AdministratorCreateCommand.java create mode 100644 poc/admin/src/main/java/com/bpgroup/poc/admin/domain/admin/service/AdministratorService.java create mode 100644 poc/admin/src/main/java/com/bpgroup/poc/admin/domain/admin/service/AdministratorUpdateCommand.java create mode 100644 poc/admin/src/main/java/com/bpgroup/poc/admin/domain/admin/service/DuplicationAdministratorException.java create mode 100644 poc/admin/src/main/java/com/bpgroup/poc/admin/domain/admin/service/NotFoundAdministratorException.java create mode 100644 poc/admin/src/main/java/com/bpgroup/poc/admin/web/common/CommonResponse.java create mode 100644 poc/admin/src/main/java/com/bpgroup/poc/admin/web/main/admin/management/AdministratorManagementQueryRepository.java create mode 100644 poc/admin/src/main/java/com/bpgroup/poc/admin/web/main/admin/management/AdministratorManagementRestController.java create mode 100644 poc/admin/src/main/java/com/bpgroup/poc/admin/web/main/admin/management/AdministratorManagementWebService.java create mode 100644 poc/admin/src/main/java/com/bpgroup/poc/admin/web/main/admin/management/reqres/AdministratorCreate.java create mode 100644 poc/admin/src/main/java/com/bpgroup/poc/admin/web/main/admin/management/reqres/AdministratorDelete.java create mode 100644 poc/admin/src/main/java/com/bpgroup/poc/admin/web/main/admin/management/reqres/AdministratorFind.java create mode 100644 poc/admin/src/main/java/com/bpgroup/poc/admin/web/main/admin/management/reqres/AdministratorUpdate.java diff --git a/poc/admin/build.gradle b/poc/admin/build.gradle index 90325d8..b5451fc 100644 --- a/poc/admin/build.gradle +++ b/poc/admin/build.gradle @@ -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' diff --git a/poc/admin/src/main/java/com/bpgroup/poc/admin/app/login/LoginService.java b/poc/admin/src/main/java/com/bpgroup/poc/admin/app/login/LoginService.java index 5f07459..35535b0 100644 --- a/poc/admin/src/main/java/com/bpgroup/poc/admin/app/login/LoginService.java +++ b/poc/admin/src/main/java/com/bpgroup/poc/admin/app/login/LoginService.java @@ -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 = loginRepository.findByLoginId(loginId); if (administrator.isEmpty()) { @@ -42,22 +43,26 @@ public class LoginService { ); } - private static LinkedHashSet getMenus(Administrator administrator) { - return administrator.getAdministratorRole().getRole().getRoleMenus().stream() - .map(roleMenu -> LoginResult.MenuInfo.of( - roleMenu.getMenu().getMenuGroup().getUri(), - roleMenu.getMenu().getMenuGroup().getName(), - roleMenu.getMenu().getMenuGroup().getSortOrder(), - roleMenu.getMenu().getUri(), - roleMenu.getMenu().getName(), - roleMenu.getMenu().getSortOrder() - )) - .sorted( - Comparator - .comparingInt(LoginResult.MenuInfo::getMenuGroupSortOrder) - .thenComparingInt(LoginResult.MenuInfo::getMenuSortOrder) - ) - .collect(Collectors.toCollection(LinkedHashSet::new)); + private static LinkedHashSet getMenus(Administrator administrator) throws DoNotHaveAnyMenuException { + try { + return administrator.getAdministratorRole().getRole().getRoleMenus().stream() + .map(roleMenu -> LoginResult.MenuInfo.of( + roleMenu.getMenu().getMenuGroup().getUri(), + roleMenu.getMenu().getMenuGroup().getName(), + roleMenu.getMenu().getMenuGroup().getSortOrder(), + roleMenu.getMenu().getUri(), + roleMenu.getMenu().getName(), + roleMenu.getMenu().getSortOrder() + )) + .sorted( + Comparator + .comparingInt(LoginResult.MenuInfo::getMenuGroupSortOrder) + .thenComparingInt(LoginResult.MenuInfo::getMenuSortOrder) + ) + .collect(Collectors.toCollection(LinkedHashSet::new)); + } catch (NullPointerException e) { + throw new DoNotHaveAnyMenuException(); + } } } diff --git a/poc/admin/src/main/java/com/bpgroup/poc/admin/app/login/exception/DoNotHaveAnyMenuException.java b/poc/admin/src/main/java/com/bpgroup/poc/admin/app/login/exception/DoNotHaveAnyMenuException.java new file mode 100644 index 0000000..82690a5 --- /dev/null +++ b/poc/admin/src/main/java/com/bpgroup/poc/admin/app/login/exception/DoNotHaveAnyMenuException.java @@ -0,0 +1,7 @@ +package com.bpgroup.poc.admin.app.login.exception; + +public class DoNotHaveAnyMenuException extends Exception { + public DoNotHaveAnyMenuException() { + super(); + } +} diff --git a/poc/admin/src/main/java/com/bpgroup/poc/admin/config/QuerydslConfig.java b/poc/admin/src/main/java/com/bpgroup/poc/admin/config/QuerydslConfig.java new file mode 100644 index 0000000..3c3f956 --- /dev/null +++ b/poc/admin/src/main/java/com/bpgroup/poc/admin/config/QuerydslConfig.java @@ -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); + } +} diff --git a/poc/admin/src/main/java/com/bpgroup/poc/admin/domain/DomainException.java b/poc/admin/src/main/java/com/bpgroup/poc/admin/domain/DomainException.java new file mode 100644 index 0000000..d7f046c --- /dev/null +++ b/poc/admin/src/main/java/com/bpgroup/poc/admin/domain/DomainException.java @@ -0,0 +1,7 @@ +package com.bpgroup.poc.admin.domain; + +public class DomainException extends RuntimeException { + public DomainException() { + super(); + } +} diff --git a/poc/admin/src/main/java/com/bpgroup/poc/admin/domain/admin/entity/Administrator.java b/poc/admin/src/main/java/com/bpgroup/poc/admin/domain/admin/entity/Administrator.java index e28bb3d..f7fc3aa 100644 --- a/poc/admin/src/main/java/com/bpgroup/poc/admin/domain/admin/entity/Administrator.java +++ b/poc/admin/src/main/java/com/bpgroup/poc/admin/domain/admin/entity/Administrator.java @@ -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; + } + } diff --git a/poc/admin/src/main/java/com/bpgroup/poc/admin/domain/admin/service/AdministratorCreateCommand.java b/poc/admin/src/main/java/com/bpgroup/poc/admin/domain/admin/service/AdministratorCreateCommand.java new file mode 100644 index 0000000..39d3f74 --- /dev/null +++ b/poc/admin/src/main/java/com/bpgroup/poc/admin/domain/admin/service/AdministratorCreateCommand.java @@ -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(); + } + +} diff --git a/poc/admin/src/main/java/com/bpgroup/poc/admin/domain/admin/service/AdministratorService.java b/poc/admin/src/main/java/com/bpgroup/poc/admin/domain/admin/service/AdministratorService.java new file mode 100644 index 0000000..008cbb6 --- /dev/null +++ b/poc/admin/src/main/java/com/bpgroup/poc/admin/domain/admin/service/AdministratorService.java @@ -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 = 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 = administratorRepository.findById(command.getId()); + if (administrator.isEmpty()) { + throw new NotFoundAdministratorException(); + } + + administrator.get().update(command.toEntity()); + } + + public void delete( + @NotNull Long id + ) { + administratorRepository.deleteById(id); + } +} \ No newline at end of file diff --git a/poc/admin/src/main/java/com/bpgroup/poc/admin/domain/admin/service/AdministratorUpdateCommand.java b/poc/admin/src/main/java/com/bpgroup/poc/admin/domain/admin/service/AdministratorUpdateCommand.java new file mode 100644 index 0000000..062c04a --- /dev/null +++ b/poc/admin/src/main/java/com/bpgroup/poc/admin/domain/admin/service/AdministratorUpdateCommand.java @@ -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(); + } + +} diff --git a/poc/admin/src/main/java/com/bpgroup/poc/admin/domain/admin/service/DuplicationAdministratorException.java b/poc/admin/src/main/java/com/bpgroup/poc/admin/domain/admin/service/DuplicationAdministratorException.java new file mode 100644 index 0000000..096ff82 --- /dev/null +++ b/poc/admin/src/main/java/com/bpgroup/poc/admin/domain/admin/service/DuplicationAdministratorException.java @@ -0,0 +1,7 @@ +package com.bpgroup.poc.admin.domain.admin.service; + +public class DuplicationAdministratorException extends RuntimeException { + public DuplicationAdministratorException(String loginId) { + super("이미 존재하는 아이디 입니다. : " + loginId); + } +} diff --git a/poc/admin/src/main/java/com/bpgroup/poc/admin/domain/admin/service/NotFoundAdministratorException.java b/poc/admin/src/main/java/com/bpgroup/poc/admin/domain/admin/service/NotFoundAdministratorException.java new file mode 100644 index 0000000..103abc3 --- /dev/null +++ b/poc/admin/src/main/java/com/bpgroup/poc/admin/domain/admin/service/NotFoundAdministratorException.java @@ -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(); + } +} diff --git a/poc/admin/src/main/java/com/bpgroup/poc/admin/security/SecurityConfig.java b/poc/admin/src/main/java/com/bpgroup/poc/admin/security/SecurityConfig.java index 9261d37..04a2ead 100644 --- a/poc/admin/src/main/java/com/bpgroup/poc/admin/security/SecurityConfig.java +++ b/poc/admin/src/main/java/com/bpgroup/poc/admin/security/SecurityConfig.java @@ -37,12 +37,11 @@ public class SecurityConfig { }).addFilterAfter(new CsrfCookieFilter(), BasicAuthenticationFilter.class); // 로그인이 완료된 후 CSRF Filter 를 실행 // 인증 설정 - http.authorizeHttpRequests(c -> { - c.requestMatchers("/css/**", "/images/**", "/js/**").permitAll() - .requestMatchers("/common/modal/**").permitAll() - .requestMatchers(LOGIN_PATH, LOGOUT_PATH, ERROR_PATH).permitAll() - .anyRequest().authenticated(); - }); + http.authorizeHttpRequests(c -> c + .requestMatchers("/css/**", "/images/**", "/js/**").permitAll() + .requestMatchers("/common/modal/**").permitAll() + .requestMatchers(LOGIN_PATH, LOGOUT_PATH, ERROR_PATH).permitAll() + .anyRequest().authenticated()); http.formLogin(c -> c .loginPage(LOGIN_PATH) diff --git a/poc/admin/src/main/java/com/bpgroup/poc/admin/security/authentication/AuthenticationFailReason.java b/poc/admin/src/main/java/com/bpgroup/poc/admin/security/authentication/AuthenticationFailReason.java index 26cfb1c..3240105 100644 --- a/poc/admin/src/main/java/com/bpgroup/poc/admin/security/authentication/AuthenticationFailReason.java +++ b/poc/admin/src/main/java/com/bpgroup/poc/admin/security/authentication/AuthenticationFailReason.java @@ -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; } diff --git a/poc/admin/src/main/java/com/bpgroup/poc/admin/web/common/CommonResponse.java b/poc/admin/src/main/java/com/bpgroup/poc/admin/web/common/CommonResponse.java new file mode 100644 index 0000000..ca06769 --- /dev/null +++ b/poc/admin/src/main/java/com/bpgroup/poc/admin/web/common/CommonResponse.java @@ -0,0 +1,8 @@ +package com.bpgroup.poc.admin.web.common; + +public class CommonResponse { + + protected String resultCode; + protected String resultMessage; + +} diff --git a/poc/admin/src/main/java/com/bpgroup/poc/admin/web/login/LoginController.java b/poc/admin/src/main/java/com/bpgroup/poc/admin/web/login/LoginController.java index 79e5d0a..e7761e5 100644 --- a/poc/admin/src/main/java/com/bpgroup/poc/admin/web/login/LoginController.java +++ b/poc/admin/src/main/java/com/bpgroup/poc/admin/web/login/LoginController.java @@ -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 -> "서버에 오류가 발생했습니다."; }; } diff --git a/poc/admin/src/main/java/com/bpgroup/poc/admin/web/main/admin/management/AdministratorManagementQueryRepository.java b/poc/admin/src/main/java/com/bpgroup/poc/admin/web/main/admin/management/AdministratorManagementQueryRepository.java new file mode 100644 index 0000000..2e223a8 --- /dev/null +++ b/poc/admin/src/main/java/com/bpgroup/poc/admin/web/main/admin/management/AdministratorManagementQueryRepository.java @@ -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 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(); + + } +} diff --git a/poc/admin/src/main/java/com/bpgroup/poc/admin/web/main/admin/management/AdministratorManagementRestController.java b/poc/admin/src/main/java/com/bpgroup/poc/admin/web/main/admin/management/AdministratorManagementRestController.java new file mode 100644 index 0000000..3d35078 --- /dev/null +++ b/poc/admin/src/main/java/com/bpgroup/poc/admin/web/main/admin/management/AdministratorManagementRestController.java @@ -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 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(); + } + +} diff --git a/poc/admin/src/main/java/com/bpgroup/poc/admin/web/main/admin/management/AdministratorManagementWebService.java b/poc/admin/src/main/java/com/bpgroup/poc/admin/web/main/admin/management/AdministratorManagementWebService.java new file mode 100644 index 0000000..03c6d50 --- /dev/null +++ b/poc/admin/src/main/java/com/bpgroup/poc/admin/web/main/admin/management/AdministratorManagementWebService.java @@ -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 findAll() { + return administratorManagementQueryRepository.findAll(); + } +} diff --git a/poc/admin/src/main/java/com/bpgroup/poc/admin/web/main/admin/management/reqres/AdministratorCreate.java b/poc/admin/src/main/java/com/bpgroup/poc/admin/web/main/admin/management/reqres/AdministratorCreate.java new file mode 100644 index 0000000..11c455d --- /dev/null +++ b/poc/admin/src/main/java/com/bpgroup/poc/admin/web/main/admin/management/reqres/AdministratorCreate.java @@ -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; + } + } + +} diff --git a/poc/admin/src/main/java/com/bpgroup/poc/admin/web/main/admin/management/reqres/AdministratorDelete.java b/poc/admin/src/main/java/com/bpgroup/poc/admin/web/main/admin/management/reqres/AdministratorDelete.java new file mode 100644 index 0000000..624f988 --- /dev/null +++ b/poc/admin/src/main/java/com/bpgroup/poc/admin/web/main/admin/management/reqres/AdministratorDelete.java @@ -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; + } + +} diff --git a/poc/admin/src/main/java/com/bpgroup/poc/admin/web/main/admin/management/reqres/AdministratorFind.java b/poc/admin/src/main/java/com/bpgroup/poc/admin/web/main/admin/management/reqres/AdministratorFind.java new file mode 100644 index 0000000..4168c0e --- /dev/null +++ b/poc/admin/src/main/java/com/bpgroup/poc/admin/web/main/admin/management/reqres/AdministratorFind.java @@ -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; + } + +} diff --git a/poc/admin/src/main/java/com/bpgroup/poc/admin/web/main/admin/management/reqres/AdministratorUpdate.java b/poc/admin/src/main/java/com/bpgroup/poc/admin/web/main/admin/management/reqres/AdministratorUpdate.java new file mode 100644 index 0000000..1b5495c --- /dev/null +++ b/poc/admin/src/main/java/com/bpgroup/poc/admin/web/main/admin/management/reqres/AdministratorUpdate.java @@ -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; + } + +} diff --git a/poc/admin/src/main/resources/data.sql b/poc/admin/src/main/resources/data.sql index b587923..4c20415 100644 --- a/poc/admin/src/main/resources/data.sql +++ b/poc/admin/src/main/resources/data.sql @@ -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()) ; diff --git a/poc/admin/src/main/resources/templates/fragment/csrf/csrf.html b/poc/admin/src/main/resources/templates/fragment/csrf/csrf.html index 3cf213e..511db91 100644 --- a/poc/admin/src/main/resources/templates/fragment/csrf/csrf.html +++ b/poc/admin/src/main/resources/templates/fragment/csrf/csrf.html @@ -5,15 +5,31 @@ diff --git a/poc/admin/src/main/resources/templates/main/admin/management/list.html b/poc/admin/src/main/resources/templates/main/admin/management/list.html index bb3d4ab..69c43b0 100644 --- a/poc/admin/src/main/resources/templates/main/admin/management/list.html +++ b/poc/admin/src/main/resources/templates/main/admin/management/list.html @@ -4,10 +4,171 @@ layout:decorate="~{main/admin/management/root.html}"> +
+

관리자 등록

+
+ + + + + + +
+ +

관리자 조회

+
+ + + +
+ +

관리자 수정

+
+ + + + + + +
+ +

관리자 삭제

+
+ + + +
+