Merge branch 'feat/dev_251201' of https://kamco.gitea.gs.dabeeo.com/dabeeo/kamco-dabeeo-backoffice into feat/dev_251201
# Conflicts: # src/main/java/com/kamco/cd/kamcoback/mapsheet/MapSheetMngApiController.java # src/main/java/com/kamco/cd/kamcoback/postgres/entity/MapSheetMngEntity.java # src/main/java/com/kamco/cd/kamcoback/postgres/repository/mapsheet/MapSheetMngRepositoryCustom.java # src/main/java/com/kamco/cd/kamcoback/postgres/repository/mapsheet/MapSheetMngRepositoryImpl.java
This commit is contained in:
@@ -6,7 +6,6 @@ import com.kamco.cd.kamcoback.postgres.core.AuthCoreService;
|
||||
import com.kamco.cd.kamcoback.postgres.entity.UserEntity;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@@ -16,7 +15,6 @@ import org.springframework.transaction.annotation.Transactional;
|
||||
public class AuthService {
|
||||
|
||||
private final AuthCoreService authCoreService;
|
||||
private final PasswordEncoder passwordEncoder;
|
||||
|
||||
/**
|
||||
* 관리자 등록
|
||||
@@ -26,7 +24,6 @@ public class AuthService {
|
||||
*/
|
||||
@Transactional
|
||||
public UserEntity save(AuthDto.SaveReq saveReq) {
|
||||
saveReq.setUserPw(passwordEncoder.encode(saveReq.getUserPw()));
|
||||
return authCoreService.save(saveReq);
|
||||
}
|
||||
|
||||
@@ -38,9 +35,7 @@ public class AuthService {
|
||||
* @return
|
||||
*/
|
||||
public UserEntity update(Long id, AuthDto.SaveReq saveReq) {
|
||||
if (saveReq.getUserPw() != null) {
|
||||
saveReq.setUserPw(passwordEncoder.encode(saveReq.getUserPw()));
|
||||
}
|
||||
if (saveReq.getUserPw() != null) {}
|
||||
return authCoreService.update(id, saveReq);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
package com.kamco.cd.kamcoback.common.utils;
|
||||
|
||||
import com.kamco.cd.kamcoback.common.utils.interfaces.EnumValid;
|
||||
import jakarta.validation.ConstraintValidator;
|
||||
import jakarta.validation.ConstraintValidatorContext;
|
||||
import java.util.Arrays;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class EnumValidator implements ConstraintValidator<EnumValid, String> {
|
||||
|
||||
private Set<String> acceptedValues;
|
||||
|
||||
@Override
|
||||
public void initialize(EnumValid constraintAnnotation) {
|
||||
acceptedValues =
|
||||
Arrays.stream(constraintAnnotation.enumClass().getEnumConstants())
|
||||
.map(Enum::name)
|
||||
.collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValid(String value, ConstraintValidatorContext context) {
|
||||
return value != null && acceptedValues.contains(value);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package com.kamco.cd.kamcoback.common.utils.interfaces;
|
||||
|
||||
import com.kamco.cd.kamcoback.common.utils.EnumValidator;
|
||||
import jakarta.validation.Constraint;
|
||||
import jakarta.validation.Payload;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Target(ElementType.FIELD)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Constraint(validatedBy = EnumValidator.class)
|
||||
public @interface EnumValid {
|
||||
|
||||
String message() default "올바르지 않은 값입니다.";
|
||||
|
||||
Class<?>[] groups() default {};
|
||||
|
||||
Class<? extends Payload>[] payload() default {};
|
||||
|
||||
Class<? extends Enum<?>> enumClass();
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package com.kamco.cd.kamcoback.config;
|
||||
|
||||
import java.security.SecureRandom;
|
||||
import java.util.Base64;
|
||||
|
||||
public class BCryptSaltGenerator {
|
||||
|
||||
public static String generateSaltWithEmployeeNo(String employeeNo) {
|
||||
|
||||
// bcrypt salt는 16바이트(128비트) 필요
|
||||
byte[] randomBytes = new byte[16];
|
||||
new SecureRandom().nextBytes(randomBytes);
|
||||
|
||||
String base64 = Base64.getEncoder().encodeToString(randomBytes);
|
||||
|
||||
// 사번을 포함 (22자 제한 → 잘라내기)
|
||||
String mixedSalt = (employeeNo + base64).substring(0, 22);
|
||||
|
||||
// bcrypt 포맷에 맞게 구성
|
||||
return "$2a$10$" + mixedSalt;
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,7 @@ import com.kamco.cd.kamcoback.config.api.ApiLogFunction;
|
||||
import com.kamco.cd.kamcoback.config.api.ApiResponseDto;
|
||||
import com.kamco.cd.kamcoback.config.api.ApiResponseDto.ApiResponseCode;
|
||||
import com.kamco.cd.kamcoback.log.dto.ErrorLogDto;
|
||||
import com.kamco.cd.kamcoback.members.exception.MemberException;
|
||||
import com.kamco.cd.kamcoback.postgres.entity.ErrorLogEntity;
|
||||
import com.kamco.cd.kamcoback.postgres.repository.log.ErrorLogRepository;
|
||||
import jakarta.persistence.EntityNotFoundException;
|
||||
@@ -226,6 +227,64 @@ public class GlobalExceptionHandler {
|
||||
errorLog.getId());
|
||||
}
|
||||
|
||||
@ResponseStatus(HttpStatus.BAD_REQUEST)
|
||||
@ExceptionHandler(MemberException.DuplicateMemberException.class)
|
||||
public ApiResponseDto<String> handlerDuplicateMemberException(
|
||||
MemberException.DuplicateMemberException e, HttpServletRequest request) {
|
||||
log.warn("[DuplicateMemberException] resource :{} ", e.getMessage());
|
||||
|
||||
String codeName = "";
|
||||
|
||||
switch (e.getField()) {
|
||||
case EMPLOYEE_NO -> {
|
||||
codeName = "DUPLICATE_EMPLOYEEID";
|
||||
}
|
||||
case EMAIL -> {
|
||||
codeName = "DUPLICATE_EMAIL";
|
||||
}
|
||||
default -> {
|
||||
codeName = "DUPLICATE_DATA";
|
||||
}
|
||||
}
|
||||
|
||||
ErrorLogEntity errorLog =
|
||||
saveErrerLogData(
|
||||
request,
|
||||
ApiResponseCode.getCode(codeName),
|
||||
HttpStatus.valueOf("BAD_REQUEST"),
|
||||
ErrorLogDto.LogErrorLevel.WARNING,
|
||||
e.getStackTrace());
|
||||
|
||||
return ApiResponseDto.createException(
|
||||
ApiResponseCode.getCode(codeName),
|
||||
ApiResponseCode.getMessage(codeName),
|
||||
HttpStatus.valueOf("BAD_REQUEST"),
|
||||
errorLog.getId());
|
||||
}
|
||||
|
||||
@ResponseStatus(HttpStatus.BAD_REQUEST)
|
||||
@ExceptionHandler(MemberException.MemberNotFoundException.class)
|
||||
public ApiResponseDto<String> handlerMemberNotFoundException(
|
||||
MemberException.MemberNotFoundException e, HttpServletRequest request) {
|
||||
log.warn("[MemberNotFoundException] resource :{} ", e.getMessage());
|
||||
|
||||
String codeName = "NOT_FOUND_USER";
|
||||
|
||||
ErrorLogEntity errorLog =
|
||||
saveErrerLogData(
|
||||
request,
|
||||
ApiResponseCode.getCode(codeName),
|
||||
HttpStatus.valueOf("BAD_REQUEST"),
|
||||
ErrorLogDto.LogErrorLevel.WARNING,
|
||||
e.getStackTrace());
|
||||
|
||||
return ApiResponseDto.createException(
|
||||
ApiResponseCode.getCode(codeName),
|
||||
ApiResponseCode.getMessage(codeName),
|
||||
HttpStatus.valueOf("BAD_REQUEST"),
|
||||
errorLog.getId());
|
||||
}
|
||||
|
||||
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
|
||||
@ExceptionHandler(RuntimeException.class)
|
||||
public ApiResponseDto<String> handlerRuntimeException(
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
package com.kamco.cd.kamcoback.config;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
|
||||
@Configuration
|
||||
public class PasswordConfig {
|
||||
@Bean
|
||||
public PasswordEncoder passwordEncoder() {
|
||||
// strength 기본값 10, 필요하면 조절 가능
|
||||
return new BCryptPasswordEncoder();
|
||||
}
|
||||
}
|
||||
@@ -2,17 +2,14 @@ package com.kamco.cd.kamcoback.mapsheet.dto;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
|
||||
|
||||
public class FileDto {
|
||||
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@NoArgsConstructor
|
||||
@@ -45,14 +42,13 @@ public class FileDto {
|
||||
private final String lastModified;
|
||||
|
||||
public FolderDto(
|
||||
String folderNm,
|
||||
String parentFolderNm,
|
||||
String parentPath,
|
||||
String fullPath,
|
||||
int depth,
|
||||
long childCnt,
|
||||
String lastModified
|
||||
) {
|
||||
String folderNm,
|
||||
String parentFolderNm,
|
||||
String parentPath,
|
||||
String fullPath,
|
||||
int depth,
|
||||
long childCnt,
|
||||
String lastModified) {
|
||||
this.folderNm = folderNm;
|
||||
this.parentFolderNm = parentFolderNm;
|
||||
this.parentPath = parentPath;
|
||||
@@ -61,7 +57,6 @@ public class FileDto {
|
||||
this.childCnt = childCnt;
|
||||
this.lastModified = lastModified;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Schema(name = "File Basic", description = "파일 기본 정보")
|
||||
@@ -75,12 +70,7 @@ public class FileDto {
|
||||
private final String lastModified;
|
||||
|
||||
public Basic(
|
||||
String fileNm,
|
||||
String filePath,
|
||||
String extension,
|
||||
long fileSize,
|
||||
String lastModified
|
||||
) {
|
||||
String fileNm, String filePath, String extension, long fileSize, String lastModified) {
|
||||
this.fileNm = fileNm;
|
||||
this.filePath = filePath;
|
||||
this.extension = extension;
|
||||
@@ -97,19 +87,12 @@ public class FileDto {
|
||||
private final long fileTotSize;
|
||||
private final List<Basic> files;
|
||||
|
||||
public FilesDto(
|
||||
String dirPath,
|
||||
int fileTotCnt,
|
||||
long fileTotSize,
|
||||
List<Basic> files
|
||||
public FilesDto(String dirPath, int fileTotCnt, long fileTotSize, List<Basic> files) {
|
||||
|
||||
) {
|
||||
this.dirPath = dirPath;
|
||||
this.fileTotCnt = fileTotCnt;
|
||||
this.fileTotSize = fileTotSize;
|
||||
this.files = files;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -10,8 +10,6 @@ import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.domain.Sort;
|
||||
|
||||
import java.time.ZonedDateTime;
|
||||
|
||||
public class MapSheetMngDto {
|
||||
|
||||
@Schema(name = "searchReq", description = "영상관리 오류데이터 검색 요청")
|
||||
@@ -33,7 +31,7 @@ public class MapSheetMngDto {
|
||||
String[] sortParams = sort.split(",");
|
||||
String property = sortParams[0];
|
||||
Sort.Direction direction =
|
||||
sortParams.length > 1 ? Sort.Direction.fromString(sortParams[1]) : Sort.Direction.ASC;
|
||||
sortParams.length > 1 ? Sort.Direction.fromString(sortParams[1]) : Sort.Direction.ASC;
|
||||
return PageRequest.of(page, size, Sort.by(direction, property));
|
||||
}
|
||||
return PageRequest.of(page, size);
|
||||
@@ -45,7 +43,7 @@ public class MapSheetMngDto {
|
||||
@Setter
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public static class ErrorDataDto{
|
||||
public static class ErrorDataDto {
|
||||
private Long hstUid;
|
||||
private Integer rowNum;
|
||||
private String map50kName;
|
||||
|
||||
@@ -5,6 +5,9 @@ import com.kamco.cd.kamcoback.mapsheet.dto.FileDto.FilesDto;
|
||||
import com.kamco.cd.kamcoback.mapsheet.dto.FileDto.FolderDto;
|
||||
import com.kamco.cd.kamcoback.mapsheet.dto.FileDto.SrchFilesDto;
|
||||
import com.kamco.cd.kamcoback.mapsheet.dto.FileDto.SrchFoldersDto;
|
||||
import com.kamco.cd.kamcoback.mapsheet.dto.MapSheetMngDto;
|
||||
import com.kamco.cd.kamcoback.postgres.core.MapSheetMngCoreService;
|
||||
import jakarta.validation.Valid;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
@@ -19,10 +22,6 @@ import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import com.kamco.cd.kamcoback.mapsheet.dto.MapSheetMngDto;
|
||||
import com.kamco.cd.kamcoback.postgres.core.MapSheetMngCoreService;
|
||||
import jakarta.validation.Valid;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.apache.commons.io.FilenameUtils;
|
||||
import org.springframework.data.domain.Page;
|
||||
@@ -46,68 +45,66 @@ public class MapSheetMngService {
|
||||
List<FolderDto> folderDtoList = List.of();
|
||||
SimpleDateFormat dttmFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||
|
||||
|
||||
try (Stream<Path> stream = Files.walk(startPath, maxDepth)) {
|
||||
|
||||
folderDtoList = stream
|
||||
// 1. 디렉토리만 필터링
|
||||
.filter(Files::isDirectory)
|
||||
.filter(p -> !p.toString().equals(dirPath))
|
||||
.map(path -> {
|
||||
folderDtoList =
|
||||
stream
|
||||
// 1. 디렉토리만 필터링
|
||||
.filter(Files::isDirectory)
|
||||
.filter(p -> !p.toString().equals(dirPath))
|
||||
.map(
|
||||
path -> {
|
||||
int depth = path.getNameCount();
|
||||
|
||||
int depth = path.getNameCount();
|
||||
String folderNm = path.getFileName().toString();
|
||||
String parentFolderNm = path.getParent().getFileName().toString();
|
||||
String parentPath = path.getParent().toString();
|
||||
String fullPath = path.toAbsolutePath().toString();
|
||||
|
||||
String folderNm = path.getFileName().toString();
|
||||
String parentFolderNm = path.getParent().getFileName().toString();
|
||||
String parentPath = path.getParent().toString();
|
||||
String fullPath = path.toAbsolutePath().toString();
|
||||
File directory = new File(fullPath);
|
||||
File[] childFolders = directory.listFiles(File::isDirectory);
|
||||
|
||||
File directory = new File(fullPath);
|
||||
File[] childFolders = directory.listFiles(File::isDirectory);
|
||||
long childCnt = 0;
|
||||
if (childFolders != null) {
|
||||
childCnt = childFolders.length;
|
||||
}
|
||||
|
||||
long childCnt = 0;
|
||||
if (childFolders != null) {
|
||||
childCnt = childFolders.length;
|
||||
}
|
||||
FileTime time = null;
|
||||
try {
|
||||
time = Files.getLastModifiedTime(path);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
FileTime time = null;
|
||||
try {
|
||||
time = Files.getLastModifiedTime(path);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
String lastModified = dttmFormat.format(new Date(time.toMillis()));
|
||||
|
||||
String lastModified = dttmFormat.format(new Date(time.toMillis()));
|
||||
FolderDto folderDto =
|
||||
new FolderDto(
|
||||
folderNm,
|
||||
parentFolderNm,
|
||||
parentPath,
|
||||
fullPath,
|
||||
depth,
|
||||
childCnt,
|
||||
lastModified);
|
||||
|
||||
return folderDto;
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
|
||||
FolderDto folderDto = new FolderDto(
|
||||
folderNm,
|
||||
parentFolderNm,
|
||||
parentPath,
|
||||
fullPath,
|
||||
depth,
|
||||
childCnt,
|
||||
lastModified
|
||||
);
|
||||
|
||||
return folderDto;
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
|
||||
folderDtoList.sort(Comparator.comparing(
|
||||
FolderDto::getFolderNm,
|
||||
String.CASE_INSENSITIVE_ORDER // 대소문자 구분 없이
|
||||
).reversed());
|
||||
folderDtoList.sort(
|
||||
Comparator.comparing(
|
||||
FolderDto::getFolderNm, String.CASE_INSENSITIVE_ORDER // 대소문자 구분 없이
|
||||
)
|
||||
.reversed());
|
||||
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
return folderDtoList;
|
||||
|
||||
}
|
||||
|
||||
|
||||
public FilesDto getFilesAll(SrchFilesDto srchDto) {
|
||||
|
||||
String dirPath = srchDto.getDirPath();
|
||||
@@ -125,22 +122,20 @@ public class MapSheetMngService {
|
||||
int fileTotCnt = 0;
|
||||
long fileTotSize = 0;
|
||||
|
||||
if( fileList != null )
|
||||
{
|
||||
if( sortType.equals("name")){
|
||||
if (fileList != null) {
|
||||
if (sortType.equals("name")) {
|
||||
Arrays.sort(fileList);
|
||||
}
|
||||
else if( sortType.equals("date")){
|
||||
} else if (sortType.equals("date")) {
|
||||
Arrays.sort(fileList, Comparator.comparingLong(File::lastModified));
|
||||
}
|
||||
|
||||
for (File file : fileList) {
|
||||
if (file.isFile() ) { // 파일인 경우만
|
||||
if( extension.equals("*") || file.getName().endsWith("."+extension) ) {
|
||||
if (file.isFile()) { // 파일인 경우만
|
||||
if (extension.equals("*") || file.getName().endsWith("." + extension)) {
|
||||
|
||||
fileListPos = fileListPos + 1;
|
||||
|
||||
if( startPos <= fileListPos && endPos >= fileListPos ) {
|
||||
if (startPos <= fileListPos && endPos >= fileListPos) {
|
||||
|
||||
// 생성자를 통해 객체를 만들고 리스트에 추가
|
||||
String fileName = file.getName();
|
||||
@@ -153,28 +148,19 @@ public class MapSheetMngService {
|
||||
|
||||
fileTotCnt = fileTotCnt + 1;
|
||||
fileTotSize = fileTotSize + fileSize;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
FilesDto filesDto = new FilesDto(
|
||||
dirPath,
|
||||
fileTotCnt,
|
||||
fileTotSize,
|
||||
files);
|
||||
|
||||
|
||||
FilesDto filesDto = new FilesDto(dirPath, fileTotCnt, fileTotSize, files);
|
||||
|
||||
return filesDto;
|
||||
|
||||
}
|
||||
|
||||
public Page<MapSheetMngDto.ErrorDataDto> findMapSheetErrorList(MapSheetMngDto.@Valid searchReq searchReq) {
|
||||
public Page<MapSheetMngDto.ErrorDataDto> findMapSheetErrorList(
|
||||
MapSheetMngDto.@Valid searchReq searchReq) {
|
||||
return mapSheetMngCoreService.findMapSheetErrorList(searchReq);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,117 @@
|
||||
package com.kamco.cd.kamcoback.members;
|
||||
|
||||
import com.kamco.cd.kamcoback.config.api.ApiResponseDto;
|
||||
import com.kamco.cd.kamcoback.members.dto.MembersDto;
|
||||
import com.kamco.cd.kamcoback.members.service.AdminService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.media.Content;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import io.swagger.v3.oas.annotations.responses.ApiResponse;
|
||||
import io.swagger.v3.oas.annotations.responses.ApiResponses;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.validation.Valid;
|
||||
import java.util.UUID;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
@Tag(name = "회원정보 관리자 관리", description = "회원정보 관리자 관리 API")
|
||||
@RestController
|
||||
@RequestMapping("/api/admin")
|
||||
@RequiredArgsConstructor
|
||||
public class AdminApiController {
|
||||
|
||||
private final AdminService adminService;
|
||||
|
||||
@Operation(summary = "회원가입", description = "회원가입")
|
||||
@ApiResponses(
|
||||
value = {
|
||||
@ApiResponse(
|
||||
responseCode = "201",
|
||||
description = "회원가입 성공",
|
||||
content =
|
||||
@Content(
|
||||
mediaType = "application/json",
|
||||
schema = @Schema(implementation = Long.class))),
|
||||
@ApiResponse(responseCode = "400", description = "잘못된 요청 데이터", content = @Content),
|
||||
@ApiResponse(responseCode = "404", description = "코드를 찾을 수 없음", content = @Content),
|
||||
@ApiResponse(responseCode = "500", description = "서버 오류", content = @Content)
|
||||
})
|
||||
@PostMapping("/members/join")
|
||||
public ApiResponseDto<Long> saveMember(
|
||||
@io.swagger.v3.oas.annotations.parameters.RequestBody(
|
||||
description = "회원가입",
|
||||
required = true,
|
||||
content =
|
||||
@Content(
|
||||
mediaType = "application/json",
|
||||
schema = @Schema(implementation = MembersDto.AddReq.class)))
|
||||
@RequestBody
|
||||
@Valid
|
||||
MembersDto.AddReq addReq) {
|
||||
|
||||
return ApiResponseDto.createOK(adminService.saveMember(addReq));
|
||||
}
|
||||
|
||||
@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)
|
||||
})
|
||||
@PostMapping("/roles/add")
|
||||
public ApiResponseDto<UUID> saveRoles(
|
||||
@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.saveRoles(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)
|
||||
})
|
||||
@PostMapping("/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());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
package com.kamco.cd.kamcoback.members;
|
||||
|
||||
import com.kamco.cd.kamcoback.config.api.ApiResponseDto;
|
||||
import com.kamco.cd.kamcoback.members.dto.MembersDto;
|
||||
import com.kamco.cd.kamcoback.members.dto.MembersDto.Basic;
|
||||
import com.kamco.cd.kamcoback.members.service.MembersService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.media.Content;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import io.swagger.v3.oas.annotations.responses.ApiResponse;
|
||||
import io.swagger.v3.oas.annotations.responses.ApiResponses;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
@Tag(name = "회원정보 관리", description = "회원정보 관리 API")
|
||||
@RestController
|
||||
@RequestMapping("/api/members")
|
||||
@RequiredArgsConstructor
|
||||
public class MembersApiController {
|
||||
|
||||
private final MembersService membersService;
|
||||
|
||||
@Operation(summary = "회원정보 목록", description = "회원정보 조회")
|
||||
@ApiResponses(
|
||||
value = {
|
||||
@ApiResponse(
|
||||
responseCode = "200",
|
||||
description = "검색 성공",
|
||||
content =
|
||||
@Content(
|
||||
mediaType = "application/json",
|
||||
schema = @Schema(implementation = Page.class))),
|
||||
@ApiResponse(responseCode = "400", description = "잘못된 검색 조건", content = @Content),
|
||||
@ApiResponse(responseCode = "500", description = "서버 오류", content = @Content)
|
||||
})
|
||||
@PostMapping("/list")
|
||||
public ApiResponseDto<Page<Basic>> getMemberList(@RequestBody MembersDto.SearchReq searchReq) {
|
||||
return ApiResponseDto.ok(membersService.findByMembers(searchReq));
|
||||
}
|
||||
}
|
||||
133
src/main/java/com/kamco/cd/kamcoback/members/dto/MembersDto.java
Normal file
133
src/main/java/com/kamco/cd/kamcoback/members/dto/MembersDto.java
Normal file
@@ -0,0 +1,133 @@
|
||||
package com.kamco.cd.kamcoback.members.dto;
|
||||
|
||||
import com.kamco.cd.kamcoback.common.utils.interfaces.EnumValid;
|
||||
import com.kamco.cd.kamcoback.common.utils.interfaces.JsonFormatDttm;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.Size;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.util.UUID;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
|
||||
public class MembersDto {
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
public static class Basic {
|
||||
|
||||
private Long id;
|
||||
private UUID uuid;
|
||||
private String employeeNo;
|
||||
private String name;
|
||||
private String email;
|
||||
private String status;
|
||||
private String roleName;
|
||||
@JsonFormatDttm private ZonedDateTime createdDttm;
|
||||
@JsonFormatDttm private ZonedDateTime updatedDttm;
|
||||
|
||||
public Basic(
|
||||
Long id,
|
||||
UUID uuid,
|
||||
String employeeNo,
|
||||
String name,
|
||||
String email,
|
||||
String status,
|
||||
String roleName,
|
||||
ZonedDateTime createdDttm,
|
||||
ZonedDateTime updatedDttm) {
|
||||
this.id = id;
|
||||
this.uuid = uuid;
|
||||
this.employeeNo = employeeNo;
|
||||
this.name = name;
|
||||
this.email = email;
|
||||
this.status = status;
|
||||
this.roleName = roleName;
|
||||
this.createdDttm = createdDttm;
|
||||
this.updatedDttm = updatedDttm;
|
||||
}
|
||||
}
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public static class SearchReq {
|
||||
|
||||
@Schema(description = "이름(name), 이메일(email), 사번(employeeNo)", example = "name")
|
||||
private String field;
|
||||
|
||||
@Schema(description = "키워드", example = "홍길동")
|
||||
private String keyword;
|
||||
|
||||
@Schema(description = "라벨러 포함 여부", example = "true")
|
||||
private boolean labeler = true;
|
||||
|
||||
@Schema(description = "검수자 포함 여부", example = "true")
|
||||
private boolean reviewer = true;
|
||||
|
||||
@Schema(description = "운영자 포함 여부", example = "true")
|
||||
private boolean admin = true;
|
||||
|
||||
// 페이징 파라미터
|
||||
@Schema(description = "페이지 번호 (0부터 시작) ", example = "0")
|
||||
private int page = 0;
|
||||
|
||||
@Schema(description = "페이지 크기", example = "20")
|
||||
private int size = 20;
|
||||
|
||||
public Pageable toPageable() {
|
||||
return PageRequest.of(page, size);
|
||||
}
|
||||
}
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
public static class AddReq {
|
||||
|
||||
@Schema(description = "사번", example = "11111")
|
||||
@NotBlank
|
||||
@Size(max = 50)
|
||||
private String employeeNo;
|
||||
|
||||
@Schema(description = "이름", example = "홍길동")
|
||||
@NotBlank
|
||||
@Size(min = 2, max = 100)
|
||||
private String name;
|
||||
|
||||
@Schema(description = "패스워드", example = "")
|
||||
@NotBlank
|
||||
@Size(max = 255)
|
||||
private String password;
|
||||
|
||||
@Schema(description = "이메일", example = "gildong@daum.net")
|
||||
@Size(max = 100)
|
||||
private String email;
|
||||
|
||||
public AddReq(String employeeNo, String name, String password, String email) {
|
||||
this.employeeNo = employeeNo;
|
||||
this.name = name;
|
||||
this.password = password;
|
||||
this.email = email;
|
||||
}
|
||||
}
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
public static class RolesDto {
|
||||
|
||||
private UUID uuid;
|
||||
|
||||
@EnumValid(enumClass = RoleType.class)
|
||||
private String roleName;
|
||||
|
||||
public RolesDto(UUID uuid, String roleName) {
|
||||
this.uuid = uuid;
|
||||
this.roleName = roleName;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package com.kamco.cd.kamcoback.members.dto;
|
||||
|
||||
import com.kamco.cd.kamcoback.config.enums.EnumType;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum RoleType implements EnumType {
|
||||
ROLE_ADMIN("시스템 관리자"),
|
||||
ROLE_LABELER("라벨러"),
|
||||
ROLE_REVIEWER("검수자");
|
||||
|
||||
private final String desc;
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return name();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getText() {
|
||||
return desc;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package com.kamco.cd.kamcoback.members.exception;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
public class MemberException {
|
||||
|
||||
// *** Duplicate Member Exception ***
|
||||
@Getter
|
||||
public static class DuplicateMemberException extends RuntimeException {
|
||||
|
||||
public enum Field {
|
||||
EMPLOYEE_NO,
|
||||
EMAIL,
|
||||
DEFAULT
|
||||
}
|
||||
|
||||
private final Field field;
|
||||
private final String value;
|
||||
|
||||
public DuplicateMemberException(Field field, String value) {
|
||||
super(field.name() + " duplicate: " + value);
|
||||
this.field = field;
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
|
||||
// *** Member Not Found Exception ***
|
||||
public static class MemberNotFoundException extends RuntimeException {
|
||||
|
||||
public MemberNotFoundException() {
|
||||
super("Member not found");
|
||||
}
|
||||
|
||||
public MemberNotFoundException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
package com.kamco.cd.kamcoback.members.service;
|
||||
|
||||
import com.kamco.cd.kamcoback.config.BCryptSaltGenerator;
|
||||
import com.kamco.cd.kamcoback.members.dto.MembersDto;
|
||||
import com.kamco.cd.kamcoback.postgres.core.MembersCoreService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.mindrot.jbcrypt.BCrypt;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@Service
|
||||
@Transactional(readOnly = true)
|
||||
@RequiredArgsConstructor
|
||||
public class AdminService {
|
||||
|
||||
private final MembersCoreService membersCoreService;
|
||||
|
||||
/**
|
||||
* 회원가입
|
||||
*
|
||||
* @param addReq
|
||||
* @return
|
||||
*/
|
||||
@Transactional
|
||||
public Long saveMember(MembersDto.AddReq addReq) {
|
||||
// salt 생성
|
||||
String salt = BCryptSaltGenerator.generateSaltWithEmployeeNo(addReq.getEmployeeNo());
|
||||
|
||||
// 패스워드 암호화
|
||||
String hashedPassword = BCrypt.hashpw(addReq.getPassword(), salt);
|
||||
addReq.setPassword(hashedPassword);
|
||||
return membersCoreService.saveMembers(addReq);
|
||||
}
|
||||
|
||||
/**
|
||||
* 역할 추가
|
||||
*
|
||||
* @param rolesDto
|
||||
*/
|
||||
@Transactional
|
||||
public void saveRoles(MembersDto.RolesDto rolesDto) {
|
||||
membersCoreService.saveRoles(rolesDto);
|
||||
}
|
||||
|
||||
/**
|
||||
* 역할 삭제
|
||||
*
|
||||
* @param rolesDto
|
||||
*/
|
||||
public void deleteRoles(MembersDto.RolesDto rolesDto) {
|
||||
membersCoreService.deleteRoles(rolesDto);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package com.kamco.cd.kamcoback.members.service;
|
||||
|
||||
import com.kamco.cd.kamcoback.members.dto.MembersDto;
|
||||
import com.kamco.cd.kamcoback.members.dto.MembersDto.Basic;
|
||||
import com.kamco.cd.kamcoback.postgres.core.MembersCoreService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@Service
|
||||
@Transactional(readOnly = true)
|
||||
@RequiredArgsConstructor
|
||||
public class MembersService {
|
||||
|
||||
private final MembersCoreService membersCoreService;
|
||||
|
||||
/**
|
||||
* 회원목록 조회
|
||||
*
|
||||
* @param searchReq
|
||||
* @return
|
||||
*/
|
||||
public Page<Basic> findByMembers(MembersDto.SearchReq searchReq) {
|
||||
return membersCoreService.findByMembers(searchReq);
|
||||
}
|
||||
}
|
||||
@@ -7,15 +7,14 @@ import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class MapSheetMngCoreService {
|
||||
|
||||
private final MapSheetMngRepository mapSheetMngRepository;
|
||||
|
||||
public Page<MapSheetMngDto.ErrorDataDto> findMapSheetErrorList(MapSheetMngDto.@Valid searchReq searchReq) {
|
||||
public Page<MapSheetMngDto.ErrorDataDto> findMapSheetErrorList(
|
||||
MapSheetMngDto.@Valid searchReq searchReq) {
|
||||
return mapSheetMngRepository.findMapSheetErrorList(searchReq);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,108 @@
|
||||
package com.kamco.cd.kamcoback.postgres.core;
|
||||
|
||||
import com.kamco.cd.kamcoback.members.dto.MembersDto;
|
||||
import com.kamco.cd.kamcoback.members.exception.MemberException;
|
||||
import com.kamco.cd.kamcoback.members.exception.MemberException.MemberNotFoundException;
|
||||
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.MembersRepository;
|
||||
import com.kamco.cd.kamcoback.postgres.repository.members.MembersRoleRepository;
|
||||
import java.time.ZonedDateTime;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class MembersCoreService {
|
||||
|
||||
private final MembersRepository membersRepository;
|
||||
private final MembersRoleRepository memberRoleRepository;
|
||||
|
||||
/**
|
||||
* 회원가입
|
||||
*
|
||||
* @param addReq
|
||||
* @return
|
||||
*/
|
||||
public Long saveMembers(MembersDto.AddReq addReq) {
|
||||
if (membersRepository.findByEmployeeNo(addReq.getEmployeeNo())) {
|
||||
throw new MemberException.DuplicateMemberException(
|
||||
MemberException.DuplicateMemberException.Field.EMPLOYEE_NO, addReq.getEmployeeNo());
|
||||
}
|
||||
|
||||
if (membersRepository.findByEmail(addReq.getEmail())) {
|
||||
throw new MemberException.DuplicateMemberException(
|
||||
MemberException.DuplicateMemberException.Field.EMAIL, addReq.getEmail());
|
||||
}
|
||||
|
||||
MemberEntity memberEntity = new MemberEntity();
|
||||
memberEntity.setEmployeeNo(addReq.getEmployeeNo());
|
||||
memberEntity.setName(addReq.getName());
|
||||
memberEntity.setPassword(addReq.getPassword());
|
||||
memberEntity.setEmail(addReq.getEmail());
|
||||
|
||||
return membersRepository.save(memberEntity).getId();
|
||||
}
|
||||
|
||||
/**
|
||||
* 역할 추가
|
||||
*
|
||||
* @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 searchReq
|
||||
* @return
|
||||
*/
|
||||
public Page<MembersDto.Basic> findByMembers(MembersDto.SearchReq searchReq) {
|
||||
return membersRepository.findByMembers(searchReq);
|
||||
}
|
||||
}
|
||||
@@ -3,11 +3,10 @@ package com.kamco.cd.kamcoback.postgres.entity;
|
||||
import com.kamco.cd.kamcoback.mapsheet.dto.MapSheetMngDto;
|
||||
import com.kamco.cd.kamcoback.postgres.CommonDateEntity;
|
||||
import jakarta.persistence.*;
|
||||
import java.time.ZonedDateTime;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.time.ZonedDateTime;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@Entity
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
package com.kamco.cd.kamcoback.postgres.entity;
|
||||
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.Table;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import jakarta.validation.constraints.Size;
|
||||
import java.time.OffsetDateTime;
|
||||
import java.util.UUID;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.hibernate.annotations.ColumnDefault;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@Entity
|
||||
@Table(name = "tb_member_archived")
|
||||
public class MemberArchivedEntity {
|
||||
|
||||
@Id
|
||||
@Column(name = "uuid", nullable = false)
|
||||
private UUID id;
|
||||
|
||||
@NotNull
|
||||
@Column(name = "id", nullable = false)
|
||||
private Long id1;
|
||||
|
||||
@Size(max = 50)
|
||||
@Column(name = "employee_no", length = 50)
|
||||
private String employeeNo;
|
||||
|
||||
@Size(max = 100)
|
||||
@NotNull
|
||||
@Column(name = "name", nullable = false, length = 100)
|
||||
private String name;
|
||||
|
||||
@Size(max = 255)
|
||||
@NotNull
|
||||
@Column(name = "password", nullable = false)
|
||||
private String password;
|
||||
|
||||
@Size(max = 100)
|
||||
@NotNull
|
||||
@Column(name = "email", nullable = false, length = 100)
|
||||
private String email;
|
||||
|
||||
@Size(max = 20)
|
||||
@Column(name = "status", length = 20)
|
||||
private String status;
|
||||
|
||||
@NotNull
|
||||
@Column(name = "created_dttm", nullable = false)
|
||||
private OffsetDateTime createdDttm;
|
||||
|
||||
@NotNull
|
||||
@ColumnDefault("now()")
|
||||
@Column(name = "archived_dttm", nullable = false)
|
||||
private OffsetDateTime archivedDttm;
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
package com.kamco.cd.kamcoback.postgres.entity;
|
||||
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.GeneratedValue;
|
||||
import jakarta.persistence.GenerationType;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.OneToMany;
|
||||
import jakarta.persistence.Table;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import jakarta.validation.constraints.Size;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.hibernate.annotations.ColumnDefault;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@Entity
|
||||
@Table(name = "tb_member")
|
||||
public class MemberEntity {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
@Column(name = "id", nullable = false)
|
||||
private Long id;
|
||||
|
||||
@Column(name = "uuid", nullable = false, insertable = false)
|
||||
private UUID uuid;
|
||||
|
||||
@Size(max = 50)
|
||||
@Column(name = "employee_no", length = 50)
|
||||
private String employeeNo;
|
||||
|
||||
@Size(max = 100)
|
||||
@NotNull
|
||||
@Column(name = "name", nullable = false, length = 100)
|
||||
private String name;
|
||||
|
||||
@Size(max = 255)
|
||||
@NotNull
|
||||
@Column(name = "password", nullable = false)
|
||||
private String password;
|
||||
|
||||
@Size(max = 100)
|
||||
@Column(name = "email", length = 100)
|
||||
private String email;
|
||||
|
||||
@Size(max = 20)
|
||||
@ColumnDefault("'ACTIVE'")
|
||||
@Column(name = "status", length = 20)
|
||||
private String status = "ACTIVE";
|
||||
|
||||
@Column(name = "created_dttm", nullable = false, insertable = false)
|
||||
private ZonedDateTime createdDttm;
|
||||
|
||||
@Column(name = "updated_dttm", nullable = false, insertable = false)
|
||||
private ZonedDateTime updatedDttm;
|
||||
|
||||
@OneToMany(mappedBy = "memberUuid")
|
||||
private Set<MemberRoleEntity> tbMemberRoles = new LinkedHashSet<>();
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
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;
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -3,4 +3,5 @@ package com.kamco.cd.kamcoback.postgres.repository.mapsheet;
|
||||
import com.kamco.cd.kamcoback.postgres.entity.MapSheetMngEntity;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
|
||||
public interface MapSheetMngRepository extends JpaRepository<MapSheetMngEntity, Long>, MapSheetMngRepositoryCustom {}
|
||||
public interface MapSheetMngRepository
|
||||
extends JpaRepository<MapSheetMngEntity, Long>, MapSheetMngRepositoryCustom {}
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
package com.kamco.cd.kamcoback.postgres.repository.members;
|
||||
|
||||
import com.kamco.cd.kamcoback.postgres.entity.MemberEntity;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
|
||||
public interface MembersRepository
|
||||
extends JpaRepository<MemberEntity, Long>, MembersRepositoryCustom {}
|
||||
@@ -0,0 +1,19 @@
|
||||
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 java.util.Optional;
|
||||
import java.util.UUID;
|
||||
import org.springframework.data.domain.Page;
|
||||
|
||||
public interface MembersRepositoryCustom {
|
||||
|
||||
boolean findByEmployeeNo(String employeeNo);
|
||||
|
||||
boolean findByEmail(String email);
|
||||
|
||||
Page<Basic> findByMembers(MembersDto.SearchReq searchReq);
|
||||
|
||||
Optional<MemberEntity> findByUUID(UUID uuid);
|
||||
}
|
||||
@@ -0,0 +1,145 @@
|
||||
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.members.dto.RoleType;
|
||||
import com.kamco.cd.kamcoback.postgres.entity.MemberEntity;
|
||||
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 java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.PageImpl;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
@Repository
|
||||
@RequiredArgsConstructor
|
||||
public class MembersRepositoryImpl implements MembersRepositoryCustom {
|
||||
|
||||
private final JPAQueryFactory queryFactory;
|
||||
private final QMemberEntity memberEntity = QMemberEntity.memberEntity;
|
||||
private final QMemberRoleEntity memberRoleEntity = QMemberRoleEntity.memberRoleEntity;
|
||||
|
||||
/**
|
||||
* 사원번호 조회
|
||||
*
|
||||
* @param employeeNo
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public boolean findByEmployeeNo(String employeeNo) {
|
||||
return queryFactory
|
||||
.selectOne()
|
||||
.from(memberEntity)
|
||||
.where(memberEntity.employeeNo.eq(employeeNo))
|
||||
.fetchFirst()
|
||||
!= null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 이메일 조회
|
||||
*
|
||||
* @param email
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public boolean findByEmail(String email) {
|
||||
return queryFactory
|
||||
.selectOne()
|
||||
.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 (searchReq.getField() != null && !searchReq.getField().isEmpty()) {
|
||||
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);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<MemberEntity> findByUUID(UUID uuid) {
|
||||
return Optional.ofNullable(
|
||||
queryFactory.selectFrom(memberEntity).where(memberEntity.uuid.eq(uuid)).fetchOne());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
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 {}
|
||||
@@ -0,0 +1,8 @@
|
||||
package com.kamco.cd.kamcoback.postgres.repository.members;
|
||||
|
||||
import com.kamco.cd.kamcoback.members.dto.MembersDto;
|
||||
|
||||
public interface MembersRoleRepositoryCutom {
|
||||
|
||||
boolean findByUuidAndRoleName(MembersDto.RolesDto rolesDto);
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
Binary file not shown.
BIN
src/main/resources/db/migration/dump-kamco_cds-202512021838.tar
Normal file
BIN
src/main/resources/db/migration/dump-kamco_cds-202512021838.tar
Normal file
Binary file not shown.
Binary file not shown.
@@ -1 +0,0 @@
|
||||
UTF-8
|
||||
Binary file not shown.
File diff suppressed because one or more lines are too long
@@ -1 +0,0 @@
|
||||
PROJCS["KGD2002_Central_Belt_2010",GEOGCS["GCS_KGD2002",DATUM["D_Korea_Geodetic_Datum_2002",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",200000.0],PARAMETER["False_Northing",600000.0],PARAMETER["Central_Meridian",127.0],PARAMETER["Scale_Factor",1.0],PARAMETER["Latitude_Of_Origin",38.0],UNIT["Meter",1.0]]
|
||||
Binary file not shown.
Binary file not shown.
@@ -1 +0,0 @@
|
||||
UTF-8
|
||||
Binary file not shown.
File diff suppressed because one or more lines are too long
@@ -1 +0,0 @@
|
||||
PROJCS["KGD2002_Central_Belt_2010",GEOGCS["GCS_KGD2002",DATUM["D_Korea_Geodetic_Datum_2002",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",200000.0],PARAMETER["False_Northing",600000.0],PARAMETER["Central_Meridian",127.0],PARAMETER["Scale_Factor",1.0],PARAMETER["Latitude_Of_Origin",38.0],UNIT["Meter",1.0]]
|
||||
Binary file not shown.
Binary file not shown.
@@ -1 +0,0 @@
|
||||
CP949
|
||||
Binary file not shown.
@@ -1 +0,0 @@
|
||||
PROJCS["Korea_2000_Korea_Unified_Coordinate_System",GEOGCS["GCS_Korea_2000",DATUM["D_Korea_2000",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",1000000.0],PARAMETER["False_Northing",2000000.0],PARAMETER["Central_Meridian",127.5],PARAMETER["Scale_Factor",0.9996],PARAMETER["Latitude_Of_Origin",38.0],UNIT["Meter",1.0]]
|
||||
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user