Merge pull request 'feat/dev_251201' (#41) from feat/dev_251201 into develop

Reviewed-on: https://kamco.gitea.gs.dabeeo.com/dabeeo/kamco-dabeeo-backoffice/pulls/41
This commit is contained in:
2025-12-10 15:57:35 +09:00
27 changed files with 398 additions and 586 deletions

View File

@@ -25,7 +25,7 @@ public class CustomAuthenticationProvider implements AuthenticationProvider {
// 1. 유저 조회 // 1. 유저 조회
MemberEntity member = MemberEntity member =
membersRepository membersRepository
.findByEmployeeNo(username) .findByUserId(username)
.orElseThrow(() -> new BadCredentialsException("ID 또는 비밀번호가 일치하지 않습니다.")); .orElseThrow(() -> new BadCredentialsException("ID 또는 비밀번호가 일치하지 않습니다."));
// 2. jBCrypt + 커스텀 salt 로 저장된 패스워드 비교 // 2. jBCrypt + 커스텀 salt 로 저장된 패스워드 비교

View File

@@ -16,7 +16,6 @@ public class CustomUserDetails implements UserDetails {
@Override @Override
public Collection<? extends GrantedAuthority> getAuthorities() { public Collection<? extends GrantedAuthority> getAuthorities() {
// 권한을 Member에서 가져오는 경우 바꾸면 됩니다 — 일단 기본값
return Collections.emptyList(); return Collections.emptyList();
} }

View File

@@ -1,5 +1,9 @@
package com.kamco.cd.kamcoback.code.dto; package com.kamco.cd.kamcoback.code.dto;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.kamco.cd.kamcoback.common.utils.html.HtmlEscapeDeserializer;
import com.kamco.cd.kamcoback.common.utils.html.HtmlUnescapeSerializer;
import com.kamco.cd.kamcoback.common.utils.interfaces.JsonFormatDttm; import com.kamco.cd.kamcoback.common.utils.interfaces.JsonFormatDttm;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotEmpty; import jakarta.validation.constraints.NotEmpty;
@@ -27,8 +31,13 @@ public class CommonCodeDto {
private boolean used; private boolean used;
private Long parentId; private Long parentId;
@JsonDeserialize(using = HtmlEscapeDeserializer.class)
private String props1; private String props1;
@JsonDeserialize(using = HtmlEscapeDeserializer.class)
private String props2; private String props2;
@JsonDeserialize(using = HtmlEscapeDeserializer.class)
private String props3; private String props3;
} }
@@ -42,8 +51,13 @@ public class CommonCodeDto {
private String description; private String description;
private boolean used; private boolean used;
@JsonDeserialize(using = HtmlEscapeDeserializer.class)
private String props1; private String props1;
@JsonDeserialize(using = HtmlEscapeDeserializer.class)
private String props2; private String props2;
@JsonDeserialize(using = HtmlEscapeDeserializer.class)
private String props3; private String props3;
} }
@@ -83,8 +97,13 @@ public class CommonCodeDto {
@JsonFormatDttm private ZonedDateTime updatedDttm; @JsonFormatDttm private ZonedDateTime updatedDttm;
@JsonSerialize(using = HtmlUnescapeSerializer.class)
private String props1; private String props1;
@JsonSerialize(using = HtmlUnescapeSerializer.class)
private String props2; private String props2;
@JsonSerialize(using = HtmlUnescapeSerializer.class)
private String props3; private String props3;
@JsonFormatDttm private ZonedDateTime deletedDttm; @JsonFormatDttm private ZonedDateTime deletedDttm;

View File

@@ -0,0 +1,20 @@
package com.kamco.cd.kamcoback.common.utils.html;
import com.fasterxml.jackson.core.JacksonException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import java.io.IOException;
import org.springframework.web.util.HtmlUtils;
public class HtmlEscapeDeserializer extends JsonDeserializer<Object> {
@Override
public Object deserialize(JsonParser jsonParser, DeserializationContext deserializationContext)
throws IOException, JacksonException {
String value = jsonParser.getValueAsString();
System.out.println("🔥 HtmlEscapeDeserializer 실행됨: " + value);
System.out.println("convert : " + (value == null ? null : HtmlUtils.htmlEscape(value)));
return value == null ? null : HtmlUtils.htmlEscape(value);
}
}

View File

@@ -0,0 +1,20 @@
package com.kamco.cd.kamcoback.common.utils.html;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import java.io.IOException;
import org.springframework.web.util.HtmlUtils;
public class HtmlUnescapeSerializer extends JsonSerializer<String> {
@Override
public void serialize(
String value, JsonGenerator jsonGenerator, SerializerProvider serializerProvider)
throws IOException {
if (value == null) {
jsonGenerator.writeNull();
} else {
jsonGenerator.writeString(HtmlUtils.htmlUnescape(value));
}
}
}

View File

@@ -241,11 +241,8 @@ public class GlobalExceptionHandler {
String codeName = ""; String codeName = "";
switch (e.getField()) { switch (e.getField()) {
case EMPLOYEE_NO -> { case USER_ID -> {
codeName = "DUPLICATE_EMPLOYEEID"; codeName = "DUPLICATE_DATA";
}
case EMAIL -> {
codeName = "DUPLICATE_EMAIL";
} }
default -> { default -> {
codeName = "DUPLICATE_DATA"; codeName = "DUPLICATE_DATA";

View File

@@ -16,11 +16,12 @@ import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PatchMapping; import org.springframework.web.bind.annotation.PatchMapping;
import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
@Tag(name = "회원정보 관리자 관리", description = "회원정보 관리자 관리 API") @Tag(name = "관리자 관리", description = "관리자 관리 API")
@RestController @RestController
@RequestMapping("/api/admin/members") @RequestMapping("/api/admin/members")
@RequiredArgsConstructor @RequiredArgsConstructor
@@ -28,12 +29,12 @@ public class AdminApiController {
private final AdminService adminService; private final AdminService adminService;
@Operation(summary = "회원가입", description = "회원가입") @Operation(summary = "관리자 계정 등록", description = "관리자 계정 등록")
@ApiResponses( @ApiResponses(
value = { value = {
@ApiResponse( @ApiResponse(
responseCode = "201", responseCode = "201",
description = "회원가입 성공", description = "등록 성공",
content = content =
@Content( @Content(
mediaType = "application/json", mediaType = "application/json",
@@ -45,7 +46,7 @@ public class AdminApiController {
@PostMapping("/join") @PostMapping("/join")
public ApiResponseDto<Long> saveMember( public ApiResponseDto<Long> saveMember(
@io.swagger.v3.oas.annotations.parameters.RequestBody( @io.swagger.v3.oas.annotations.parameters.RequestBody(
description = "회원가입", description = "관리자 계정 등록",
required = true, required = true,
content = content =
@Content( @Content(
@@ -58,94 +59,34 @@ public class AdminApiController {
return ApiResponseDto.createOK(adminService.saveMember(addReq)); return ApiResponseDto.createOK(adminService.saveMember(addReq));
} }
@Operation(summary = "역할 추가", description = "uuid 기준으로 역할 추가") @Operation(summary = "관리자 계정 수정", description = "관리자 계정 수정")
@ApiResponses( @ApiResponses(
value = { value = {
@ApiResponse( @ApiResponse(
responseCode = "201", responseCode = "201",
description = "역할 추가", description = "수정 성공",
content = content =
@Content( @Content(
mediaType = "application/json", mediaType = "application/json",
schema = @Schema(implementation = UUID.class))), schema = @Schema(implementation = Long.class))),
@ApiResponse(responseCode = "400", description = "잘못된 요청 데이터", content = @Content), @ApiResponse(responseCode = "400", description = "잘못된 요청 데이터", content = @Content),
@ApiResponse(responseCode = "404", description = "코드를 찾을 수 없음", content = @Content), @ApiResponse(responseCode = "404", description = "코드를 찾을 수 없음", content = @Content),
@ApiResponse(responseCode = "500", description = "서버 오류", content = @Content) @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content)
}) })
@PostMapping("/roles/add") @PutMapping("/{uuid}")
public ApiResponseDto<UUID> saveRoles( public ApiResponseDto<UUID> updateMembers(
@io.swagger.v3.oas.annotations.parameters.RequestBody( @io.swagger.v3.oas.annotations.parameters.RequestBody(
description = "역할 추가", description = "관리자 계정 수정",
required = true, required = true,
content = content =
@Content( @Content(
mediaType = "application/json", mediaType = "application/json",
schema = @Schema(implementation = MembersDto.RolesDto.class))) schema = @Schema(implementation = MembersDto.UpdateReq.class)))
@RequestBody
@Valid
MembersDto.RolesDto rolesDto) {
adminService.saveRoles(rolesDto);
return ApiResponseDto.createOK(rolesDto.getUuid());
}
@Operation(summary = "역할 삭제", description = "uuid 기준으로 역할 삭제")
@ApiResponses(
value = {
@ApiResponse(
responseCode = "201",
description = "역할 삭제",
content =
@Content(
mediaType = "application/json",
schema = @Schema(implementation = UUID.class))),
@ApiResponse(responseCode = "400", description = "잘못된 요청 데이터", content = @Content),
@ApiResponse(responseCode = "404", description = "코드를 찾을 수 없음", content = @Content),
@ApiResponse(responseCode = "500", description = "서버 오류", content = @Content)
})
@DeleteMapping("/roles/rm")
public ApiResponseDto<UUID> deleteRoles(
@io.swagger.v3.oas.annotations.parameters.RequestBody(
description = "역할 삭제",
required = true,
content =
@Content(
mediaType = "application/json",
schema = @Schema(implementation = MembersDto.RolesDto.class)))
@RequestBody
@Valid
MembersDto.RolesDto rolesDto) {
adminService.deleteRoles(rolesDto);
return ApiResponseDto.createOK(rolesDto.getUuid());
}
@Operation(summary = "상태 수정", description = "상태 수정")
@ApiResponses(
value = {
@ApiResponse(
responseCode = "201",
description = "상태 수정",
content =
@Content(
mediaType = "application/json",
schema = @Schema(implementation = UUID.class))),
@ApiResponse(responseCode = "400", description = "잘못된 요청 데이터", content = @Content),
@ApiResponse(responseCode = "404", description = "코드를 찾을 수 없음", content = @Content),
@ApiResponse(responseCode = "500", description = "서버 오류", content = @Content)
})
@PatchMapping("{uuid}/status")
public ApiResponseDto<UUID> updateStatus(
@io.swagger.v3.oas.annotations.parameters.RequestBody(
description = "상태 수정",
required = true,
content =
@Content(
mediaType = "application/json",
schema = @Schema(implementation = MembersDto.StatusDto.class)))
@PathVariable @PathVariable
UUID uuid, UUID uuid,
@RequestBody @Valid MembersDto.StatusDto statusDto) { @RequestBody MembersDto.UpdateReq updateReq) {
adminService.updateStatus(uuid, statusDto); adminService.updateMembers(uuid, updateReq);
return ApiResponseDto.createOK(uuid); return ApiResponseDto.createOK(UUID.randomUUID());
} }
@Operation(summary = "회원 탈퇴", description = "회원 탈퇴") @Operation(summary = "회원 탈퇴", description = "회원 탈퇴")

View File

@@ -86,7 +86,7 @@ public class AuthController {
.build(); .build();
response.addHeader(HttpHeaders.SET_COOKIE, cookie.toString()); response.addHeader(HttpHeaders.SET_COOKIE, cookie.toString());
return ApiResponseDto.ok(new TokenResponse(accessToken)); return ApiResponseDto.ok(new TokenResponse(accessToken, refreshToken));
} }
@PostMapping("/refresh") @PostMapping("/refresh")
@@ -133,7 +133,7 @@ public class AuthController {
.build(); .build();
response.addHeader(HttpHeaders.SET_COOKIE, cookie.toString()); response.addHeader(HttpHeaders.SET_COOKIE, cookie.toString());
return ResponseEntity.ok(new TokenResponse(newAccessToken)); return ResponseEntity.ok(new TokenResponse(newAccessToken, newRefreshToken));
} }
@PostMapping("/logout") @PostMapping("/logout")
@@ -166,5 +166,5 @@ public class AuthController {
return ApiResponseDto.createOK(ResponseEntity.noContent().build()); return ApiResponseDto.createOK(ResponseEntity.noContent().build());
} }
public record TokenResponse(String accessToken) {} public record TokenResponse(String accessToken, String refreshToken) {}
} }

View File

@@ -65,7 +65,7 @@ public class MembersApiController {
@PutMapping("/{uuid}") @PutMapping("/{uuid}")
public ApiResponseDto<UUID> updateMember( public ApiResponseDto<UUID> updateMember(
@PathVariable UUID uuid, @RequestBody MembersDto.UpdateReq updateReq) { @PathVariable UUID uuid, @RequestBody MembersDto.UpdateReq updateReq) {
membersService.updateMember(uuid, updateReq); // membersService.updateMember(uuid, updateReq);
return ApiResponseDto.createOK(uuid); return ApiResponseDto.createOK(uuid);
} }
} }

View File

@@ -32,7 +32,7 @@ public class MemberDetails implements UserDetails {
public String getUsername() { public String getUsername() {
// 로그인 ID 로 무엇을 쓸지 선택 // 로그인 ID 로 무엇을 쓸지 선택
// 1) 이메일 로그인: // 1) 이메일 로그인:
return member.getEmail(); return member.getUserId();
// 2) 사번으로 로그인하고 싶으면: // 2) 사번으로 로그인하고 싶으면:
// return member.getEmployeeNo(); // return member.getEmployeeNo();

View File

@@ -90,28 +90,34 @@ public class MembersDto {
@Setter @Setter
public static class AddReq { public static class AddReq {
@Schema(description = "사번", example = "11111") @Schema(description = "관리자 유형", example = "ROLE_ADMIN")
@NotBlank @NotBlank
@Size(max = 50) @Size(max = 50)
private String employeeNo; private String userRole;
@Schema(description = "이름", example = "홍길동") @Schema(description = "이름", example = "홍길동")
@NotBlank @NotBlank
@Size(min = 2, max = 100) @Size(min = 2, max = 100)
private String name; private String name;
@Schema(hidden = true) @Schema(description = "ID", example = "gildong")
private String password; @NotBlank
@Size(min = 2, max = 50)
private String userId;
@Schema(description = "이메일", example = "gildong@daum.net") @Schema(description = "임시 비밀번호", example = "q!w@e#r4")
@Size(max = 100) private String tempPassword;
private String email;
public AddReq(String employeeNo, String name, String password, String email) { @Schema(description = "사번", example = "123456")
this.employeeNo = employeeNo; private String employeeNo;
public AddReq(
String userRole, String name, String userId, String tempPassword, String employeeNo) {
this.userRole = userRole;
this.name = name; this.name = name;
this.password = password; this.userId = userId;
this.email = email; this.tempPassword = tempPassword;
this.employeeNo = employeeNo;
} }
} }
@@ -129,17 +135,12 @@ public class MembersDto {
@Schema(description = "패스워드", example = "") @Schema(description = "패스워드", example = "")
@Size(max = 255) @Size(max = 255)
private String password; private String tempPassword;
@Schema(description = "이메일", example = "gildong@daum.net") public UpdateReq(String employeeNo, String name, String tempPassword) {
@Size(max = 100)
private String email;
public UpdateReq(String employeeNo, String name, String password, String email) {
this.employeeNo = employeeNo; this.employeeNo = employeeNo;
this.name = name; this.name = name;
this.password = password; this.tempPassword = tempPassword;
this.email = email;
} }
} }

View File

@@ -11,7 +11,7 @@ import lombok.ToString;
@ToString(exclude = "password") @ToString(exclude = "password")
public class SignInRequest { public class SignInRequest {
@Schema(description = "", example = "11111") @Schema(description = "용자 ID", example = "admin")
private String username; private String username;
@Schema(description = "비밀번호", example = "kamco1234!") @Schema(description = "비밀번호", example = "kamco1234!")

View File

@@ -10,8 +10,7 @@ public class MemberException {
public static class DuplicateMemberException extends RuntimeException { public static class DuplicateMemberException extends RuntimeException {
public enum Field { public enum Field {
EMPLOYEE_NO, USER_ID,
EMAIL,
DEFAULT DEFAULT
} }

View File

@@ -6,7 +6,6 @@ import com.kamco.cd.kamcoback.postgres.core.MembersCoreService;
import java.util.UUID; import java.util.UUID;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.mindrot.jbcrypt.BCrypt; import org.mindrot.jbcrypt.BCrypt;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
@@ -17,9 +16,6 @@ public class AdminService {
private final MembersCoreService membersCoreService; private final MembersCoreService membersCoreService;
@Value("${member.init_password}")
private String password;
/** /**
* 회원가입 * 회원가입
* *
@@ -29,14 +25,18 @@ public class AdminService {
@Transactional @Transactional
public Long saveMember(MembersDto.AddReq addReq) { public Long saveMember(MembersDto.AddReq addReq) {
// salt 생성, 사번이 salt // salt 생성, 사번이 salt
String salt = BCryptSaltGenerator.generateSaltWithEmployeeNo(addReq.getEmployeeNo().trim()); String salt = BCryptSaltGenerator.generateSaltWithEmployeeNo(addReq.getUserId().trim());
// 패스워드 암호화, 초기 패스워드 고정 // 패스워드 암호화, 초기 패스워드 고정
String hashedPassword = BCrypt.hashpw(password, salt); String hashedPassword = BCrypt.hashpw(addReq.getTempPassword(), salt);
addReq.setPassword(hashedPassword); addReq.setTempPassword(hashedPassword);
return membersCoreService.saveMembers(addReq); return membersCoreService.saveMembers(addReq);
} }
public void updateMembers(UUID uuid, MembersDto.UpdateReq updateReq) {
membersCoreService.updateMembers(uuid, updateReq);
}
/** /**
* 역할 추가 * 역할 추가
* *
@@ -44,7 +44,7 @@ public class AdminService {
*/ */
@Transactional @Transactional
public void saveRoles(MembersDto.RolesDto rolesDto) { public void saveRoles(MembersDto.RolesDto rolesDto) {
membersCoreService.saveRoles(rolesDto); // membersCoreService.saveRoles(rolesDto);
} }
/** /**
@@ -53,7 +53,7 @@ public class AdminService {
* @param rolesDto * @param rolesDto
*/ */
public void deleteRoles(MembersDto.RolesDto rolesDto) { public void deleteRoles(MembersDto.RolesDto rolesDto) {
membersCoreService.deleteRoles(rolesDto); // membersCoreService.deleteRoles(rolesDto);
} }
/** /**
@@ -62,7 +62,7 @@ public class AdminService {
* @param statusDto * @param statusDto
*/ */
public void updateStatus(UUID uuid, MembersDto.StatusDto statusDto) { public void updateStatus(UUID uuid, MembersDto.StatusDto statusDto) {
membersCoreService.updateStatus(uuid, statusDto); // membersCoreService.updateStatus(uuid, statusDto);
} }
/** /**
@@ -71,7 +71,7 @@ public class AdminService {
* @param uuid * @param uuid
*/ */
public void deleteAccount(UUID uuid) { public void deleteAccount(UUID uuid) {
membersCoreService.deleteAccount(uuid); // membersCoreService.deleteAccount(uuid);
} }
/** /**
@@ -80,6 +80,6 @@ public class AdminService {
* @param id * @param id
*/ */
public void resetPassword(Long id) { public void resetPassword(Long id) {
membersCoreService.resetPassword(id); // membersCoreService.resetPassword(id);
} }
} }

View File

@@ -1,17 +1,11 @@
package com.kamco.cd.kamcoback.members.service; package com.kamco.cd.kamcoback.members.service;
import com.kamco.cd.kamcoback.auth.BCryptSaltGenerator;
import com.kamco.cd.kamcoback.common.exception.CustomApiException;
import com.kamco.cd.kamcoback.members.dto.MembersDto; import com.kamco.cd.kamcoback.members.dto.MembersDto;
import com.kamco.cd.kamcoback.members.dto.MembersDto.Basic; import com.kamco.cd.kamcoback.members.dto.MembersDto.Basic;
import com.kamco.cd.kamcoback.postgres.core.MembersCoreService; import com.kamco.cd.kamcoback.postgres.core.MembersCoreService;
import java.util.UUID;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.mindrot.jbcrypt.BCrypt;
import org.springframework.data.domain.Page; import org.springframework.data.domain.Page;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
@@ -29,7 +23,7 @@ public class MembersService {
* @return * @return
*/ */
public Page<Basic> findByMembers(MembersDto.SearchReq searchReq) { public Page<Basic> findByMembers(MembersDto.SearchReq searchReq) {
return membersCoreService.findByMembers(searchReq); return null; // membersCoreService.findByMembers(searchReq);
} }
/** /**
@@ -38,29 +32,29 @@ public class MembersService {
* @param uuid * @param uuid
* @param updateReq * @param updateReq
*/ */
public void updateMember(UUID uuid, MembersDto.UpdateReq updateReq) { // public void updateMember(UUID uuid, MembersDto.UpdateReq updateReq) {
//
if (StringUtils.isNotBlank(updateReq.getPassword())) { // if (StringUtils.isNotBlank(updateReq.getPassword())) {
//
if (!this.isValidPassword(updateReq.getPassword())) { // if (!this.isValidPassword(updateReq.getPassword())) {
throw new CustomApiException("WRONG_PASSWORD", HttpStatus.BAD_REQUEST); // throw new CustomApiException("WRONG_PASSWORD", HttpStatus.BAD_REQUEST);
} // }
//
if (StringUtils.isBlank(updateReq.getEmployeeNo())) { // if (StringUtils.isBlank(updateReq.getEmployeeNo())) {
throw new CustomApiException("BAD_REQUEST", HttpStatus.BAD_REQUEST); // throw new CustomApiException("BAD_REQUEST", HttpStatus.BAD_REQUEST);
} // }
//
// salt 생성, 사번이 salt // // salt 생성, 사번이 salt
String salt = // String salt =
BCryptSaltGenerator.generateSaltWithEmployeeNo(updateReq.getEmployeeNo().trim()); // BCryptSaltGenerator.generateSaltWithEmployeeNo(updateReq.getEmployeeNo().trim());
//
// 패스워드 암호화, 초기 패스워드 고정 // // 패스워드 암호화, 초기 패스워드 고정
String hashedPassword = BCrypt.hashpw(updateReq.getPassword(), salt); // String hashedPassword = BCrypt.hashpw(updateReq.getPassword(), salt);
updateReq.setPassword(hashedPassword); // updateReq.setPassword(hashedPassword);
} // }
//
membersCoreService.updateMembers(uuid, updateReq); // membersCoreService.updateMembers(uuid, updateReq);
} // }
/** /**
* 대문자 1개 이상 소문자 1개 이상 숫자 1개 이상 특수문자(!@#$) 1개 이상 * 대문자 1개 이상 소문자 1개 이상 숫자 1개 이상 특수문자(!@#$) 1개 이상

View File

@@ -1,24 +1,16 @@
package com.kamco.cd.kamcoback.postgres.core; package com.kamco.cd.kamcoback.postgres.core;
import com.kamco.cd.kamcoback.auth.BCryptSaltGenerator;
import com.kamco.cd.kamcoback.members.dto.MembersDto; import com.kamco.cd.kamcoback.members.dto.MembersDto;
import com.kamco.cd.kamcoback.members.exception.MemberException; import com.kamco.cd.kamcoback.members.dto.MembersDto.AddReq;
import com.kamco.cd.kamcoback.members.exception.MemberException.DuplicateMemberException;
import com.kamco.cd.kamcoback.members.exception.MemberException.DuplicateMemberException.Field;
import com.kamco.cd.kamcoback.members.exception.MemberException.MemberNotFoundException; import com.kamco.cd.kamcoback.members.exception.MemberException.MemberNotFoundException;
import com.kamco.cd.kamcoback.postgres.entity.MemberArchivedEntity;
import com.kamco.cd.kamcoback.postgres.entity.MemberArchivedEntityId;
import com.kamco.cd.kamcoback.postgres.entity.MemberEntity; import com.kamco.cd.kamcoback.postgres.entity.MemberEntity;
import com.kamco.cd.kamcoback.postgres.entity.MemberRoleEntity;
import com.kamco.cd.kamcoback.postgres.entity.MemberRoleEntityId;
import com.kamco.cd.kamcoback.postgres.repository.members.MembersArchivedRepository; import com.kamco.cd.kamcoback.postgres.repository.members.MembersArchivedRepository;
import com.kamco.cd.kamcoback.postgres.repository.members.MembersRepository; import com.kamco.cd.kamcoback.postgres.repository.members.MembersRepository;
import com.kamco.cd.kamcoback.postgres.repository.members.MembersRoleRepository;
import java.time.ZonedDateTime;
import java.util.UUID; import java.util.UUID;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.mindrot.jbcrypt.BCrypt;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@Service @Service
@@ -26,34 +18,25 @@ import org.springframework.stereotype.Service;
public class MembersCoreService { public class MembersCoreService {
private final MembersRepository membersRepository; private final MembersRepository membersRepository;
private final MembersRoleRepository memberRoleRepository;
private final MembersArchivedRepository memberArchivedRepository; private final MembersArchivedRepository memberArchivedRepository;
@Value("${member.init_password}")
private String password;
/** /**
* 회원가입 * 회원가입
* *
* @param addReq * @param addReq
* @return * @return
*/ */
public Long saveMembers(MembersDto.AddReq addReq) { public Long saveMembers(AddReq addReq) {
if (membersRepository.existsByEmployeeNo(addReq.getEmployeeNo())) { if (membersRepository.existsByUserId(addReq.getUserId())) {
throw new MemberException.DuplicateMemberException( throw new DuplicateMemberException(Field.USER_ID, addReq.getUserId());
MemberException.DuplicateMemberException.Field.EMPLOYEE_NO, addReq.getEmployeeNo());
} }
if (membersRepository.existsByEmail(addReq.getEmail())) {
throw new MemberException.DuplicateMemberException(
MemberException.DuplicateMemberException.Field.EMAIL, addReq.getEmail());
}
MemberEntity memberEntity = new MemberEntity(); MemberEntity memberEntity = new MemberEntity();
memberEntity.setEmployeeNo(addReq.getEmployeeNo()); memberEntity.setUserId(addReq.getUserId());
memberEntity.setUserRole(addReq.getUserRole());
memberEntity.setTempPassword(addReq.getTempPassword());
memberEntity.setPassword(addReq.getTempPassword());
memberEntity.setName(addReq.getName()); memberEntity.setName(addReq.getName());
memberEntity.setPassword(addReq.getPassword()); memberEntity.setEmployeeNo(addReq.getEmployeeNo());
memberEntity.setEmail(addReq.getEmail());
return membersRepository.save(memberEntity).getId(); return membersRepository.save(memberEntity).getId();
} }
@@ -66,141 +49,141 @@ public class MembersCoreService {
*/ */
public void updateMembers(UUID uuid, MembersDto.UpdateReq updateReq) { public void updateMembers(UUID uuid, MembersDto.UpdateReq updateReq) {
MemberEntity memberEntity = MemberEntity memberEntity =
membersRepository.findByUUID(uuid).orElseThrow(() -> new MemberNotFoundException()); membersRepository.findByUUID(uuid).orElseThrow(MemberNotFoundException::new);
if (StringUtils.isNotBlank(updateReq.getName())) {
memberEntity.setName(updateReq.getName());
}
if (StringUtils.isNotBlank(updateReq.getTempPassword())) {
memberEntity.setTempPassword(updateReq.getTempPassword());
memberEntity.setPassword(updateReq.getTempPassword());
}
if (StringUtils.isNotBlank(memberEntity.getEmployeeNo())) { if (StringUtils.isNotBlank(memberEntity.getEmployeeNo())) {
memberEntity.setEmployeeNo(updateReq.getEmployeeNo()); memberEntity.setEmployeeNo(updateReq.getEmployeeNo());
} }
if (StringUtils.isNotBlank(updateReq.getName())) {
memberEntity.setName(updateReq.getName());
}
if (StringUtils.isNotBlank(updateReq.getPassword())) {
memberEntity.setPassword(updateReq.getPassword());
}
if (StringUtils.isNotBlank(updateReq.getEmail())) {
memberEntity.setEmail(updateReq.getEmail());
}
membersRepository.save(memberEntity);
}
/**
* 역할 추가
*
* @param rolesDto
*/
public void saveRoles(MembersDto.RolesDto rolesDto) {
MemberEntity memberEntity =
membersRepository
.findByUUID(rolesDto.getUuid())
.orElseThrow(() -> new MemberNotFoundException());
if (memberRoleRepository.findByUuidAndRoleName(rolesDto)) {
throw new MemberException.DuplicateMemberException(
MemberException.DuplicateMemberException.Field.DEFAULT, "중복된 역할이 있습니다.");
}
MemberRoleEntityId memberRoleEntityId = new MemberRoleEntityId();
memberRoleEntityId.setMemberUuid(rolesDto.getUuid());
memberRoleEntityId.setRoleName(rolesDto.getRoleName());
MemberRoleEntity memberRoleEntity = new MemberRoleEntity();
memberRoleEntity.setId(memberRoleEntityId);
memberRoleEntity.setMemberUuid(memberEntity);
memberRoleEntity.setCreatedDttm(ZonedDateTime.now());
memberRoleRepository.save(memberRoleEntity);
}
/**
* 역할 삭제
*
* @param rolesDto
*/
public void deleteRoles(MembersDto.RolesDto rolesDto) {
MemberEntity memberEntity =
membersRepository
.findByUUID(rolesDto.getUuid())
.orElseThrow(() -> new MemberNotFoundException());
MemberRoleEntityId memberRoleEntityId = new MemberRoleEntityId();
memberRoleEntityId.setMemberUuid(rolesDto.getUuid());
memberRoleEntityId.setRoleName(rolesDto.getRoleName());
MemberRoleEntity memberRoleEntity = new MemberRoleEntity();
memberRoleEntity.setId(memberRoleEntityId);
memberRoleEntity.setMemberUuid(memberEntity);
memberRoleRepository.delete(memberRoleEntity);
}
/**
* 상태 수정
*
* @param statusDto
*/
public void updateStatus(UUID uuid, MembersDto.StatusDto statusDto) {
MemberEntity memberEntity =
membersRepository.findByUUID(uuid).orElseThrow(() -> new MemberNotFoundException());
memberEntity.setStatus(statusDto.getStatus());
memberEntity.setUpdatedDttm(ZonedDateTime.now());
membersRepository.save(memberEntity);
}
/**
* 회원 탈퇴
*
* @param uuid
*/
public void deleteAccount(UUID uuid) {
MemberEntity memberEntity =
membersRepository.findByUUID(uuid).orElseThrow(() -> new MemberNotFoundException());
MemberArchivedEntityId memberArchivedEntityId = new MemberArchivedEntityId();
memberArchivedEntityId.setUserId(memberEntity.getId());
memberArchivedEntityId.setUuid(memberEntity.getUuid());
MemberArchivedEntity memberArchivedEntity = new MemberArchivedEntity();
memberArchivedEntity.setId(memberArchivedEntityId);
memberArchivedEntity.setEmployeeNo(memberEntity.getEmployeeNo());
memberArchivedEntity.setName(memberEntity.getName());
memberArchivedEntity.setPassword(memberEntity.getPassword());
memberArchivedEntity.setEmail(memberEntity.getEmail());
memberArchivedEntity.setStatus(memberEntity.getStatus());
memberArchivedEntity.setCreatedDttm(memberEntity.getCreatedDttm());
memberArchivedEntity.setArchivedDttm(ZonedDateTime.now());
memberArchivedRepository.save(memberArchivedEntity);
memberEntity.setStatus("ARCHIVED");
memberEntity.setName("**********");
memberEntity.setEmployeeNo("**********");
memberEntity.setPassword("**********");
memberEntity.setEmail("**********");
memberEntity.setUpdatedDttm(ZonedDateTime.now());
membersRepository.save(memberEntity);
}
/**
* 패스워드 초기화
*
* @param id
*/
public void resetPassword(Long id) {
MemberEntity memberEntity =
membersRepository.findById(id).orElseThrow(() -> new MemberNotFoundException());
String salt =
BCryptSaltGenerator.generateSaltWithEmployeeNo(memberEntity.getEmployeeNo().trim());
// 패스워드 암호화, 초기 패스워드 고정
String hashedPassword = BCrypt.hashpw(password, salt);
memberEntity.setPassword(hashedPassword);
memberEntity.setStatus("INACTIVE");
memberEntity.setUpdatedDttm(ZonedDateTime.now());
membersRepository.save(memberEntity); membersRepository.save(memberEntity);
} }
//
// /**
// * 역할 추가
// *
// * @param rolesDto
// */
// public void saveRoles(MembersDto.RolesDto rolesDto) {
//
// MemberEntity memberEntity =
// membersRepository
// .findByUUID(rolesDto.getUuid())
// .orElseThrow(() -> new MemberNotFoundException());
//
// if (memberRoleRepository.findByUuidAndRoleName(rolesDto)) {
// throw new MemberException.DuplicateMemberException(
// MemberException.DuplicateMemberException.Field.DEFAULT, "중복된 역할이 있습니다.");
// }
//
// MemberRoleEntityId memberRoleEntityId = new MemberRoleEntityId();
// memberRoleEntityId.setMemberUuid(rolesDto.getUuid());
// memberRoleEntityId.setRoleName(rolesDto.getRoleName());
//
// MemberRoleEntity memberRoleEntity = new MemberRoleEntity();
// memberRoleEntity.setId(memberRoleEntityId);
// memberRoleEntity.setMemberUuid(memberEntity);
// memberRoleEntity.setCreatedDttm(ZonedDateTime.now());
// memberRoleRepository.save(memberRoleEntity);
// }
//
// /**
// * 역할 삭제
// *
// * @param rolesDto
// */
// public void deleteRoles(MembersDto.RolesDto rolesDto) {
// MemberEntity memberEntity =
// membersRepository
// .findByUUID(rolesDto.getUuid())
// .orElseThrow(() -> new MemberNotFoundException());
//
// MemberRoleEntityId memberRoleEntityId = new MemberRoleEntityId();
// memberRoleEntityId.setMemberUuid(rolesDto.getUuid());
// memberRoleEntityId.setRoleName(rolesDto.getRoleName());
//
// MemberRoleEntity memberRoleEntity = new MemberRoleEntity();
// memberRoleEntity.setId(memberRoleEntityId);
// memberRoleEntity.setMemberUuid(memberEntity);
//
// memberRoleRepository.delete(memberRoleEntity);
// }
//
// /**
// * 상태 수정
// *
// * @param statusDto
// */
// public void updateStatus(UUID uuid, MembersDto.StatusDto statusDto) {
// MemberEntity memberEntity =
// membersRepository.findByUUID(uuid).orElseThrow(() -> new MemberNotFoundException());
//
// memberEntity.setStatus(statusDto.getStatus());
// memberEntity.setUpdatedDttm(ZonedDateTime.now());
// membersRepository.save(memberEntity);
// }
//
// /**
// * 회원 탈퇴
// *
// * @param uuid
// */
// public void deleteAccount(UUID uuid) {
// MemberEntity memberEntity =
// membersRepository.findByUUID(uuid).orElseThrow(() -> new MemberNotFoundException());
//
// MemberArchivedEntityId memberArchivedEntityId = new MemberArchivedEntityId();
// memberArchivedEntityId.setUserId(memberEntity.getId());
// memberArchivedEntityId.setUuid(memberEntity.getUuid());
//
// MemberArchivedEntity memberArchivedEntity = new MemberArchivedEntity();
// memberArchivedEntity.setId(memberArchivedEntityId);
// memberArchivedEntity.setEmployeeNo(memberEntity.getEmployeeNo());
// memberArchivedEntity.setName(memberEntity.getName());
// memberArchivedEntity.setPassword(memberEntity.getPassword());
// memberArchivedEntity.setEmail(memberEntity.getEmail());
// memberArchivedEntity.setStatus(memberEntity.getStatus());
// memberArchivedEntity.setCreatedDttm(memberEntity.getCreatedDttm());
// memberArchivedEntity.setArchivedDttm(ZonedDateTime.now());
// memberArchivedRepository.save(memberArchivedEntity);
//
// memberEntity.setStatus("ARCHIVED");
// memberEntity.setName("**********");
// memberEntity.setEmployeeNo("**********");
// memberEntity.setPassword("**********");
// memberEntity.setEmail("**********");
// memberEntity.setUpdatedDttm(ZonedDateTime.now());
// membersRepository.save(memberEntity);
// }
//
// /**
// * 패스워드 초기화
// *
// * @param id
// */
// public void resetPassword(Long id) {
// MemberEntity memberEntity =
// membersRepository.findById(id).orElseThrow(() -> new MemberNotFoundException());
//
// String salt =
// BCryptSaltGenerator.generateSaltWithEmployeeNo(memberEntity.getEmployeeNo().trim());
// // 패스워드 암호화, 초기 패스워드 고정
// String hashedPassword = BCrypt.hashpw(password, salt);
//
// memberEntity.setPassword(hashedPassword);
// memberEntity.setStatus("INACTIVE");
// memberEntity.setUpdatedDttm(ZonedDateTime.now());
// membersRepository.save(memberEntity);
// }
//
/** /**
* 회원목록 조회 * 회원목록 조회
@@ -208,7 +191,7 @@ public class MembersCoreService {
* @param searchReq * @param searchReq
* @return * @return
*/ */
public Page<MembersDto.Basic> findByMembers(MembersDto.SearchReq searchReq) { // public Page<Basic> findByMembers(MembersDto.SearchReq searchReq) {
return membersRepository.findByMembers(searchReq); // return membersRepository.findByMembers(searchReq);
} // }
} }

View File

@@ -5,13 +5,10 @@ import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue; import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType; import jakarta.persistence.GenerationType;
import jakarta.persistence.Id; import jakarta.persistence.Id;
import jakarta.persistence.OneToMany;
import jakarta.persistence.Table; import jakarta.persistence.Table;
import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size; import jakarta.validation.constraints.Size;
import java.time.ZonedDateTime; import java.time.ZonedDateTime;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.UUID; import java.util.UUID;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
@@ -28,11 +25,24 @@ public class MemberEntity {
@Column(name = "id", nullable = false) @Column(name = "id", nullable = false)
private Long id; private Long id;
@Column(name = "uuid", nullable = false, insertable = false) @NotNull
private UUID uuid; @ColumnDefault("gen_random_uuid()")
@Column(name = "uuid", nullable = false)
private UUID uuid = UUID.randomUUID();
@Size(max = 50) @Size(max = 50)
@Column(name = "employee_no", length = 50) @NotNull
@Column(name = "user_role", nullable = false, length = 50)
private String userRole;
@Size(max = 50)
@NotNull
@Column(name = "user_id", nullable = false, length = 50)
private String userId;
@Size(max = 50)
@NotNull
@Column(name = "employee_no", nullable = false, length = 50)
private String employeeNo; private String employeeNo;
@Size(max = 100) @Size(max = 100)
@@ -40,26 +50,27 @@ public class MemberEntity {
@Column(name = "name", nullable = false, length = 100) @Column(name = "name", nullable = false, length = 100)
private String name; private String name;
@Size(max = 255)
@NotNull
@Column(name = "temp_password", nullable = false)
private String tempPassword;
@Size(max = 255) @Size(max = 255)
@NotNull @NotNull
@Column(name = "password", nullable = false) @Column(name = "password", nullable = false)
private String password; private String password;
@Size(max = 100)
@Column(name = "email", length = 100)
private String email;
@Size(max = 20) @Size(max = 20)
@ColumnDefault("'INACTIVE'") @ColumnDefault("'INACTIVE'")
@Column(name = "status", length = 20) @Column(name = "status", length = 20)
private String status = "INACTIVE"; private String status = "INACTIVE";
@Column(name = "created_dttm", nullable = false, insertable = false) @NotNull
private ZonedDateTime createdDttm; @ColumnDefault("now()")
@Column(name = "created_dttm", nullable = false)
private ZonedDateTime createdDttm = ZonedDateTime.now();
@Column(name = "updated_dttm", nullable = false, insertable = false) @ColumnDefault("now()")
private ZonedDateTime updatedDttm; @Column(name = "updated_dttm")
private ZonedDateTime updatedDttm = ZonedDateTime.now();
@OneToMany(mappedBy = "memberUuid")
private Set<MemberRoleEntity> tbMemberRoles = new LinkedHashSet<>();
} }

View File

@@ -1,37 +0,0 @@
package com.kamco.cd.kamcoback.postgres.entity;
import jakarta.persistence.Column;
import jakarta.persistence.EmbeddedId;
import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.Table;
import java.time.ZonedDateTime;
import lombok.Getter;
import lombok.Setter;
import org.hibernate.annotations.ColumnDefault;
import org.hibernate.annotations.OnDelete;
import org.hibernate.annotations.OnDeleteAction;
@Getter
@Setter
@Entity
@Table(name = "tb_member_role")
public class MemberRoleEntity {
@EmbeddedId private MemberRoleEntityId id;
@ManyToOne(fetch = FetchType.LAZY, optional = false)
@OnDelete(action = OnDeleteAction.CASCADE)
@JoinColumn(
name = "member_uuid",
referencedColumnName = "uuid",
insertable = false,
updatable = false)
private MemberEntity memberUuid;
@ColumnDefault("now()")
@Column(name = "created_dttm")
private ZonedDateTime createdDttm;
}

View File

@@ -1,47 +0,0 @@
package com.kamco.cd.kamcoback.postgres.entity;
import jakarta.persistence.Column;
import jakarta.persistence.Embeddable;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import java.io.Serializable;
import java.util.Objects;
import java.util.UUID;
import lombok.Getter;
import lombok.Setter;
import org.hibernate.Hibernate;
@Getter
@Setter
@Embeddable
public class MemberRoleEntityId implements Serializable {
private static final long serialVersionUID = 9130416001060414347L;
@NotNull
@Column(name = "member_uuid", nullable = false)
private UUID memberUuid;
@Size(max = 50)
@NotNull
@Column(name = "role_name", nullable = false, length = 50)
private String roleName;
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || Hibernate.getClass(this) != Hibernate.getClass(o)) {
return false;
}
MemberRoleEntityId entity = (MemberRoleEntityId) o;
return Objects.equals(this.memberUuid, entity.memberUuid)
&& Objects.equals(this.roleName, entity.roleName);
}
@Override
public int hashCode() {
return Objects.hash(memberUuid, roleName);
}
}

View File

@@ -1,21 +1,20 @@
package com.kamco.cd.kamcoback.postgres.repository.members; package com.kamco.cd.kamcoback.postgres.repository.members;
import com.kamco.cd.kamcoback.members.dto.MembersDto;
import com.kamco.cd.kamcoback.members.dto.MembersDto.Basic;
import com.kamco.cd.kamcoback.postgres.entity.MemberEntity; import com.kamco.cd.kamcoback.postgres.entity.MemberEntity;
import java.util.Optional; import java.util.Optional;
import java.util.UUID; import java.util.UUID;
import org.springframework.data.domain.Page;
public interface MembersRepositoryCustom { public interface MembersRepositoryCustom {
boolean existsByEmployeeNo(String employeeNo); boolean existsByUserId(String userId);
boolean existsByEmail(String email); Optional<MemberEntity> findByUserId(String employeeNo);
Page<Basic> findByMembers(MembersDto.SearchReq searchReq);
Optional<MemberEntity> findByUUID(UUID uuid); Optional<MemberEntity> findByUUID(UUID uuid);
//
// Page<Basic> findByMembers(MembersDto.SearchReq searchReq);
//
Optional<MemberEntity> findByEmployeeNo(String employeeNo); //
// Optional<MemberEntity> findByEmployeeNo(String employeeNo);
} }

View File

@@ -1,23 +1,11 @@
package com.kamco.cd.kamcoback.postgres.repository.members; package com.kamco.cd.kamcoback.postgres.repository.members;
import com.kamco.cd.kamcoback.common.enums.RoleType;
import com.kamco.cd.kamcoback.members.dto.MembersDto;
import com.kamco.cd.kamcoback.members.dto.MembersDto.Basic;
import com.kamco.cd.kamcoback.postgres.entity.MemberEntity; import com.kamco.cd.kamcoback.postgres.entity.MemberEntity;
import com.kamco.cd.kamcoback.postgres.entity.QMemberEntity; import com.kamco.cd.kamcoback.postgres.entity.QMemberEntity;
import com.kamco.cd.kamcoback.postgres.entity.QMemberRoleEntity;
import com.querydsl.core.BooleanBuilder;
import com.querydsl.core.types.Projections;
import com.querydsl.jpa.impl.JPAQueryFactory; import com.querydsl.jpa.impl.JPAQueryFactory;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.UUID; import java.util.UUID;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Repository; import org.springframework.stereotype.Repository;
@Repository @Repository
@@ -26,130 +14,106 @@ public class MembersRepositoryImpl implements MembersRepositoryCustom {
private final JPAQueryFactory queryFactory; private final JPAQueryFactory queryFactory;
private final QMemberEntity memberEntity = QMemberEntity.memberEntity; private final QMemberEntity memberEntity = QMemberEntity.memberEntity;
private final QMemberRoleEntity memberRoleEntity = QMemberRoleEntity.memberRoleEntity;
/** /**
* 사원번호 조회 * 사용자 ID 조회
* *
* @param employeeNo * @param userId
* @return * @return
*/ */
@Override @Override
public boolean existsByEmployeeNo(String employeeNo) { public boolean existsByUserId(String userId) {
return queryFactory return queryFactory
.selectOne() .selectOne()
.from(memberEntity) .from(memberEntity)
.where(memberEntity.employeeNo.eq(employeeNo)) .where(memberEntity.userId.eq(userId))
.fetchFirst() .fetchFirst()
!= null; != null;
} }
/**
* 이메일 조회
*
* @param email
* @return
*/
@Override @Override
public boolean existsByEmail(String email) { public Optional<MemberEntity> findByUserId(String userId) {
return queryFactory return Optional.ofNullable(
.selectOne() queryFactory.selectFrom(memberEntity).where(memberEntity.userId.eq(userId)).fetchOne());
.from(memberEntity)
.where(memberEntity.email.eq(email))
.fetchFirst()
!= null;
}
/**
* 회원정보 목록 조회
*
* @param searchReq
* @return
*/
@Override
public Page<Basic> findByMembers(MembersDto.SearchReq searchReq) {
Pageable pageable = searchReq.toPageable();
BooleanBuilder builder = new BooleanBuilder();
BooleanBuilder leftBuilder = new BooleanBuilder();
if (StringUtils.isNotBlank(searchReq.getField())) {
switch (searchReq.getField()) {
case "name" ->
builder.and(memberEntity.name.containsIgnoreCase(searchReq.getKeyword().trim()));
case "email" ->
builder.and(memberEntity.email.containsIgnoreCase(searchReq.getKeyword().trim()));
case "employeeNo" ->
builder.and(memberEntity.employeeNo.containsIgnoreCase(searchReq.getKeyword().trim()));
}
}
List<String> roles = new ArrayList<>();
// 라벨러
if (searchReq.isLabeler()) {
roles.add(RoleType.ROLE_LABELER.getId());
}
// 시스템 전체 관리자
if (searchReq.isAdmin()) {
roles.add(RoleType.ROLE_ADMIN.getId());
}
// 검수자
if (searchReq.isReviewer()) {
roles.add(RoleType.ROLE_REVIEWER.getId());
}
// 역할 in 조건 추가
if (!roles.isEmpty()) {
leftBuilder.and(memberRoleEntity.id.roleName.in(roles));
}
List<MembersDto.Basic> content =
queryFactory
.select(
Projections.constructor(
MembersDto.Basic.class,
memberEntity.id,
memberEntity.uuid,
memberEntity.employeeNo,
memberEntity.name,
memberEntity.email,
memberEntity.status,
memberRoleEntity.id.roleName,
memberEntity.createdDttm,
memberEntity.updatedDttm))
.from(memberEntity)
.leftJoin(memberRoleEntity)
.on(memberRoleEntity.memberUuid.uuid.eq(memberEntity.uuid).and(leftBuilder))
.where(builder)
.offset(pageable.getOffset())
.limit(pageable.getPageSize())
.orderBy(memberEntity.createdDttm.desc())
.fetch();
long total =
queryFactory
.select(memberEntity)
.from(memberEntity)
.leftJoin(memberRoleEntity)
.on(memberRoleEntity.memberUuid.uuid.eq(memberEntity.uuid).and(leftBuilder))
.fetchCount();
return new PageImpl<>(content, pageable, total);
} }
// /**
// * 회원정보 목록 조회
// *
// * @param searchReq
// * @return
// */
// @Override
// public Page<Basic> findByMembers(MembersDto.SearchReq searchReq) {
// Pageable pageable = searchReq.toPageable();
// BooleanBuilder builder = new BooleanBuilder();
// BooleanBuilder leftBuilder = new BooleanBuilder();
//
// if (StringUtils.isNotBlank(searchReq.getField())) {
// switch (searchReq.getField()) {
// case "name" ->
// builder.and(memberEntity.name.containsIgnoreCase(searchReq.getKeyword().trim()));
// }
// }
//
// List<String> roles = new ArrayList<>();
// // 라벨러
// if (searchReq.isLabeler()) {
// roles.add(RoleType.ROLE_LABELER.getId());
// }
//
// // 시스템 전체 관리자
// if (searchReq.isAdmin()) {
// roles.add(RoleType.ROLE_ADMIN.getId());
// }
//
// // 검수자
// if (searchReq.isReviewer()) {
// roles.add(RoleType.ROLE_REVIEWER.getId());
// }
//
// // 역할 in 조건 추가
// if (!roles.isEmpty()) {
// leftBuilder.and(memberRoleEntity.id.roleName.in(roles));
// }
//
// List<MembersDto.Basic> content =
// queryFactory
// .select(
// Projections.constructor(
// MembersDto.Basic.class,
// memberEntity.id,
// memberEntity.uuid,
// memberEntity.employeeNo,
// memberEntity.name,
// null,
// memberEntity.status,
// memberRoleEntity.id.roleName,
// memberEntity.createdDttm,
// memberEntity.updatedDttm))
// .from(memberEntity)
// .leftJoin(memberRoleEntity)
// .on(memberRoleEntity.memberUuid.uuid.eq(memberEntity.uuid).and(leftBuilder))
// .where(builder)
// .offset(pageable.getOffset())
// .limit(pageable.getPageSize())
// .orderBy(memberEntity.createdDttm.desc())
// .fetch();
//
// long total =
// queryFactory
// .select(memberEntity)
// .from(memberEntity)
// .leftJoin(memberRoleEntity)
// .on(memberRoleEntity.memberUuid.uuid.eq(memberEntity.uuid).and(leftBuilder))
// .fetchCount();
//
// return new PageImpl<>(content, pageable, total);
// }
//
@Override @Override
public Optional<MemberEntity> findByUUID(UUID uuid) { public Optional<MemberEntity> findByUUID(UUID uuid) {
return Optional.ofNullable( return Optional.ofNullable(
queryFactory.selectFrom(memberEntity).where(memberEntity.uuid.eq(uuid)).fetchOne()); queryFactory.selectFrom(memberEntity).where(memberEntity.uuid.eq(uuid)).fetchOne());
} }
@Override
public Optional<MemberEntity> findByEmployeeNo(String employeeNo) {
return Optional.ofNullable(
queryFactory
.selectFrom(memberEntity)
.where(memberEntity.employeeNo.eq(employeeNo))
.fetchOne());
}
} }

View File

@@ -1,7 +0,0 @@
package com.kamco.cd.kamcoback.postgres.repository.members;
import com.kamco.cd.kamcoback.postgres.entity.MemberRoleEntity;
import org.springframework.data.jpa.repository.JpaRepository;
public interface MembersRoleRepository
extends JpaRepository<MemberRoleEntity, Long>, MembersRoleRepositoryCutom {}

View File

@@ -1,8 +0,0 @@
package com.kamco.cd.kamcoback.postgres.repository.members;
import com.kamco.cd.kamcoback.members.dto.MembersDto;
public interface MembersRoleRepositoryCutom {
boolean findByUuidAndRoleName(MembersDto.RolesDto rolesDto);
}

View File

@@ -1,30 +0,0 @@
package com.kamco.cd.kamcoback.postgres.repository.members;
import com.kamco.cd.kamcoback.members.dto.MembersDto;
import com.kamco.cd.kamcoback.postgres.entity.QMemberRoleEntity;
import com.querydsl.jpa.impl.JPAQueryFactory;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Repository;
@RequiredArgsConstructor
@Repository
public class MembersRoleRepositoryImpl implements MembersRoleRepositoryCutom {
private final JPAQueryFactory queryFactory;
private final QMemberRoleEntity memberRoleEntity = QMemberRoleEntity.memberRoleEntity;
@Override
public boolean findByUuidAndRoleName(MembersDto.RolesDto rolesDto) {
return queryFactory
.select(memberRoleEntity)
.from(memberRoleEntity)
.where(
memberRoleEntity
.id
.memberUuid
.eq(rolesDto.getUuid())
.and(memberRoleEntity.id.roleName.eq(rolesDto.getRoleName())))
.fetchOne()
!= null;
}
}

View File

@@ -45,5 +45,3 @@ token:
refresh-cookie-name: kamco-dev # 개발용 쿠키 이름 refresh-cookie-name: kamco-dev # 개발용 쿠키 이름
refresh-cookie-secure: false # 로컬 http 테스트면 false refresh-cookie-secure: false # 로컬 http 테스트면 false
member:
init_password: kamco1234!

View File

@@ -38,6 +38,4 @@ token:
refresh-cookie-name: kamco-local # 개발용 쿠키 이름 refresh-cookie-name: kamco-local # 개발용 쿠키 이름
refresh-cookie-secure: false # 로컬 http 테스트면 false refresh-cookie-secure: false # 로컬 http 테스트면 false
member:
init_password: kamco1234!

View File

@@ -30,7 +30,5 @@ token:
refresh-cookie-name: kamco # 개발용 쿠키 이름 refresh-cookie-name: kamco # 개발용 쿠키 이름
refresh-cookie-secure: true # 로컬 http 테스트면 false refresh-cookie-secure: true # 로컬 http 테스트면 false
member:
init_password: kamco1234!