코드 컨벤션 적용

This commit is contained in:
2025-11-20 14:52:15 +09:00
parent 107bd6b20f
commit 2f19325ba7
33 changed files with 1031 additions and 852 deletions

View File

@@ -30,19 +30,19 @@ public class CommonCodeApiController {
private final CommonCodeService commonCodeService; private final CommonCodeService commonCodeService;
@Operation(summary = "목록 조회", description = "모든 공통코드 조회") @Operation(summary = "목록 조회", description = "모든 공통코드 조회")
@ApiResponses( @ApiResponses(
value = { value = {
@ApiResponse( @ApiResponse(
responseCode = "200", responseCode = "200",
description = "조회 성공", description = "조회 성공",
content = content =
@Content( @Content(
mediaType = "application/json", mediaType = "application/json",
schema = @Schema(implementation = CommonCodeDto.Basic.class))), schema = @Schema(implementation = CommonCodeDto.Basic.class))),
@ApiResponse(responseCode = "404", description = "코드를 찾을 수 없음", content = @Content), @ApiResponse(responseCode = "404", description = "코드를 찾을 수 없음", content = @Content),
@ApiResponse(responseCode = "500", description = "서버 오류", content = @Content) @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content)
}) })
@GetMapping @GetMapping
public ApiResponseDto<List<CommonCodeDto.Basic>> getFindAll() { public ApiResponseDto<List<CommonCodeDto.Basic>> getFindAll() {
return ApiResponseDto.createOK(commonCodeService.getFindAll()); return ApiResponseDto.createOK(commonCodeService.getFindAll());
@@ -50,139 +50,160 @@ public class CommonCodeApiController {
@Operation(summary = "단건 조회", description = "단건 조회") @Operation(summary = "단건 조회", description = "단건 조회")
@ApiResponses( @ApiResponses(
value = { value = {
@ApiResponse( @ApiResponse(
responseCode = "200", responseCode = "200",
description = "조회 성공", description = "조회 성공",
content = content =
@Content( @Content(
mediaType = "application/json", mediaType = "application/json",
schema = @Schema(implementation = CommonCodeDto.Basic.class))), schema = @Schema(implementation = CommonCodeDto.Basic.class))),
@ApiResponse(responseCode = "404", description = "코드를 찾을 수 없음", content = @Content), @ApiResponse(responseCode = "404", description = "코드를 찾을 수 없음", content = @Content),
@ApiResponse(responseCode = "500", description = "서버 오류", content = @Content) @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content)
}) })
@GetMapping("/{id}") @GetMapping("/{id}")
public ApiResponseDto<CommonCodeDto.Basic> getOneById( public ApiResponseDto<CommonCodeDto.Basic> getOneById(
@io.swagger.v3.oas.annotations.parameters.RequestBody( @io.swagger.v3.oas.annotations.parameters.RequestBody(description = "단건 조회", required = true)
description = "단건 조회", @PathVariable
required = true) Long id) {
@PathVariable Long id) {
return ApiResponseDto.ok(commonCodeService.getOneById(id)); return ApiResponseDto.ok(commonCodeService.getOneById(id));
} }
@Operation(summary = "저장", description = "공통코드를 저장 합니다.") @Operation(summary = "저장", description = "공통코드를 저장 합니다.")
@ApiResponses( @ApiResponses(
value = { value = {
@ApiResponse(responseCode = "201", description = "공통코드 저장 성공", content = @ApiResponse(
@Content( responseCode = "201",
mediaType = "application/json", description = "공통코드 저장 성공",
schema = @Schema(implementation = Long.class))), content =
@ApiResponse(responseCode = "400", description = "잘못된 요청 데이터", content = @Content), @Content(
@ApiResponse(responseCode = "404", description = "코드를 찾을 수 없음", content = @Content), mediaType = "application/json",
@ApiResponse(responseCode = "500", description = "서버 오류", content = @Content) schema = @Schema(implementation = Long.class))),
}) @ApiResponse(responseCode = "400", description = "잘못된 요청 데이터", content = @Content),
@ApiResponse(responseCode = "404", description = "코드를 찾을 수 없음", content = @Content),
@ApiResponse(responseCode = "500", description = "서버 오류", content = @Content)
})
@PostMapping @PostMapping
public ApiResponseDto<Long> save( public ApiResponseDto<Long> save(
@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 = CommonCodeDto.AddReq.class))) schema = @Schema(implementation = CommonCodeDto.AddReq.class)))
@RequestBody @RequestBody
@Valid CommonCodeDto.AddReq req) { @Valid
CommonCodeDto.AddReq req) {
return ApiResponseDto.createOK(commonCodeService.save(req)); return ApiResponseDto.createOK(commonCodeService.save(req));
} }
@Operation(summary = "수정", description = "공통코드를 수정 합니다.") @Operation(summary = "수정", description = "공통코드를 수정 합니다.")
@ApiResponses( @ApiResponses(
value = { value = {
@ApiResponse(responseCode = "204", description = "공통코드 수정 성공", content = @ApiResponse(
@Content( responseCode = "204",
mediaType = "application/json", description = "공통코드 수정 성공",
schema = @Schema(implementation = Long.class))), content =
@ApiResponse(responseCode = "400", description = "잘못된 요청 데이터", content = @Content), @Content(
@ApiResponse(responseCode = "404", description = "코드를 찾을 수 없음", content = @Content), mediaType = "application/json",
@ApiResponse(responseCode = "500", description = "서버 오류", content = @Content) schema = @Schema(implementation = Long.class))),
}) @ApiResponse(responseCode = "400", description = "잘못된 요청 데이터", content = @Content),
@ApiResponse(responseCode = "404", description = "코드를 찾을 수 없음", content = @Content),
@ApiResponse(responseCode = "500", description = "서버 오류", content = @Content)
})
@PutMapping("/{id}") @PutMapping("/{id}")
public ApiResponseDto<Void> update( public ApiResponseDto<Void> update(
@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 = CommonCodeDto.ModifyReq.class))) schema = @Schema(implementation = CommonCodeDto.ModifyReq.class)))
@PathVariable Long id, @RequestBody @Valid CommonCodeDto.ModifyReq req) { @PathVariable
Long id,
@RequestBody @Valid CommonCodeDto.ModifyReq req) {
commonCodeService.update(id, req); commonCodeService.update(id, req);
return ApiResponseDto.deleteOk(null); return ApiResponseDto.deleteOk(null);
} }
@Operation(summary = "삭제", description = "공통코드를 삭제 합니다.") @Operation(summary = "삭제", description = "공통코드를 삭제 합니다.")
@ApiResponses( @ApiResponses(
value = { value = {
@ApiResponse(responseCode = "204", description = "공통코드 삭제 성공", content = @ApiResponse(
@Content( responseCode = "204",
mediaType = "application/json", description = "공통코드 삭제 성공",
schema = @Schema(implementation = Long.class))), content =
@ApiResponse(responseCode = "400", description = "잘못된 요청 데이터", content = @Content), @Content(
@ApiResponse(responseCode = "404", description = "코드를 찾을 수 없음", content = @Content), mediaType = "application/json",
@ApiResponse(responseCode = "500", description = "서버 오류", content = @Content) schema = @Schema(implementation = Long.class))),
}) @ApiResponse(responseCode = "400", description = "잘못된 요청 데이터", content = @Content),
@ApiResponse(responseCode = "404", description = "코드를 찾을 수 없음", content = @Content),
@ApiResponse(responseCode = "500", description = "서버 오류", content = @Content)
})
@DeleteMapping("/{id}") @DeleteMapping("/{id}")
public ApiResponseDto<Long> remove( public ApiResponseDto<Long> remove(
@io.swagger.v3.oas.annotations.parameters.RequestBody( @io.swagger.v3.oas.annotations.parameters.RequestBody(
description = "공통코드 삭제 요청 정보", description = "공통코드 삭제 요청 정보",
required = true) required = true)
@PathVariable Long id) { @PathVariable
commonCodeService.remove(id); Long id) {
commonCodeService.remove(id);
return ApiResponseDto.deleteOk(id); return ApiResponseDto.deleteOk(id);
} }
@Operation(summary = "순서 변경", description = "공통코드 순서를 변경 합니다.") @Operation(summary = "순서 변경", description = "공통코드 순서를 변경 합니다.")
@ApiResponses( @ApiResponses(
value = { value = {
@ApiResponse(responseCode = "204", description = "공통코드 순서 변경 성공", content = @ApiResponse(
@Content( responseCode = "204",
mediaType = "application/json", description = "공통코드 순서 변경 성공",
schema = @Schema(implementation = Long.class))), content =
@ApiResponse(responseCode = "400", description = "잘못된 요청 데이터", content = @Content), @Content(
@ApiResponse(responseCode = "404", description = "코드를 찾을 수 없음", content = @Content), mediaType = "application/json",
@ApiResponse(responseCode = "500", description = "서버 오류", content = @Content) schema = @Schema(implementation = Long.class))),
}) @ApiResponse(responseCode = "400", description = "잘못된 요청 데이터", content = @Content),
@ApiResponse(responseCode = "404", description = "코드를 찾을 수 없음", content = @Content),
@ApiResponse(responseCode = "500", description = "서버 오류", content = @Content)
})
@PutMapping("/order") @PutMapping("/order")
public ApiResponseDto<Void> updateOrder( public ApiResponseDto<Void> updateOrder(
@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 = CommonCodeDto.OrderReq.class))) schema = @Schema(implementation = CommonCodeDto.OrderReq.class)))
@RequestBody @Valid CommonCodeDto.OrderReq req) { @RequestBody
commonCodeService.updateOrder(req); @Valid
CommonCodeDto.OrderReq req) {
commonCodeService.updateOrder(req);
return ApiResponseDto.deleteOk(null); return ApiResponseDto.deleteOk(null);
} }
@Operation(summary = "code 기반 조회", description = "code 기반 조회") @Operation(summary = "code 기반 조회", description = "code 기반 조회")
@ApiResponses( @ApiResponses(
value = { value = {
@ApiResponse(responseCode = "200", description = "공통코드 순서 변경 성공", content = @ApiResponse(
@Content( responseCode = "200",
mediaType = "application/json", description = "공통코드 순서 변경 성공",
schema = @Schema(implementation = Long.class))), content =
@ApiResponse(responseCode = "400", description = "잘못된 요청 데이터", content = @Content), @Content(
@ApiResponse(responseCode = "404", description = "코드를 찾을 수 없음", content = @Content), mediaType = "application/json",
@ApiResponse(responseCode = "500", description = "서버 오류", content = @Content) schema = @Schema(implementation = Long.class))),
}) @ApiResponse(responseCode = "400", description = "잘못된 요청 데이터", content = @Content),
@ApiResponse(responseCode = "404", description = "코드를 찾을 수 없음", content = @Content),
@ApiResponse(responseCode = "500", description = "서버 오류", content = @Content)
})
@GetMapping("/used") @GetMapping("/used")
public ApiResponseDto<List<CommonCodeDto.Basic>> getByCode( public ApiResponseDto<List<CommonCodeDto.Basic>> getByCode(
@io.swagger.v3.oas.annotations.parameters.RequestBody( @io.swagger.v3.oas.annotations.parameters.RequestBody(
description = "공통코드 순서변경 요청 정보", description = "공통코드 순서변경 요청 정보",
required = true) required = true)
@RequestParam String code) { @RequestParam
String code) {
return ApiResponseDto.ok(commonCodeService.findByCode(code)); return ApiResponseDto.ok(commonCodeService.findByCode(code));
} }
} }

View File

@@ -1,13 +1,10 @@
package com.kamco.cd.kamcoback.code.dto; package com.kamco.cd.kamcoback.code.dto;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.kamco.cd.kamcoback.common.utils.interfaces.JsonFormatDttm; import com.kamco.cd.kamcoback.common.utils.interfaces.JsonFormatDttm;
import com.kamco.cd.kamcoback.postgres.entity.CommonCodeEntity;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.Valid; import jakarta.validation.Valid;
import jakarta.validation.constraints.NotEmpty; import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.PositiveOrZero;
import java.time.ZonedDateTime; import java.time.ZonedDateTime;
import java.util.List; import java.util.List;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
@@ -15,7 +12,6 @@ import lombok.Getter;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import lombok.Setter; import lombok.Setter;
public class CommonCodeDto { public class CommonCodeDto {
@Schema(name = "CodeAddReq", description = "공통코드 저장 정보") @Schema(name = "CodeAddReq", description = "공통코드 저장 정보")
@@ -25,10 +21,8 @@ public class CommonCodeDto {
@AllArgsConstructor @AllArgsConstructor
public static class AddReq { public static class AddReq {
@NotEmpty @NotEmpty private String code;
private String code; @NotEmpty private String name;
@NotEmpty
private String name;
private String description; private String description;
private int order; private int order;
private boolean used; private boolean used;
@@ -41,8 +35,7 @@ public class CommonCodeDto {
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
public static class ModifyReq { public static class ModifyReq {
@NotEmpty @NotEmpty private String name;
private String name;
private String description; private String description;
private int order; private int order;
private boolean used; private boolean used;
@@ -54,8 +47,7 @@ public class CommonCodeDto {
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
public static class OrderReq { public static class OrderReq {
@Valid @Valid List<OrderReqDetail> orders;
List<OrderReqDetail> orders;
} }
@Getter @Getter
@@ -63,11 +55,9 @@ public class CommonCodeDto {
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
public static class OrderReqDetail { public static class OrderReqDetail {
@NotNull @NotNull private Long id;
private Long id;
@NotNull @NotNull private Integer order;
private Integer order;
} }
@Schema(name = "CommonCode Basic", description = "공통코드 기본 정보") @Schema(name = "CommonCode Basic", description = "공통코드 기본 정보")
@@ -83,23 +73,21 @@ public class CommonCodeDto {
private Boolean deleted; private Boolean deleted;
private List<CommonCodeDto.Basic> children; private List<CommonCodeDto.Basic> children;
@JsonFormatDttm @JsonFormatDttm private ZonedDateTime createdDttm;
private ZonedDateTime createdDttm;
@JsonFormatDttm @JsonFormatDttm private ZonedDateTime updatedDttm;
private ZonedDateTime updatedDttm;
public Basic( public Basic(
Long id, Long id,
String code, String code,
String description, String description,
String name, String name,
Integer order, Integer order,
Boolean used, Boolean used,
Boolean deleted, Boolean deleted,
List<CommonCodeDto.Basic> children, List<CommonCodeDto.Basic> children,
ZonedDateTime createdDttm, ZonedDateTime createdDttm,
ZonedDateTime updatedDttm) { ZonedDateTime updatedDttm) {
this.id = id; this.id = id;
this.code = code; this.code = code;
this.description = description; this.description = description;

View File

@@ -17,9 +17,9 @@ public class CommonCodeService {
private final CommonCodeCoreService commonCodeCoreService; private final CommonCodeCoreService commonCodeCoreService;
/** /**
* 공통코드 목록 조회 * 공통코드 목록 조회
*
* @return 모튼 코드 정보 * @return 모튼 코드 정보
*/ */
public List<Basic> getFindAll() { public List<Basic> getFindAll() {
@@ -28,6 +28,7 @@ public class CommonCodeService {
/** /**
* 공통코드 단건 조회 * 공통코드 단건 조회
*
* @param id * @param id
* @return 코드 아이디로 조회한 코드 정보 * @return 코드 아이디로 조회한 코드 정보
*/ */
@@ -37,6 +38,7 @@ public class CommonCodeService {
/** /**
* 공통코드 생성 요청 * 공통코드 생성 요청
*
* @param req 생성요청 정보 * @param req 생성요청 정보
* @return 생성된 코드 id * @return 생성된 코드 id
*/ */
@@ -47,6 +49,7 @@ public class CommonCodeService {
/** /**
* 공통코드 수정 요청 * 공통코드 수정 요청
*
* @param id 코드 아이디 * @param id 코드 아이디
* @param req 수정요청 정보 * @param req 수정요청 정보
*/ */
@@ -57,6 +60,7 @@ public class CommonCodeService {
/** /**
* 공통코드 삭제 처리 * 공통코드 삭제 처리
*
* @param id 코드 아이디 * @param id 코드 아이디
*/ */
@Transactional @Transactional
@@ -66,6 +70,7 @@ public class CommonCodeService {
/** /**
* 공통코드 순서 변경 * 공통코드 순서 변경
*
* @param req id, order 정보를 가진 List * @param req id, order 정보를 가진 List
*/ */
@Transactional @Transactional
@@ -75,6 +80,7 @@ public class CommonCodeService {
/** /**
* 코드기반 조회 * 코드기반 조회
*
* @param code 코드 * @param code 코드
* @return 코드로 조회한 공통코드 정보 * @return 코드로 조회한 공통코드 정보
*/ */

View File

@@ -4,15 +4,12 @@ import com.fasterxml.jackson.annotation.JacksonAnnotationsInside;
import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.annotation.JsonFormat;
import java.lang.annotation.*; import java.lang.annotation.*;
@Target({ ElementType.FIELD, ElementType.METHOD }) @Target({ElementType.FIELD, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
@Documented @Documented
@JacksonAnnotationsInside @JacksonAnnotationsInside
@JsonFormat( @JsonFormat(
shape = JsonFormat.Shape.STRING, shape = JsonFormat.Shape.STRING,
pattern = "yyyy-MM-dd'T'HH:mm:ssXXX", pattern = "yyyy-MM-dd'T'HH:mm:ssXXX",
timezone = "Asia/Seoul" timezone = "Asia/Seoul")
) public @interface JsonFormatDttm {}
public @interface JsonFormatDttm {
}

View File

@@ -8,6 +8,12 @@ import com.kamco.cd.kamcoback.postgres.entity.ErrorLogEntity;
import com.kamco.cd.kamcoback.postgres.repository.log.ErrorLogRepository; import com.kamco.cd.kamcoback.postgres.repository.log.ErrorLogRepository;
import jakarta.persistence.EntityNotFoundException; import jakarta.persistence.EntityNotFoundException;
import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletRequest;
import java.nio.file.AccessDeniedException;
import java.time.ZonedDateTime;
import java.util.Arrays;
import java.util.NoSuchElementException;
import java.util.Optional;
import java.util.stream.Collectors;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.core.annotation.Order; import org.springframework.core.annotation.Order;
import org.springframework.dao.DataIntegrityViolationException; import org.springframework.dao.DataIntegrityViolationException;
@@ -19,13 +25,6 @@ import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice; import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.client.HttpServerErrorException; import org.springframework.web.client.HttpServerErrorException;
import java.nio.file.AccessDeniedException;
import java.time.ZonedDateTime;
import java.util.Arrays;
import java.util.NoSuchElementException;
import java.util.Optional;
import java.util.stream.Collectors;
@Slf4j @Slf4j
@Order(value = 1) @Order(value = 1)
@RestControllerAdvice @RestControllerAdvice
@@ -39,102 +38,192 @@ public class GlobalExceptionHandler {
@ResponseStatus(HttpStatus.NOT_FOUND) @ResponseStatus(HttpStatus.NOT_FOUND)
@ExceptionHandler(EntityNotFoundException.class) @ExceptionHandler(EntityNotFoundException.class)
public ApiResponseDto<String> handlerEntityNotFoundException(EntityNotFoundException e, HttpServletRequest request) { public ApiResponseDto<String> handlerEntityNotFoundException(
EntityNotFoundException e, HttpServletRequest request) {
log.warn("[EntityNotFoundException] resource :{} ", e.getMessage()); log.warn("[EntityNotFoundException] resource :{} ", e.getMessage());
String codeName = "NOT_FOUND"; String codeName = "NOT_FOUND";
ErrorLogEntity errorLog = saveErrerLogData(request, ApiResponseCode.getCode(codeName), ErrorLogEntity errorLog =
HttpStatus.valueOf(codeName), ErrorLogDto.LogErrorLevel.ERROR, e.getStackTrace()); saveErrerLogData(
request,
ApiResponseCode.getCode(codeName),
HttpStatus.valueOf(codeName),
ErrorLogDto.LogErrorLevel.ERROR,
e.getStackTrace());
return ApiResponseDto.createException(ApiResponseCode.getCode(codeName), ApiResponseCode.getMessage(codeName), HttpStatus.valueOf(codeName), errorLog.getId()); return ApiResponseDto.createException(
ApiResponseCode.getCode(codeName),
ApiResponseCode.getMessage(codeName),
HttpStatus.valueOf(codeName),
errorLog.getId());
} }
@ResponseStatus(HttpStatus.BAD_REQUEST) @ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler(HttpMessageNotReadableException.class) @ExceptionHandler(HttpMessageNotReadableException.class)
public ApiResponseDto<String> handleUnreadable(HttpMessageNotReadableException e, HttpServletRequest request) { public ApiResponseDto<String> handleUnreadable(
HttpMessageNotReadableException e, HttpServletRequest request) {
log.warn("[HttpMessageNotReadableException] resource :{} ", e.getMessage()); log.warn("[HttpMessageNotReadableException] resource :{} ", e.getMessage());
String codeName = "BAD_REQUEST"; String codeName = "BAD_REQUEST";
ErrorLogEntity errorLog = saveErrerLogData(request, ApiResponseCode.getCode(codeName), ErrorLogEntity errorLog =
HttpStatus.valueOf(codeName), ErrorLogDto.LogErrorLevel.WARNING, e.getStackTrace()); saveErrerLogData(
request,
ApiResponseCode.getCode(codeName),
HttpStatus.valueOf(codeName),
ErrorLogDto.LogErrorLevel.WARNING,
e.getStackTrace());
return ApiResponseDto.createException(ApiResponseCode.getCode(codeName), ApiResponseCode.getMessage(codeName), HttpStatus.valueOf(codeName), errorLog.getId()); return ApiResponseDto.createException(
ApiResponseCode.getCode(codeName),
ApiResponseCode.getMessage(codeName),
HttpStatus.valueOf(codeName),
errorLog.getId());
} }
@ResponseStatus(HttpStatus.NOT_FOUND) @ResponseStatus(HttpStatus.NOT_FOUND)
@ExceptionHandler(NoSuchElementException.class) @ExceptionHandler(NoSuchElementException.class)
public ApiResponseDto<String> handlerNoSuchElementException(NoSuchElementException e, HttpServletRequest request) { public ApiResponseDto<String> handlerNoSuchElementException(
NoSuchElementException e, HttpServletRequest request) {
log.warn("[NoSuchElementException] resource :{} ", e.getMessage()); log.warn("[NoSuchElementException] resource :{} ", e.getMessage());
String codeName = "NOT_FOUND_DATA"; String codeName = "NOT_FOUND_DATA";
ErrorLogEntity errorLog = saveErrerLogData(request, ApiResponseCode.getCode(codeName), ErrorLogEntity errorLog =
HttpStatus.valueOf(codeName), ErrorLogDto.LogErrorLevel.WARNING, e.getStackTrace()); saveErrerLogData(
request,
ApiResponseCode.getCode(codeName),
HttpStatus.valueOf(codeName),
ErrorLogDto.LogErrorLevel.WARNING,
e.getStackTrace());
return ApiResponseDto.createException(ApiResponseCode.getCode(codeName), ApiResponseCode.getMessage(codeName), HttpStatus.valueOf("NOT_FOUND"), errorLog.getId()); return ApiResponseDto.createException(
ApiResponseCode.getCode(codeName),
ApiResponseCode.getMessage(codeName),
HttpStatus.valueOf("NOT_FOUND"),
errorLog.getId());
} }
@ResponseStatus(HttpStatus.BAD_REQUEST) @ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler(IllegalArgumentException.class) @ExceptionHandler(IllegalArgumentException.class)
public ApiResponseDto<String> handlerIllegalArgumentException(IllegalArgumentException e, HttpServletRequest request) { public ApiResponseDto<String> handlerIllegalArgumentException(
IllegalArgumentException e, HttpServletRequest request) {
log.warn("[handlerIllegalArgumentException] resource :{} ", e.getMessage()); log.warn("[handlerIllegalArgumentException] resource :{} ", e.getMessage());
String codeName = "BAD_REQUEST"; String codeName = "BAD_REQUEST";
ErrorLogEntity errorLog = saveErrerLogData(request, ApiResponseCode.getCode(codeName), ErrorLogEntity errorLog =
HttpStatus.valueOf(codeName), ErrorLogDto.LogErrorLevel.WARNING, e.getStackTrace()); saveErrerLogData(
request,
ApiResponseCode.getCode(codeName),
HttpStatus.valueOf(codeName),
ErrorLogDto.LogErrorLevel.WARNING,
e.getStackTrace());
return ApiResponseDto.createException(ApiResponseCode.getCode(codeName), ApiResponseCode.getMessage(codeName), HttpStatus.valueOf(codeName), errorLog.getId()); return ApiResponseDto.createException(
ApiResponseCode.getCode(codeName),
ApiResponseCode.getMessage(codeName),
HttpStatus.valueOf(codeName),
errorLog.getId());
} }
@ResponseStatus(HttpStatus.UNPROCESSABLE_ENTITY) @ResponseStatus(HttpStatus.UNPROCESSABLE_ENTITY)
@ExceptionHandler(DataIntegrityViolationException.class) @ExceptionHandler(DataIntegrityViolationException.class)
public ApiResponseDto<String> handlerDataIntegrityViolationException(DataIntegrityViolationException e, HttpServletRequest request) { public ApiResponseDto<String> handlerDataIntegrityViolationException(
DataIntegrityViolationException e, HttpServletRequest request) {
log.warn("[DataIntegrityViolationException] resource :{} ", e.getMessage()); log.warn("[DataIntegrityViolationException] resource :{} ", e.getMessage());
String codeName = "DATA_INTEGRITY_ERROR"; String codeName = "DATA_INTEGRITY_ERROR";
ErrorLogEntity errorLog = saveErrerLogData(request, ApiResponseCode.getCode(codeName), ErrorLogEntity errorLog =
HttpStatus.valueOf(codeName), ErrorLogDto.LogErrorLevel.CRITICAL, e.getStackTrace()); saveErrerLogData(
request,
ApiResponseCode.getCode(codeName),
HttpStatus.valueOf(codeName),
ErrorLogDto.LogErrorLevel.CRITICAL,
e.getStackTrace());
return ApiResponseDto.createException(ApiResponseCode.getCode(codeName), ApiResponseCode.getMessage(codeName), HttpStatus.valueOf("UNPROCESSABLE_ENTITY"), errorLog.getId()); return ApiResponseDto.createException(
ApiResponseCode.getCode(codeName),
ApiResponseCode.getMessage(codeName),
HttpStatus.valueOf("UNPROCESSABLE_ENTITY"),
errorLog.getId());
} }
@ResponseStatus(HttpStatus.BAD_REQUEST) @ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler(MethodArgumentNotValidException.class) @ExceptionHandler(MethodArgumentNotValidException.class)
public ApiResponseDto<String> handlerMethodArgumentNotValidException(MethodArgumentNotValidException e, HttpServletRequest request) { public ApiResponseDto<String> handlerMethodArgumentNotValidException(
MethodArgumentNotValidException e, HttpServletRequest request) {
log.warn("[MethodArgumentNotValidException] resource :{} ", e.getMessage()); log.warn("[MethodArgumentNotValidException] resource :{} ", e.getMessage());
String codeName = "BAD_REQUEST"; String codeName = "BAD_REQUEST";
ErrorLogEntity errorLog = saveErrerLogData(request, ApiResponseCode.getCode(codeName), ErrorLogEntity errorLog =
HttpStatus.valueOf(codeName), ErrorLogDto.LogErrorLevel.WARNING, e.getStackTrace()); saveErrerLogData(
request,
ApiResponseCode.getCode(codeName),
HttpStatus.valueOf(codeName),
ErrorLogDto.LogErrorLevel.WARNING,
e.getStackTrace());
return ApiResponseDto.createException(ApiResponseCode.getCode(codeName), ApiResponseCode.getMessage(codeName), HttpStatus.valueOf(codeName), errorLog.getId()); return ApiResponseDto.createException(
ApiResponseCode.getCode(codeName),
ApiResponseCode.getMessage(codeName),
HttpStatus.valueOf(codeName),
errorLog.getId());
} }
@ResponseStatus(HttpStatus.UNAUTHORIZED) @ResponseStatus(HttpStatus.UNAUTHORIZED)
@ExceptionHandler(AccessDeniedException.class) @ExceptionHandler(AccessDeniedException.class)
public ApiResponseDto<String> handlerAccessDeniedException(AccessDeniedException e, HttpServletRequest request) { public ApiResponseDto<String> handlerAccessDeniedException(
AccessDeniedException e, HttpServletRequest request) {
log.warn("[AccessDeniedException] resource :{} ", e.getMessage()); log.warn("[AccessDeniedException] resource :{} ", e.getMessage());
String codeName = "UNAUTHORIZED"; String codeName = "UNAUTHORIZED";
ErrorLogEntity errorLog = saveErrerLogData(request, ApiResponseCode.getCode(codeName), ErrorLogEntity errorLog =
HttpStatus.valueOf(codeName), ErrorLogDto.LogErrorLevel.ERROR, e.getStackTrace()); saveErrerLogData(
request,
ApiResponseCode.getCode(codeName),
HttpStatus.valueOf(codeName),
ErrorLogDto.LogErrorLevel.ERROR,
e.getStackTrace());
return ApiResponseDto.createException(ApiResponseCode.getCode(codeName), ApiResponseCode.getMessage(codeName), HttpStatus.valueOf(codeName), errorLog.getId()); return ApiResponseDto.createException(
ApiResponseCode.getCode(codeName),
ApiResponseCode.getMessage(codeName),
HttpStatus.valueOf(codeName),
errorLog.getId());
} }
@ResponseStatus(HttpStatus.BAD_GATEWAY) @ResponseStatus(HttpStatus.BAD_GATEWAY)
@ExceptionHandler(HttpServerErrorException.BadGateway.class) @ExceptionHandler(HttpServerErrorException.BadGateway.class)
public ApiResponseDto<String> handlerHttpServerErrorException(HttpServerErrorException e, HttpServletRequest request) { public ApiResponseDto<String> handlerHttpServerErrorException(
HttpServerErrorException e, HttpServletRequest request) {
log.warn("[HttpServerErrorException] resource :{} ", e.getMessage()); log.warn("[HttpServerErrorException] resource :{} ", e.getMessage());
String codeName = "BAD_GATEWAY"; String codeName = "BAD_GATEWAY";
ErrorLogEntity errorLog = saveErrerLogData(request, ApiResponseCode.getCode(codeName), ErrorLogEntity errorLog =
HttpStatus.valueOf(codeName), ErrorLogDto.LogErrorLevel.CRITICAL, e.getStackTrace()); saveErrerLogData(
request,
ApiResponseCode.getCode(codeName),
HttpStatus.valueOf(codeName),
ErrorLogDto.LogErrorLevel.CRITICAL,
e.getStackTrace());
return ApiResponseDto.createException(ApiResponseCode.getCode(codeName), ApiResponseCode.getMessage(codeName), HttpStatus.valueOf(codeName), errorLog.getId()); return ApiResponseDto.createException(
ApiResponseCode.getCode(codeName),
ApiResponseCode.getMessage(codeName),
HttpStatus.valueOf(codeName),
errorLog.getId());
} }
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
@ExceptionHandler(RuntimeException.class) @ExceptionHandler(RuntimeException.class)
public ApiResponseDto<String> handlerRuntimeException(RuntimeException e, HttpServletRequest request) { public ApiResponseDto<String> handlerRuntimeException(
RuntimeException e, HttpServletRequest request) {
log.warn("[RuntimeException] resource :{} ", e.getMessage()); log.warn("[RuntimeException] resource :{} ", e.getMessage());
String codeName = "INTERNAL_SERVER_ERROR"; String codeName = "INTERNAL_SERVER_ERROR";
ErrorLogEntity errorLog = saveErrerLogData(request, ApiResponseCode.getCode(codeName), ErrorLogEntity errorLog =
HttpStatus.valueOf(codeName), ErrorLogDto.LogErrorLevel.CRITICAL, e.getStackTrace()); saveErrerLogData(
request,
ApiResponseCode.getCode(codeName),
HttpStatus.valueOf(codeName),
ErrorLogDto.LogErrorLevel.CRITICAL,
e.getStackTrace());
return ApiResponseDto.createException(ApiResponseCode.getCode(codeName), ApiResponseCode.getMessage(codeName), HttpStatus.valueOf(codeName), errorLog.getId()); return ApiResponseDto.createException(
ApiResponseCode.getCode(codeName),
ApiResponseCode.getMessage(codeName),
HttpStatus.valueOf(codeName),
errorLog.getId());
} }
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
@@ -143,14 +232,24 @@ public class GlobalExceptionHandler {
log.warn("[Exception] resource :{} ", e.getMessage()); log.warn("[Exception] resource :{} ", e.getMessage());
String codeName = "INTERNAL_SERVER_ERROR"; String codeName = "INTERNAL_SERVER_ERROR";
ErrorLogEntity errorLog = saveErrerLogData(request, ApiResponseCode.getCode(codeName), ErrorLogEntity errorLog =
HttpStatus.valueOf(codeName), ErrorLogDto.LogErrorLevel.CRITICAL, e.getStackTrace()); saveErrerLogData(
request,
ApiResponseCode.getCode(codeName),
HttpStatus.valueOf(codeName),
ErrorLogDto.LogErrorLevel.CRITICAL,
e.getStackTrace());
return ApiResponseDto.createException(ApiResponseCode.getCode(codeName), ApiResponseCode.getMessage(codeName), HttpStatus.valueOf(codeName), errorLog.getId()); return ApiResponseDto.createException(
ApiResponseCode.getCode(codeName),
ApiResponseCode.getMessage(codeName),
HttpStatus.valueOf(codeName),
errorLog.getId());
} }
/** /**
* 에러 로그 테이블 저장 로직 * 에러 로그 테이블 저장 로직
*
* @param request : request * @param request : request
* @param errorCode : 정의된 enum errorCode * @param errorCode : 정의된 enum errorCode
* @param httpStatus : HttpStatus 값 * @param httpStatus : HttpStatus 값
@@ -158,19 +257,32 @@ public class GlobalExceptionHandler {
* @param stackTrace : 에러 내용 * @param stackTrace : 에러 내용
* @return : insert하고 결과로 받은 Entity * @return : insert하고 결과로 받은 Entity
*/ */
private ErrorLogEntity saveErrerLogData(HttpServletRequest request, ApiResponseCode errorCode, private ErrorLogEntity saveErrerLogData(
HttpStatus httpStatus, ErrorLogDto.LogErrorLevel logErrorLevel, StackTraceElement[] stackTrace) { HttpServletRequest request,
//TODO : 로그인 개발되면 이것도 연결해야 함 ApiResponseCode errorCode,
HttpStatus httpStatus,
ErrorLogDto.LogErrorLevel logErrorLevel,
StackTraceElement[] stackTrace) {
// TODO : 로그인 개발되면 이것도 연결해야 함
Long userid = Long.valueOf(Optional.ofNullable(ApiLogFunction.getUserId(request)).orElse("1")); Long userid = Long.valueOf(Optional.ofNullable(ApiLogFunction.getUserId(request)).orElse("1"));
//TODO : stackTrace limit 10줄? 확인 필요 // TODO : stackTrace limit 10줄? 확인 필요
String stackTraceStr = Arrays.stream(stackTrace) String stackTraceStr =
.limit(10) Arrays.stream(stackTrace)
.map(StackTraceElement::toString) .limit(10)
.collect(Collectors.joining("\n")); .map(StackTraceElement::toString)
.collect(Collectors.joining("\n"));
ErrorLogEntity errorLogEntity = new ErrorLogEntity(request.getRequestURI(), ApiLogFunction.getEventType(request), logErrorLevel, ErrorLogEntity errorLogEntity =
String.valueOf(httpStatus.value()), errorCode.getText(), stackTraceStr, userid, ZonedDateTime.now()); new ErrorLogEntity(
request.getRequestURI(),
ApiLogFunction.getEventType(request),
logErrorLevel,
String.valueOf(httpStatus.value()),
errorCode.getText(),
stackTraceStr,
userid,
ZonedDateTime.now());
return errorLogRepository.save(errorLogEntity); return errorLogRepository.save(errorLogEntity);
} }

View File

@@ -4,22 +4,21 @@ import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException; import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter; import org.springframework.web.filter.OncePerRequestFilter;
import org.springframework.web.util.ContentCachingRequestWrapper; import org.springframework.web.util.ContentCachingRequestWrapper;
import org.springframework.web.util.ContentCachingResponseWrapper; import org.springframework.web.util.ContentCachingResponseWrapper;
import java.io.IOException;
@Component @Component
public class ApiLogFilter extends OncePerRequestFilter { public class ApiLogFilter extends OncePerRequestFilter {
@Override @Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { protected void doFilterInternal(
ContentCachingRequestWrapper wrappedRequest = HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
new ContentCachingRequestWrapper(request); throws ServletException, IOException {
ContentCachingRequestWrapper wrappedRequest = new ContentCachingRequestWrapper(request);
ContentCachingResponseWrapper wrappedResponse = ContentCachingResponseWrapper wrappedResponse = new ContentCachingResponseWrapper(response);
new ContentCachingResponseWrapper(response);
filterChain.doFilter(wrappedRequest, wrappedResponse); filterChain.doFilter(wrappedRequest, wrappedResponse);

View File

@@ -3,11 +3,10 @@ package com.kamco.cd.kamcoback.config.api;
import com.kamco.cd.kamcoback.log.dto.EventStatus; import com.kamco.cd.kamcoback.log.dto.EventStatus;
import com.kamco.cd.kamcoback.log.dto.EventType; import com.kamco.cd.kamcoback.log.dto.EventType;
import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletRequest;
import org.springframework.web.util.ContentCachingRequestWrapper;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.util.Map; import java.util.Map;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import org.springframework.web.util.ContentCachingRequestWrapper;
public class ApiLogFunction { public class ApiLogFunction {
// 클라이언트 IP 추출 // 클라이언트 IP 추출
@@ -26,7 +25,7 @@ public class ApiLogFunction {
} }
} }
String ip = request.getRemoteAddr(); String ip = request.getRemoteAddr();
if ("0:0:0:0:0:0:0:1".equals(ip)) { //local 일 때 if ("0:0:0:0:0:0:0:1".equals(ip)) { // local 일 때
ip = "127.0.0.1"; ip = "127.0.0.1";
} }
return ip; return ip;
@@ -45,9 +44,9 @@ public class ApiLogFunction {
String method = request.getMethod().toUpperCase(); String method = request.getMethod().toUpperCase();
String uri = request.getRequestURI().toLowerCase(); String uri = request.getRequestURI().toLowerCase();
//URL 기반 DOWNLOAD/PRINT 분류 // URL 기반 DOWNLOAD/PRINT 분류
if(uri.contains("/download") || uri.contains("/export")) return EventType.DOWNLOAD; if (uri.contains("/download") || uri.contains("/export")) return EventType.DOWNLOAD;
if(uri.contains("/print")) return EventType.PRINT; if (uri.contains("/print")) return EventType.PRINT;
// 일반 CRUD // 일반 CRUD
return switch (method) { return switch (method) {
@@ -59,23 +58,25 @@ public class ApiLogFunction {
}; };
} }
public static String getRequestBody(HttpServletRequest servletRequest, ContentCachingRequestWrapper contentWrapper) { public static String getRequestBody(
HttpServletRequest servletRequest, ContentCachingRequestWrapper contentWrapper) {
StringBuilder resultBody = new StringBuilder(); StringBuilder resultBody = new StringBuilder();
// GET, form-urlencoded POST 파라미터 // GET, form-urlencoded POST 파라미터
Map<String, String[]> paramMap = servletRequest.getParameterMap(); Map<String, String[]> paramMap = servletRequest.getParameterMap();
String queryParams = paramMap.entrySet().stream() String queryParams =
.map(e -> e.getKey() + "=" + String.join(",", e.getValue())) paramMap.entrySet().stream()
.collect(Collectors.joining("&")); .map(e -> e.getKey() + "=" + String.join(",", e.getValue()))
.collect(Collectors.joining("&"));
resultBody.append(queryParams.isEmpty() ? "" : queryParams); resultBody.append(queryParams.isEmpty() ? "" : queryParams);
// JSON Body // JSON Body
if ("POST".equalsIgnoreCase(servletRequest.getMethod()) if ("POST".equalsIgnoreCase(servletRequest.getMethod())
&& servletRequest.getContentType() != null && servletRequest.getContentType() != null
&& servletRequest.getContentType().contains("application/json")) { && servletRequest.getContentType().contains("application/json")) {
try { try {
//json인 경우는 Wrapper를 통해 가져오기 // json인 경우는 Wrapper를 통해 가져오기
resultBody.append(getBodyData(contentWrapper)); resultBody.append(getBodyData(contentWrapper));
} catch (Exception e) { } catch (Exception e) {
@@ -85,8 +86,8 @@ public class ApiLogFunction {
// Multipart form-data // Multipart form-data
if ("POST".equalsIgnoreCase(servletRequest.getMethod()) if ("POST".equalsIgnoreCase(servletRequest.getMethod())
&& servletRequest.getContentType() != null && servletRequest.getContentType() != null
&& servletRequest.getContentType().startsWith("multipart/form-data")) { && servletRequest.getContentType().startsWith("multipart/form-data")) {
resultBody.append("multipart/form-data request"); resultBody.append("multipart/form-data request");
} }
@@ -104,8 +105,8 @@ public class ApiLogFunction {
} }
} }
//ApiResponse 의 Status가 2xx 범위이면 SUCCESS, 아니면 FAILED // ApiResponse 의 Status가 2xx 범위이면 SUCCESS, 아니면 FAILED
public static EventStatus isSuccessFail(ApiResponseDto<?> apiResponse){ public static EventStatus isSuccessFail(ApiResponseDto<?> apiResponse) {
return apiResponse.getHttpStatus().is2xxSuccessful() ? EventStatus.SUCCESS : EventStatus.FAILED; return apiResponse.getHttpStatus().is2xxSuccessful() ? EventStatus.SUCCESS : EventStatus.FAILED;
} }
} }

View File

@@ -3,6 +3,7 @@ package com.kamco.cd.kamcoback.config.api;
import com.kamco.cd.kamcoback.postgres.entity.AuditLogEntity; import com.kamco.cd.kamcoback.postgres.entity.AuditLogEntity;
import com.kamco.cd.kamcoback.postgres.repository.log.AuditLogRepository; import com.kamco.cd.kamcoback.postgres.repository.log.AuditLogRepository;
import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletRequest;
import java.util.Optional;
import org.springframework.core.MethodParameter; import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType; import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter; import org.springframework.http.converter.HttpMessageConverter;
@@ -13,8 +14,6 @@ import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice; import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;
import org.springframework.web.util.ContentCachingRequestWrapper; import org.springframework.web.util.ContentCachingRequestWrapper;
import java.util.Optional;
/** /**
* ApiResponseDto의 내장된 HTTP 상태 코드를 실제 HTTP 응답에 적용하는 Advice * ApiResponseDto의 내장된 HTTP 상태 코드를 실제 HTTP 응답에 적용하는 Advice
* *
@@ -53,16 +52,23 @@ public class ApiResponseAdvice implements ResponseBodyAdvice<Object> {
response.setStatusCode(apiResponse.getHttpStatus()); response.setStatusCode(apiResponse.getHttpStatus());
String ip = ApiLogFunction.getClientIp(servletRequest); String ip = ApiLogFunction.getClientIp(servletRequest);
//TODO : userid 가 계정명인지, uid 인지 확인 후 로직 수정 필요함 // TODO : userid 가 계정명인지, uid 인지 확인 후 로직 수정 필요함
Long userid = Long.valueOf(Optional.ofNullable(ApiLogFunction.getUserId(servletRequest)).orElse("1")); Long userid =
Long.valueOf(Optional.ofNullable(ApiLogFunction.getUserId(servletRequest)).orElse("1"));
//TODO: menuUid 를 동적으로 가져오게끔 해야함 // TODO: menuUid 를 동적으로 가져오게끔 해야함
AuditLogEntity log = new AuditLogEntity(userid, ApiLogFunction.getEventType(servletRequest), AuditLogEntity log =
ApiLogFunction.isSuccessFail(apiResponse), "MU_01_01", ip, servletRequest.getRequestURI(), ApiLogFunction.getRequestBody(servletRequest, contentWrapper), new AuditLogEntity(
apiResponse.getErrorLogUid() userid,
); ApiLogFunction.getEventType(servletRequest),
ApiLogFunction.isSuccessFail(apiResponse),
"MU_01_01",
ip,
servletRequest.getRequestURI(),
ApiLogFunction.getRequestBody(servletRequest, contentWrapper),
apiResponse.getErrorLogUid());
//tb_audit_log 테이블 저장 // tb_audit_log 테이블 저장
auditLogRepository.save(log); auditLogRepository.save(log);
} }

View File

@@ -40,11 +40,14 @@ public class ApiResponseDto<T> {
public ApiResponseDto(ApiResponseCode code, String message) { public ApiResponseDto(ApiResponseCode code, String message) {
this.error = new Error(code.getId(), message); this.error = new Error(code.getId(), message);
} }
public ApiResponseDto(ApiResponseCode code, String message, HttpStatus httpStatus) { public ApiResponseDto(ApiResponseCode code, String message, HttpStatus httpStatus) {
this.error = new Error(code.getId(), message); this.error = new Error(code.getId(), message);
this.httpStatus = httpStatus; this.httpStatus = httpStatus;
} }
public ApiResponseDto(ApiResponseCode code, String message, HttpStatus httpStatus, Long errorLogUid) {
public ApiResponseDto(
ApiResponseCode code, String message, HttpStatus httpStatus, Long errorLogUid) {
this.error = new Error(code.getId(), message); this.error = new Error(code.getId(), message);
this.httpStatus = httpStatus; this.httpStatus = httpStatus;
this.errorLogUid = errorLogUid; this.errorLogUid = errorLogUid;
@@ -75,10 +78,14 @@ public class ApiResponseDto<T> {
public static ApiResponseDto<String> createException(ApiResponseCode code, String message) { public static ApiResponseDto<String> createException(ApiResponseCode code, String message) {
return new ApiResponseDto<>(code, message); return new ApiResponseDto<>(code, message);
} }
public static ApiResponseDto<String> createException(ApiResponseCode code, String message, HttpStatus httpStatus) {
public static ApiResponseDto<String> createException(
ApiResponseCode code, String message, HttpStatus httpStatus) {
return new ApiResponseDto<>(code, message, httpStatus); return new ApiResponseDto<>(code, message, httpStatus);
} }
public static ApiResponseDto<String> createException(ApiResponseCode code, String message, HttpStatus httpStatus, Long errorLogUid) {
public static ApiResponseDto<String> createException(
ApiResponseCode code, String message, HttpStatus httpStatus, Long errorLogUid) {
return new ApiResponseDto<>(code, message, httpStatus, errorLogUid); return new ApiResponseDto<>(code, message, httpStatus, errorLogUid);
} }

View File

@@ -4,8 +4,8 @@ import com.kamco.cd.kamcoback.config.api.ApiResponseDto;
import com.kamco.cd.kamcoback.log.dto.AuditLogDto; import com.kamco.cd.kamcoback.log.dto.AuditLogDto;
import com.kamco.cd.kamcoback.postgres.core.AuditLogCoreService; import com.kamco.cd.kamcoback.postgres.core.AuditLogCoreService;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tag;
import java.time.LocalDate;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page; import org.springframework.data.domain.Page;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
@@ -13,8 +13,6 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import java.time.LocalDate;
@Tag(name = "감사 로그", description = "감사 로그 관리 API") @Tag(name = "감사 로그", description = "감사 로그 관리 API")
@RequiredArgsConstructor @RequiredArgsConstructor
@RestController @RestController
@@ -26,18 +24,15 @@ public class AuditLogApiController {
@Operation(summary = "일자별 로그 조회") @Operation(summary = "일자별 로그 조회")
@GetMapping("/daily") @GetMapping("/daily")
public ApiResponseDto<Page<AuditLogDto.AuditList>> getDailyLogs( public ApiResponseDto<Page<AuditLogDto.AuditList>> getDailyLogs(
@RequestParam(required = false) LocalDate startDate, @RequestParam(required = false) LocalDate startDate,
@RequestParam(required = false) LocalDate endDate, @RequestParam(required = false) LocalDate endDate,
@RequestParam int page, @RequestParam int page,
@RequestParam(defaultValue = "20") int size @RequestParam(defaultValue = "20") int size) {
) { AuditLogDto.DailySearchReq searchReq =
AuditLogDto.DailySearchReq searchReq = new AuditLogDto.DailySearchReq(startDate, endDate, null, page, size, "created_dttm,desc"); new AuditLogDto.DailySearchReq(startDate, endDate, null, page, size, "created_dttm,desc");
Page<AuditLogDto.AuditList> result = auditLogCoreService.getLogByDaily( Page<AuditLogDto.AuditList> result =
searchReq, auditLogCoreService.getLogByDaily(searchReq, startDate, endDate);
startDate,
endDate
);
return ApiResponseDto.ok(result); return ApiResponseDto.ok(result);
} }
@@ -45,83 +40,69 @@ public class AuditLogApiController {
@Operation(summary = "일자별 로그 상세") @Operation(summary = "일자별 로그 상세")
@GetMapping("/daily/result") @GetMapping("/daily/result")
public ApiResponseDto<Page<AuditLogDto.AuditDetail>> getDailyResultLogs( public ApiResponseDto<Page<AuditLogDto.AuditDetail>> getDailyResultLogs(
@RequestParam LocalDate logDate, @RequestParam LocalDate logDate,
@RequestParam int page, @RequestParam int page,
@RequestParam(defaultValue = "20") int size @RequestParam(defaultValue = "20") int size) {
) { AuditLogDto.DailySearchReq searchReq =
AuditLogDto.DailySearchReq searchReq = new AuditLogDto.DailySearchReq(null, null, logDate, page, size, "created_dttm,desc"); new AuditLogDto.DailySearchReq(null, null, logDate, page, size, "created_dttm,desc");
Page<AuditLogDto.AuditDetail> result = auditLogCoreService.getLogByDailyResult( Page<AuditLogDto.AuditDetail> result =
searchReq, auditLogCoreService.getLogByDailyResult(searchReq, logDate);
logDate
);
return ApiResponseDto.ok(result); return ApiResponseDto.ok(result);
} }
@Operation(summary = "메뉴별 로그 조회") @Operation(summary = "메뉴별 로그 조회")
@GetMapping("/menu") @GetMapping("/menu")
public ApiResponseDto<Page<AuditLogDto.AuditList>> getMenuLogs( public ApiResponseDto<Page<AuditLogDto.AuditList>> getMenuLogs(
@RequestParam(required = false) String searchValue, @RequestParam(required = false) String searchValue,
@RequestParam int page, @RequestParam int page,
@RequestParam(defaultValue = "20") int size @RequestParam(defaultValue = "20") int size) {
) { AuditLogDto.MenuUserSearchReq searchReq =
AuditLogDto.MenuUserSearchReq searchReq = new AuditLogDto.MenuUserSearchReq(searchValue, null, null, page, size, "created_dttm,desc"); new AuditLogDto.MenuUserSearchReq(searchValue, null, null, page, size, "created_dttm,desc");
Page<AuditLogDto.AuditList> result = auditLogCoreService.getLogByMenu( Page<AuditLogDto.AuditList> result = auditLogCoreService.getLogByMenu(searchReq, searchValue);
searchReq, searchValue
);
return ApiResponseDto.ok(result); return ApiResponseDto.ok(result);
} }
@Operation(summary = "메뉴별 로그 상세") @Operation(summary = "메뉴별 로그 상세")
@GetMapping("/menu/result") @GetMapping("/menu/result")
public ApiResponseDto<Page<AuditLogDto.AuditDetail>> getMenuResultLogs( public ApiResponseDto<Page<AuditLogDto.AuditDetail>> getMenuResultLogs(
@RequestParam String menuId, @RequestParam String menuId,
@RequestParam int page, @RequestParam int page,
@RequestParam(defaultValue = "20") int size @RequestParam(defaultValue = "20") int size) {
) { AuditLogDto.MenuUserSearchReq searchReq =
AuditLogDto.MenuUserSearchReq searchReq = new AuditLogDto.MenuUserSearchReq(null, menuId, null, page, size, "created_dttm,desc"); new AuditLogDto.MenuUserSearchReq(null, menuId, null, page, size, "created_dttm,desc");
Page<AuditLogDto.AuditDetail> result = auditLogCoreService.getLogByMenuResult( Page<AuditLogDto.AuditDetail> result =
searchReq, auditLogCoreService.getLogByMenuResult(searchReq, menuId);
menuId
);
return ApiResponseDto.ok(result); return ApiResponseDto.ok(result);
} }
@Operation(summary = "사용자별 로그 조회") @Operation(summary = "사용자별 로그 조회")
@GetMapping("/account") @GetMapping("/account")
public ApiResponseDto<Page<AuditLogDto.AuditList>> getAccountLogs( public ApiResponseDto<Page<AuditLogDto.AuditList>> getAccountLogs(
@RequestParam(required = false) String searchValue, @RequestParam(required = false) String searchValue,
@RequestParam int page, @RequestParam int page,
@RequestParam(defaultValue = "20") int size @RequestParam(defaultValue = "20") int size) {
) { AuditLogDto.MenuUserSearchReq searchReq =
AuditLogDto.MenuUserSearchReq searchReq = new AuditLogDto.MenuUserSearchReq(searchValue, null, null, page, size, "created_dttm,desc"); new AuditLogDto.MenuUserSearchReq(searchValue, null, null, page, size, "created_dttm,desc");
Page<AuditLogDto.AuditList> result = auditLogCoreService.getLogByAccount( Page<AuditLogDto.AuditList> result =
searchReq, searchValue auditLogCoreService.getLogByAccount(searchReq, searchValue);
);
return ApiResponseDto.ok(result); return ApiResponseDto.ok(result);
} }
@Operation(summary = "사용자별 로그 상세") @Operation(summary = "사용자별 로그 상세")
@GetMapping("/account/result") @GetMapping("/account/result")
public ApiResponseDto<Page<AuditLogDto.AuditDetail>> getAccountResultLogs( public ApiResponseDto<Page<AuditLogDto.AuditDetail>> getAccountResultLogs(
@RequestParam Long userUid, @RequestParam Long userUid,
@RequestParam int page, @RequestParam int page,
@RequestParam(defaultValue = "20") int size @RequestParam(defaultValue = "20") int size) {
) { AuditLogDto.MenuUserSearchReq searchReq =
AuditLogDto.MenuUserSearchReq searchReq = new AuditLogDto.MenuUserSearchReq(null, null, userUid, page, size, "created_dttm,desc"); new AuditLogDto.MenuUserSearchReq(null, null, userUid, page, size, "created_dttm,desc");
Page<AuditLogDto.AuditDetail> result = auditLogCoreService.getLogByAccountResult( Page<AuditLogDto.AuditDetail> result =
searchReq, auditLogCoreService.getLogByAccountResult(searchReq, userUid);
userUid
);
return ApiResponseDto.ok(result); return ApiResponseDto.ok(result);
} }
} }

View File

@@ -1,25 +1,19 @@
package com.kamco.cd.kamcoback.log; package com.kamco.cd.kamcoback.log;
import com.kamco.cd.kamcoback.config.api.ApiResponseDto; import com.kamco.cd.kamcoback.config.api.ApiResponseDto;
import com.kamco.cd.kamcoback.log.dto.AuditLogDto;
import com.kamco.cd.kamcoback.log.dto.ErrorLogDto; import com.kamco.cd.kamcoback.log.dto.ErrorLogDto;
import com.kamco.cd.kamcoback.log.dto.EventType; import com.kamco.cd.kamcoback.log.dto.EventType;
import com.kamco.cd.kamcoback.postgres.core.AuditLogCoreService;
import com.kamco.cd.kamcoback.postgres.core.ErrorLogCoreService; import com.kamco.cd.kamcoback.postgres.core.ErrorLogCoreService;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tag;
import java.time.LocalDate;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page; import org.springframework.data.domain.Page;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import java.time.LocalDate;
import java.util.List;
@Tag(name = "에러 로그", description = "에러 로그 관리 API") @Tag(name = "에러 로그", description = "에러 로그 관리 API")
@RequiredArgsConstructor @RequiredArgsConstructor
@RestController @RestController
@@ -29,17 +23,17 @@ public class ErrorLogApiController {
private final ErrorLogCoreService errorLogCoreService; private final ErrorLogCoreService errorLogCoreService;
@Operation(summary = "에러로그 조회") @Operation(summary = "에러로그 조회")
@GetMapping("/error") @GetMapping("/error")
public ApiResponseDto<Page<ErrorLogDto.Basic>> getErrorLogs( public ApiResponseDto<Page<ErrorLogDto.Basic>> getErrorLogs(
@RequestParam(required = false) ErrorLogDto.LogErrorLevel logErrorLevel, @RequestParam(required = false) ErrorLogDto.LogErrorLevel logErrorLevel,
@RequestParam(required = false) EventType eventType, @RequestParam(required = false) EventType eventType,
@RequestParam(required = false) LocalDate startDate, @RequestParam(required = false) LocalDate startDate,
@RequestParam(required = false) LocalDate endDate, @RequestParam(required = false) LocalDate endDate,
@RequestParam int page, @RequestParam int page,
@RequestParam(defaultValue = "20") int size @RequestParam(defaultValue = "20") int size) {
) { ErrorLogDto.ErrorSearchReq searchReq =
ErrorLogDto.ErrorSearchReq searchReq = new ErrorLogDto.ErrorSearchReq(logErrorLevel, eventType, startDate, endDate, page, size, "created_dttm,desc"); new ErrorLogDto.ErrorSearchReq(
logErrorLevel, eventType, startDate, endDate, page, size, "created_dttm,desc");
Page<ErrorLogDto.Basic> result = errorLogCoreService.findLogByError(searchReq); Page<ErrorLogDto.Basic> result = errorLogCoreService.findLogByError(searchReq);
return ApiResponseDto.ok(result); return ApiResponseDto.ok(result);

View File

@@ -3,6 +3,9 @@ package com.kamco.cd.kamcoback.log.dto;
import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnore;
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 java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZonedDateTime;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Getter; import lombok.Getter;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
@@ -11,18 +14,13 @@ import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort; import org.springframework.data.domain.Sort;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZonedDateTime;
public class AuditLogDto { public class AuditLogDto {
@Schema(name = "AuditLogBasic", description = "감사로그 기본 정보") @Schema(name = "AuditLogBasic", description = "감사로그 기본 정보")
@Getter @Getter
public static class Basic { public static class Basic {
@JsonIgnore @JsonIgnore private final Long id;
private final Long id;
private final Long userUid; private final Long userUid;
private final EventType eventType; private final EventType eventType;
private final EventStatus eventStatus; private final EventStatus eventStatus;
@@ -32,30 +30,29 @@ public class AuditLogDto {
private final String requestBody; private final String requestBody;
private final Long errorLogUid; private final Long errorLogUid;
@JsonFormatDttm @JsonFormatDttm private final ZonedDateTime createdDttm;
private final ZonedDateTime createdDttm;
public Basic( public Basic(
Long id, Long id,
Long userUid, Long userUid,
EventType eventType, EventType eventType,
EventStatus eventStatus, EventStatus eventStatus,
String menuUid, String menuUid,
String ipAddress, String ipAddress,
String requestUri, String requestUri,
String requestBody, String requestBody,
Long errorLogUid, Long errorLogUid,
ZonedDateTime createdDttm) { ZonedDateTime createdDttm) {
this.id = id; this.id = id;
this.userUid = userUid; this.userUid = userUid;
this.eventType = eventType; this.eventType = eventType;
this.eventStatus = eventStatus; this.eventStatus = eventStatus;
this.menuUid = menuUid; this.menuUid = menuUid;
this.ipAddress = ipAddress; this.ipAddress = ipAddress;
this.requestUri = requestUri; this.requestUri = requestUri;
this.requestBody = requestBody; this.requestBody = requestBody;
this.errorLogUid = errorLogUid; this.errorLogUid = errorLogUid;
this.createdDttm = createdDttm; this.createdDttm = createdDttm;
} }
} }
@@ -76,7 +73,13 @@ public class AuditLogDto {
private Long menuId; private Long menuId;
private String menuName; private String menuName;
public AuditList(LocalDateTime baseDate, int readCount, int cudCount, int printCount, int downloadCount, Long totalCount){ public AuditList(
LocalDateTime baseDate,
int readCount,
int cudCount,
int printCount,
int downloadCount,
Long totalCount) {
this.baseDate = baseDate; this.baseDate = baseDate;
this.readCount = readCount; this.readCount = readCount;
this.cudCount = cudCount; this.cudCount = cudCount;
@@ -103,7 +106,7 @@ public class AuditLogDto {
@Getter @Getter
@Setter @Setter
@AllArgsConstructor @AllArgsConstructor
public static class LogDetail{ public static class LogDetail {
String serviceName; String serviceName;
String parentMenuName; String parentMenuName;
String menuName; String menuName;
@@ -152,14 +155,15 @@ public class AuditLogDto {
// 메뉴별, 사용자별 로그 검색 조건 // 메뉴별, 사용자별 로그 검색 조건
private String searchValue; private String searchValue;
private String menuUid; private String menuUid;
private Long userUid; //menuId, userUid 조회 private Long userUid; // menuId, userUid 조회
// 페이징 파라미터 // 페이징 파라미터
private int page = 0; private int page = 0;
private int size = 20; private int size = 20;
private String sort; private String sort;
public MenuUserSearchReq(String searchValue, String menuUid, Long userUid, int page, int size, String sort) { public MenuUserSearchReq(
String searchValue, String menuUid, Long userUid, int page, int size, String sort) {
this.searchValue = searchValue; this.searchValue = searchValue;
this.menuUid = menuUid; this.menuUid = menuUid;
this.page = page; this.page = page;

View File

@@ -4,6 +4,8 @@ import com.fasterxml.jackson.annotation.JsonIgnore;
import com.kamco.cd.kamcoback.common.utils.interfaces.JsonFormatDttm; import com.kamco.cd.kamcoback.common.utils.interfaces.JsonFormatDttm;
import com.kamco.cd.kamcoback.config.enums.EnumType; import com.kamco.cd.kamcoback.config.enums.EnumType;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import java.time.LocalDate;
import java.time.ZonedDateTime;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Getter; import lombok.Getter;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
@@ -12,18 +14,13 @@ import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort; import org.springframework.data.domain.Sort;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZonedDateTime;
public class ErrorLogDto { public class ErrorLogDto {
@Schema(name = "ErrorLogBasic", description = "에러로그 기본 정보") @Schema(name = "ErrorLogBasic", description = "에러로그 기본 정보")
@Getter @Getter
public static class Basic { public static class Basic {
@JsonIgnore @JsonIgnore private final Long id;
private final Long id;
private final String requestId; private final String requestId;
private final EventType errorType; private final EventType errorType;
private final LogErrorLevel errorLevel; private final LogErrorLevel errorLevel;
@@ -32,23 +29,21 @@ public class ErrorLogDto {
private final String stackTrace; private final String stackTrace;
private final Long handlerUid; private final Long handlerUid;
@JsonFormatDttm @JsonFormatDttm private final ZonedDateTime handledDttm;
private final ZonedDateTime handledDttm;
@JsonFormatDttm @JsonFormatDttm private final ZonedDateTime createdDttm;
private final ZonedDateTime createdDttm;
public Basic( public Basic(
Long id, Long id,
String requestId, String requestId,
EventType errorType, EventType errorType,
LogErrorLevel errorLevel, LogErrorLevel errorLevel,
String errorCode, String errorCode,
String errorMessage, String errorMessage,
String stackTrace, String stackTrace,
Long handlerUid, Long handlerUid,
ZonedDateTime handledDttm, ZonedDateTime handledDttm,
ZonedDateTime createdDttm) { ZonedDateTime createdDttm) {
this.id = id; this.id = id;
this.requestId = requestId; this.requestId = requestId;
this.errorType = errorType; this.errorType = errorType;
@@ -79,7 +74,13 @@ public class ErrorLogDto {
private int size = 20; private int size = 20;
private String sort; private String sort;
public ErrorSearchReq(LogErrorLevel errorLevel, EventType eventType, LocalDate startDate, LocalDate endDate, int page, int size) { public ErrorSearchReq(
LogErrorLevel errorLevel,
EventType eventType,
LocalDate startDate,
LocalDate endDate,
int page,
int size) {
this.errorLevel = errorLevel; this.errorLevel = errorLevel;
this.eventType = eventType; this.eventType = eventType;
this.startDate = startDate; this.startDate = startDate;
@@ -93,7 +94,7 @@ public class ErrorLogDto {
String[] sortParams = sort.split(","); String[] sortParams = sort.split(",");
String property = sortParams[0]; String property = sortParams[0];
Sort.Direction direction = 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, Sort.by(direction, property));
} }
return PageRequest.of(page, size); return PageRequest.of(page, size);
@@ -112,10 +113,13 @@ public class ErrorLogDto {
} }
@Override @Override
public String getId() { return name(); } public String getId() {
return name();
}
@Override @Override
public String getText() { return desc; } public String getText() {
return desc;
}
} }
} }

View File

@@ -13,8 +13,12 @@ public enum EventStatus implements EnumType {
private final String desc; private final String desc;
@Override @Override
public String getId() { return name(); } public String getId() {
return name();
}
@Override @Override
public String getText() { return desc; } public String getText() {
return desc;
}
} }

View File

@@ -18,8 +18,12 @@ public enum EventType implements EnumType {
private final String desc; private final String desc;
@Override @Override
public String getId() { return name(); } public String getId() {
return name();
}
@Override @Override
public String getText() { return desc; } public String getText() {
return desc;
}
} }

View File

@@ -3,11 +3,10 @@ package com.kamco.cd.kamcoback.postgres;
import jakarta.persistence.Column; import jakarta.persistence.Column;
import jakarta.persistence.MappedSuperclass; import jakarta.persistence.MappedSuperclass;
import jakarta.persistence.PrePersist; import jakarta.persistence.PrePersist;
import java.time.ZonedDateTime;
import lombok.Getter; import lombok.Getter;
import org.springframework.data.annotation.CreatedDate; import org.springframework.data.annotation.CreatedDate;
import java.time.ZonedDateTime;
@Getter @Getter
@MappedSuperclass @MappedSuperclass
public class CommonCreateEntity { public class CommonCreateEntity {

View File

@@ -3,24 +3,22 @@ package com.kamco.cd.kamcoback.postgres.core;
import com.kamco.cd.kamcoback.common.service.BaseCoreService; import com.kamco.cd.kamcoback.common.service.BaseCoreService;
import com.kamco.cd.kamcoback.log.dto.AuditLogDto; import com.kamco.cd.kamcoback.log.dto.AuditLogDto;
import com.kamco.cd.kamcoback.postgres.repository.log.AuditLogRepository; import com.kamco.cd.kamcoback.postgres.repository.log.AuditLogRepository;
import java.time.LocalDate;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page; import org.springframework.data.domain.Page;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDate;
@Service @Service
@RequiredArgsConstructor @RequiredArgsConstructor
@Transactional(readOnly = true) @Transactional(readOnly = true)
public class AuditLogCoreService implements BaseCoreService<AuditLogDto.AuditList, Long, AuditLogDto.DailySearchReq> { public class AuditLogCoreService
implements BaseCoreService<AuditLogDto.AuditList, Long, AuditLogDto.DailySearchReq> {
private final AuditLogRepository auditLogRepository; private final AuditLogRepository auditLogRepository;
@Override @Override
public void remove(Long aLong) { public void remove(Long aLong) {}
}
@Override @Override
public AuditLogDto.AuditList getOneById(Long aLong) { public AuditLogDto.AuditList getOneById(Long aLong) {
@@ -32,27 +30,33 @@ public class AuditLogCoreService implements BaseCoreService<AuditLogDto.AuditLis
return null; return null;
} }
public Page<AuditLogDto.AuditList> getLogByDaily(AuditLogDto.DailySearchReq searchRange, LocalDate startDate, LocalDate endDate) { public Page<AuditLogDto.AuditList> getLogByDaily(
AuditLogDto.DailySearchReq searchRange, LocalDate startDate, LocalDate endDate) {
return auditLogRepository.findLogByDaily(searchRange, startDate, endDate); return auditLogRepository.findLogByDaily(searchRange, startDate, endDate);
} }
public Page<AuditLogDto.AuditList> getLogByMenu(AuditLogDto.MenuUserSearchReq searchRange, String searchValue) { public Page<AuditLogDto.AuditList> getLogByMenu(
AuditLogDto.MenuUserSearchReq searchRange, String searchValue) {
return auditLogRepository.findLogByMenu(searchRange, searchValue); return auditLogRepository.findLogByMenu(searchRange, searchValue);
} }
public Page<AuditLogDto.AuditList> getLogByAccount(AuditLogDto.MenuUserSearchReq searchRange, String searchValue) { public Page<AuditLogDto.AuditList> getLogByAccount(
AuditLogDto.MenuUserSearchReq searchRange, String searchValue) {
return auditLogRepository.findLogByAccount(searchRange, searchValue); return auditLogRepository.findLogByAccount(searchRange, searchValue);
} }
public Page<AuditLogDto.AuditDetail> getLogByDailyResult(AuditLogDto.DailySearchReq searchRange, LocalDate logDate) { public Page<AuditLogDto.AuditDetail> getLogByDailyResult(
AuditLogDto.DailySearchReq searchRange, LocalDate logDate) {
return auditLogRepository.findLogByDailyResult(searchRange, logDate); return auditLogRepository.findLogByDailyResult(searchRange, logDate);
} }
public Page<AuditLogDto.AuditDetail> getLogByMenuResult(AuditLogDto.MenuUserSearchReq searchRange, String menuId) { public Page<AuditLogDto.AuditDetail> getLogByMenuResult(
AuditLogDto.MenuUserSearchReq searchRange, String menuId) {
return auditLogRepository.findLogByMenuResult(searchRange, menuId); return auditLogRepository.findLogByMenuResult(searchRange, menuId);
} }
public Page<AuditLogDto.AuditDetail> getLogByAccountResult(AuditLogDto.MenuUserSearchReq searchRange, Long accountId) { public Page<AuditLogDto.AuditDetail> getLogByAccountResult(
AuditLogDto.MenuUserSearchReq searchRange, Long accountId) {
return auditLogRepository.findLogByAccountResult(searchRange, accountId); return auditLogRepository.findLogByAccountResult(searchRange, accountId);
} }
} }

View File

@@ -14,34 +14,52 @@ import org.springframework.stereotype.Service;
@Service @Service
@RequiredArgsConstructor @RequiredArgsConstructor
public class CommonCodeCoreService implements BaseCoreService<CommonCodeDto.Basic, Long, SearchReq> { public class CommonCodeCoreService
implements BaseCoreService<CommonCodeDto.Basic, Long, SearchReq> {
private final CommonCodeRepository commonCodeRepository; private final CommonCodeRepository commonCodeRepository;
public List<CommonCodeDto.Basic> findAll() { public List<CommonCodeDto.Basic> findAll() {
return commonCodeRepository.findByAll().stream().map(CommonCodeEntity::toDto).toList(); return commonCodeRepository.findByAll().stream().map(CommonCodeEntity::toDto).toList();
} }
public CommonCodeDto.Basic save(CommonCodeDto.AddReq req) { public CommonCodeDto.Basic save(CommonCodeDto.AddReq req) {
if(req.getParentId() != null){ if (req.getParentId() != null) {
CommonCodeEntity parentCommonCodeEntity = commonCodeRepository.findById(req.getParentId()) CommonCodeEntity parentCommonCodeEntity =
.orElseThrow(() -> new EntityNotFoundException("parent id 를 찾을 수 없습니다. id : " + req.getParentId())); commonCodeRepository
.findById(req.getParentId())
.orElseThrow(
() ->
new EntityNotFoundException(
"parent id 를 찾을 수 없습니다. id : " + req.getParentId()));
CommonCodeEntity entity = new CommonCodeEntity(req.getCode(), req.getName(), req.getDescription(), req.getOrder(), req.isUsed()); CommonCodeEntity entity =
new CommonCodeEntity(
req.getCode(), req.getName(), req.getDescription(), req.getOrder(), req.isUsed());
entity.addParent(parentCommonCodeEntity); entity.addParent(parentCommonCodeEntity);
return commonCodeRepository.save(entity).toDto(); return commonCodeRepository.save(entity).toDto();
} }
CommonCodeEntity entity = new CommonCodeEntity(req.getCode(), req.getName(), req.getDescription(), req.getOrder(), req.isUsed()); CommonCodeEntity entity =
new CommonCodeEntity(
req.getCode(), req.getName(), req.getDescription(), req.getOrder(), req.isUsed());
return commonCodeRepository.save(entity).toDto(); return commonCodeRepository.save(entity).toDto();
} }
public CommonCodeDto.Basic update(Long id, CommonCodeDto.ModifyReq req) { public CommonCodeDto.Basic update(Long id, CommonCodeDto.ModifyReq req) {
CommonCodeEntity found = commonCodeRepository.findByCodeId(id) CommonCodeEntity found =
.orElseThrow(()->new EntityNotFoundException("common code 를 찾을 수 없습니다. id : " + id)); commonCodeRepository
.findByCodeId(id)
.orElseThrow(() -> new EntityNotFoundException("common code 를 찾을 수 없습니다. id : " + id));
CommonCodeEntity entity = new CommonCodeEntity( id, req.getName(), req.getDescription(), req.getOrder(), req.isUsed(), found.getDeleted()); CommonCodeEntity entity =
new CommonCodeEntity(
id,
req.getName(),
req.getDescription(),
req.getOrder(),
req.isUsed(),
found.getDeleted());
return commonCodeRepository.save(entity).toDto(); return commonCodeRepository.save(entity).toDto();
} }
@@ -56,8 +74,10 @@ public class CommonCodeCoreService implements BaseCoreService<CommonCodeDto.Basi
@Override @Override
public void remove(Long id) { public void remove(Long id) {
CommonCodeEntity entity = commonCodeRepository.findByCodeId(id) CommonCodeEntity entity =
.orElseThrow(()->new EntityNotFoundException("code를 찾을 수 없습니다. id " + id)); commonCodeRepository
.findByCodeId(id)
.orElseThrow(() -> new EntityNotFoundException("code를 찾을 수 없습니다. id " + id));
// 하위 코드 deleted = false 업데이트 // 하위 코드 deleted = false 업데이트
entity.getChildren().forEach(CommonCodeEntity::deleted); entity.getChildren().forEach(CommonCodeEntity::deleted);
@@ -67,8 +87,10 @@ public class CommonCodeCoreService implements BaseCoreService<CommonCodeDto.Basi
@Override @Override
public Basic getOneById(Long id) { public Basic getOneById(Long id) {
CommonCodeEntity entity = commonCodeRepository.findByCodeId(id) CommonCodeEntity entity =
.orElseThrow(()->new EntityNotFoundException("code를 찾을 수 없습니다. id " + id)); commonCodeRepository
.findByCodeId(id)
.orElseThrow(() -> new EntityNotFoundException("code를 찾을 수 없습니다. id " + id));
return entity.toDto(); return entity.toDto();
} }

View File

@@ -1,21 +1,18 @@
package com.kamco.cd.kamcoback.postgres.core; package com.kamco.cd.kamcoback.postgres.core;
import com.kamco.cd.kamcoback.common.service.BaseCoreService; import com.kamco.cd.kamcoback.common.service.BaseCoreService;
import com.kamco.cd.kamcoback.log.dto.AuditLogDto;
import com.kamco.cd.kamcoback.log.dto.ErrorLogDto; import com.kamco.cd.kamcoback.log.dto.ErrorLogDto;
import com.kamco.cd.kamcoback.postgres.repository.log.AuditLogRepository;
import com.kamco.cd.kamcoback.postgres.repository.log.ErrorLogRepository; import com.kamco.cd.kamcoback.postgres.repository.log.ErrorLogRepository;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page; import org.springframework.data.domain.Page;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDate;
@Service @Service
@RequiredArgsConstructor @RequiredArgsConstructor
@Transactional(readOnly = true) @Transactional(readOnly = true)
public class ErrorLogCoreService implements BaseCoreService<ErrorLogDto.Basic, Long, ErrorLogDto.ErrorSearchReq> { public class ErrorLogCoreService
implements BaseCoreService<ErrorLogDto.Basic, Long, ErrorLogDto.ErrorSearchReq> {
private final ErrorLogRepository errorLogRepository; private final ErrorLogRepository errorLogRepository;

View File

@@ -43,7 +43,15 @@ public class AuditLogEntity extends CommonCreateEntity {
@Column(name = "error_log_uid") @Column(name = "error_log_uid")
private Long errorLogUid; private Long errorLogUid;
public AuditLogEntity(Long userUid, EventType eventType, EventStatus eventStatus, String menuUid, String ipAddress, String requestUri, String requestBody, Long errorLogUid) { public AuditLogEntity(
Long userUid,
EventType eventType,
EventStatus eventStatus,
String menuUid,
String ipAddress,
String requestUri,
String requestBody,
Long errorLogUid) {
this.userUid = userUid; this.userUid = userUid;
this.eventType = eventType; this.eventType = eventType;
this.eventStatus = eventStatus; this.eventStatus = eventStatus;
@@ -56,29 +64,37 @@ public class AuditLogEntity extends CommonCreateEntity {
public AuditLogDto.Basic toDto() { public AuditLogDto.Basic toDto() {
return new AuditLogDto.Basic( return new AuditLogDto.Basic(
this.id, this.id,
this.userUid, this.userUid,
this.eventType, this.eventType,
this.eventStatus, this.eventStatus,
this.menuUid, this.menuUid,
this.ipAddress, this.ipAddress,
this.requestUri, this.requestUri,
this.requestBody, this.requestBody,
this.errorLogUid, this.errorLogUid,
super.getCreatedDate()); super.getCreatedDate());
} }
@Override @Override
public String toString(){ public String toString() {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
sb.append(this.id).append("\n") sb.append(this.id)
.append(this.userUid).append("\n") .append("\n")
.append(this.eventType).append("\n") .append(this.userUid)
.append(this.eventStatus).append("\n") .append("\n")
.append(this.menuUid).append("\n") .append(this.eventType)
.append(this.ipAddress).append("\n") .append("\n")
.append(this.requestUri).append("\n") .append(this.eventStatus)
.append(this.requestBody).append("\n") .append("\n")
.append(this.menuUid)
.append("\n")
.append(this.ipAddress)
.append("\n")
.append(this.requestUri)
.append("\n")
.append(this.requestBody)
.append("\n")
.append(this.errorLogUid); .append(this.errorLogUid);
return sb.toString(); return sb.toString();
} }

View File

@@ -61,7 +61,8 @@ public class CommonCodeEntity extends CommonDateEntity {
@OneToMany(mappedBy = "parent", fetch = FetchType.LAZY, cascade = CascadeType.ALL) @OneToMany(mappedBy = "parent", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
private List<CommonCodeEntity> children = new ArrayList<>(); private List<CommonCodeEntity> children = new ArrayList<>();
public CommonCodeEntity(String code, String name, String description, Integer order, Boolean used) { public CommonCodeEntity(
String code, String name, String description, Integer order, Boolean used) {
this.code = code; this.code = code;
this.name = name; this.name = name;
this.description = description; this.description = description;
@@ -69,7 +70,8 @@ public class CommonCodeEntity extends CommonDateEntity {
this.used = used; this.used = used;
} }
public CommonCodeEntity(Long id, String name, String description, Integer order, Boolean used, Boolean deleted) { public CommonCodeEntity(
Long id, String name, String description, Integer order, Boolean used, Boolean deleted) {
this.id = id; this.id = id;
this.name = name; this.name = name;
this.description = description; this.description = description;
@@ -80,19 +82,18 @@ public class CommonCodeEntity extends CommonDateEntity {
public CommonCodeDto.Basic toDto() { public CommonCodeDto.Basic toDto() {
return new CommonCodeDto.Basic( return new CommonCodeDto.Basic(
this.id, this.id,
this.code, this.code,
this.description, this.description,
this.name, this.name,
this.order, this.order,
this.used, this.used,
this.deleted, this.deleted,
this.children.stream().map(CommonCodeEntity::toDto).toList(), this.children.stream().map(CommonCodeEntity::toDto).toList(),
super.getCreatedDate(), super.getCreatedDate(),
super.getModifiedDate()); super.getModifiedDate());
} }
public void addParent(CommonCodeEntity parent) { public void addParent(CommonCodeEntity parent) {
this.parent = parent; this.parent = parent;
} }

View File

@@ -4,13 +4,11 @@ import com.kamco.cd.kamcoback.log.dto.ErrorLogDto;
import com.kamco.cd.kamcoback.log.dto.EventType; import com.kamco.cd.kamcoback.log.dto.EventType;
import com.kamco.cd.kamcoback.postgres.CommonCreateEntity; import com.kamco.cd.kamcoback.postgres.CommonCreateEntity;
import jakarta.persistence.*; import jakarta.persistence.*;
import java.time.ZonedDateTime;
import lombok.AccessLevel; import lombok.AccessLevel;
import lombok.Getter; import lombok.Getter;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import java.time.LocalDateTime;
import java.time.ZonedDateTime;
@Entity @Entity
@Getter @Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED) @NoArgsConstructor(access = AccessLevel.PROTECTED)
@@ -30,14 +28,22 @@ public class ErrorLogEntity extends CommonCreateEntity {
@Enumerated(EnumType.STRING) @Enumerated(EnumType.STRING)
private ErrorLogDto.LogErrorLevel errorLevel; private ErrorLogDto.LogErrorLevel errorLevel;
private String errorCode; private String errorCode;
private String errorMessage; private String errorMessage;
private String stackTrace; private String stackTrace;
private Long handlerUid; private Long handlerUid;
private ZonedDateTime handledDttm; private ZonedDateTime handledDttm;
public ErrorLogEntity(String requestId, EventType errorType, ErrorLogDto.LogErrorLevel errorLevel, String errorCode, String errorMessage, String stackTrace public ErrorLogEntity(
, Long handlerUid, ZonedDateTime handledDttm) { String requestId,
EventType errorType,
ErrorLogDto.LogErrorLevel errorLevel,
String errorCode,
String errorMessage,
String stackTrace,
Long handlerUid,
ZonedDateTime handledDttm) {
this.requestId = requestId; this.requestId = requestId;
this.errorType = errorType; this.errorType = errorType;
this.errorLevel = errorLevel; this.errorLevel = errorLevel;

View File

@@ -1,17 +1,14 @@
package com.kamco.cd.kamcoback.postgres.entity; package com.kamco.cd.kamcoback.postgres.entity;
import com.kamco.cd.kamcoback.log.dto.EventStatus;
import com.kamco.cd.kamcoback.log.dto.EventType;
import com.kamco.cd.kamcoback.postgres.CommonDateEntity; import com.kamco.cd.kamcoback.postgres.CommonDateEntity;
import jakarta.persistence.*; import jakarta.persistence.*;
import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.NotNull;
import java.util.ArrayList;
import java.util.List;
import lombok.AccessLevel; import lombok.AccessLevel;
import lombok.Getter; import lombok.Getter;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import java.util.ArrayList;
import java.util.List;
@Entity @Entity
@Getter @Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED) @NoArgsConstructor(access = AccessLevel.PROTECTED)

View File

@@ -1,15 +1,12 @@
package com.kamco.cd.kamcoback.postgres.entity; package com.kamco.cd.kamcoback.postgres.entity;
import com.kamco.cd.kamcoback.log.dto.ErrorLogDto;
import com.kamco.cd.kamcoback.log.dto.EventType;
import com.kamco.cd.kamcoback.postgres.CommonDateEntity; import com.kamco.cd.kamcoback.postgres.CommonDateEntity;
import jakarta.persistence.*; import jakarta.persistence.*;
import java.time.ZonedDateTime;
import lombok.AccessLevel; import lombok.AccessLevel;
import lombok.Getter; import lombok.Getter;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import java.time.ZonedDateTime;
@Entity @Entity
@Getter @Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED) @NoArgsConstructor(access = AccessLevel.PROTECTED)
@@ -27,15 +24,14 @@ public class UserEntity extends CommonDateEntity {
private String userId; private String userId;
@Column(name = "pswd") @Column(name = "pswd")
private String pswd; //TODO: 암호화 private String pswd; // TODO: 암호화
//@Enumerated(EnumType.STRING) // @Enumerated(EnumType.STRING)
private String state; //TODO: 추후 enum -> ACTIVE : 정상, LOCKED : 잠김, EXPIRED : 만료, WITHDRAWAL : 탈퇴 private String state; // TODO: 추후 enum -> ACTIVE : 정상, LOCKED : 잠김, EXPIRED : 만료, WITHDRAWAL : 탈퇴
private ZonedDateTime dateWithdrawal; private ZonedDateTime dateWithdrawal;
private String userEmail; private String userEmail;
private Long createdUid; private Long createdUid;
private Long updatedUid; private Long updatedUid;
} }

View File

@@ -3,6 +3,5 @@ package com.kamco.cd.kamcoback.postgres.repository;
import com.kamco.cd.kamcoback.postgres.entity.CommonCodeEntity; import com.kamco.cd.kamcoback.postgres.entity.CommonCodeEntity;
import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaRepository;
public interface CommonCodeRepository extends JpaRepository<CommonCodeEntity, Long>, CommonCodeRepositoryCustom { public interface CommonCodeRepository
extends JpaRepository<CommonCodeEntity, Long>, CommonCodeRepositoryCustom {}
}

View File

@@ -7,7 +7,10 @@ import java.util.Optional;
public interface CommonCodeRepositoryCustom { public interface CommonCodeRepositoryCustom {
Optional<CommonCodeEntity> findByCodeId(Long id); Optional<CommonCodeEntity> findByCodeId(Long id);
Optional<CommonCodeEntity> findByCode(String code); Optional<CommonCodeEntity> findByCode(String code);
List<CommonCodeEntity> findByAll(); List<CommonCodeEntity> findByAll();
void updateOrder(CommonCodeDto.OrderReq req); void updateOrder(CommonCodeDto.OrderReq req);
} }

View File

@@ -6,10 +6,7 @@ import com.kamco.cd.kamcoback.code.dto.CommonCodeDto;
import com.kamco.cd.kamcoback.code.dto.CommonCodeDto.OrderReqDetail; import com.kamco.cd.kamcoback.code.dto.CommonCodeDto.OrderReqDetail;
import com.kamco.cd.kamcoback.postgres.entity.CommonCodeEntity; import com.kamco.cd.kamcoback.postgres.entity.CommonCodeEntity;
import com.kamco.cd.kamcoback.postgres.entity.QCommonCodeEntity; import com.kamco.cd.kamcoback.postgres.entity.QCommonCodeEntity;
import com.querydsl.core.types.dsl.Expressions;
import com.querydsl.jpa.impl.JPAQueryFactory; import com.querydsl.jpa.impl.JPAQueryFactory;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Optional; import java.util.Optional;
@@ -17,7 +14,8 @@ import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import org.springframework.data.jpa.repository.support.QuerydslRepositorySupport; import org.springframework.data.jpa.repository.support.QuerydslRepositorySupport;
public class CommonCodeRepositoryImpl extends QuerydslRepositorySupport implements CommonCodeRepositoryCustom { public class CommonCodeRepositoryImpl extends QuerydslRepositorySupport
implements CommonCodeRepositoryCustom {
private final JPAQueryFactory queryFactory; private final JPAQueryFactory queryFactory;
@@ -30,75 +28,65 @@ public class CommonCodeRepositoryImpl extends QuerydslRepositorySupport implemen
public Optional<CommonCodeEntity> findByCodeId(Long id) { public Optional<CommonCodeEntity> findByCodeId(Long id) {
QCommonCodeEntity child = new QCommonCodeEntity("child"); QCommonCodeEntity child = new QCommonCodeEntity("child");
return Optional.ofNullable( return Optional.ofNullable(
queryFactory queryFactory
.selectFrom(commonCodeEntity) .selectFrom(commonCodeEntity)
.leftJoin(commonCodeEntity.children, child) .leftJoin(commonCodeEntity.children, child)
.fetchJoin() .fetchJoin()
.where( .where(commonCodeEntity.id.eq(id), commonCodeEntity.deleted.isFalse())
commonCodeEntity.id.eq(id), .orderBy(commonCodeEntity.order.asc(), child.order.asc())
commonCodeEntity.deleted.isFalse() .fetchOne());
)
.orderBy(commonCodeEntity.order.asc(), child.order.asc())
.fetchOne()
);
} }
@Override @Override
public Optional<CommonCodeEntity> findByCode(String code) { public Optional<CommonCodeEntity> findByCode(String code) {
QCommonCodeEntity child = new QCommonCodeEntity("child"); QCommonCodeEntity child = new QCommonCodeEntity("child");
return Optional.ofNullable( return Optional.ofNullable(
queryFactory queryFactory
.selectFrom(commonCodeEntity) .selectFrom(commonCodeEntity)
.leftJoin(commonCodeEntity.children, child) .leftJoin(commonCodeEntity.children, child)
.fetchJoin() .fetchJoin()
.where( .where(
commonCodeEntity.parent.isNull(), commonCodeEntity.parent.isNull(),
commonCodeEntity.code.eq(code), commonCodeEntity.code.eq(code),
commonCodeEntity.used.isTrue(), commonCodeEntity.used.isTrue(),
commonCodeEntity.deleted.isFalse() commonCodeEntity.deleted.isFalse())
) .orderBy(child.order.asc())
.orderBy(child.order.asc()) .fetchOne());
.fetchOne()
);
} }
@Override @Override
public List<CommonCodeEntity> findByAll() { public List<CommonCodeEntity> findByAll() {
QCommonCodeEntity child = new QCommonCodeEntity("child"); QCommonCodeEntity child = new QCommonCodeEntity("child");
return queryFactory return queryFactory
.selectFrom(commonCodeEntity) .selectFrom(commonCodeEntity)
.leftJoin(commonCodeEntity.children, child) .leftJoin(commonCodeEntity.children, child)
.fetchJoin() .fetchJoin()
.where( .where(commonCodeEntity.parent.isNull(), commonCodeEntity.deleted.isFalse())
commonCodeEntity.parent.isNull(), .orderBy(commonCodeEntity.order.asc(), child.order.asc())
commonCodeEntity.deleted.isFalse() .fetch();
)
.orderBy(commonCodeEntity.order.asc(), child.order.asc())
.fetch();
} }
@Override @Override
public void updateOrder(CommonCodeDto.OrderReq req) { public void updateOrder(CommonCodeDto.OrderReq req) {
Map<Long, Integer> orderMap = req.getOrders().stream(). Map<Long, Integer> orderMap =
collect(Collectors.toMap(OrderReqDetail::getId, OrderReqDetail::getOrder)); req.getOrders().stream()
.collect(Collectors.toMap(OrderReqDetail::getId, OrderReqDetail::getOrder));
List<CommonCodeEntity> entity = findAllByIds(orderMap.keySet()); List<CommonCodeEntity> entity = findAllByIds(orderMap.keySet());
entity.forEach(commonCodeEntity -> { entity.forEach(
Integer order = orderMap.get(commonCodeEntity.getId()); commonCodeEntity -> {
if(order != null) { Integer order = orderMap.get(commonCodeEntity.getId());
commonCodeEntity.updateOrder(order); if (order != null) {
} commonCodeEntity.updateOrder(order);
}); }
});
} }
private List<CommonCodeEntity> findAllByIds(Set<Long> ids) { private List<CommonCodeEntity> findAllByIds(Set<Long> ids) {
return queryFactory return queryFactory
.selectFrom(commonCodeEntity) .selectFrom(commonCodeEntity)
.where( .where(commonCodeEntity.id.in(ids), commonCodeEntity.deleted.isFalse())
commonCodeEntity.id.in(ids), .fetch();
commonCodeEntity.deleted.isFalse()
)
.fetch();
} }
} }

View File

@@ -3,4 +3,5 @@ package com.kamco.cd.kamcoback.postgres.repository.log;
import com.kamco.cd.kamcoback.postgres.entity.AuditLogEntity; import com.kamco.cd.kamcoback.postgres.entity.AuditLogEntity;
import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaRepository;
public interface AuditLogRepository extends JpaRepository<AuditLogEntity, Long>, AuditLogRepositoryCustom {} public interface AuditLogRepository
extends JpaRepository<AuditLogEntity, Long>, AuditLogRepositoryCustom {}

View File

@@ -1,21 +1,26 @@
package com.kamco.cd.kamcoback.postgres.repository.log; package com.kamco.cd.kamcoback.postgres.repository.log;
import com.kamco.cd.kamcoback.log.dto.AuditLogDto; import com.kamco.cd.kamcoback.log.dto.AuditLogDto;
import org.springframework.data.domain.Page;
import java.time.LocalDate; import java.time.LocalDate;
import org.springframework.data.domain.Page;
public interface AuditLogRepositoryCustom { public interface AuditLogRepositoryCustom {
Page<AuditLogDto.AuditList> findLogByDaily(AuditLogDto.DailySearchReq searchReq, LocalDate startDate, LocalDate endDate); Page<AuditLogDto.AuditList> findLogByDaily(
AuditLogDto.DailySearchReq searchReq, LocalDate startDate, LocalDate endDate);
Page<AuditLogDto.AuditList> findLogByMenu(AuditLogDto.MenuUserSearchReq searchReq, String searchValue); Page<AuditLogDto.AuditList> findLogByMenu(
AuditLogDto.MenuUserSearchReq searchReq, String searchValue);
Page<AuditLogDto.AuditList> findLogByAccount(AuditLogDto.MenuUserSearchReq searchReq, String searchValue); Page<AuditLogDto.AuditList> findLogByAccount(
AuditLogDto.MenuUserSearchReq searchReq, String searchValue);
Page<AuditLogDto.AuditDetail> findLogByDailyResult(AuditLogDto.DailySearchReq searchReq, LocalDate logDate); Page<AuditLogDto.AuditDetail> findLogByDailyResult(
AuditLogDto.DailySearchReq searchReq, LocalDate logDate);
Page<AuditLogDto.AuditDetail> findLogByMenuResult(AuditLogDto.MenuUserSearchReq searchReq, String menuId); Page<AuditLogDto.AuditDetail> findLogByMenuResult(
AuditLogDto.MenuUserSearchReq searchReq, String menuId);
Page<AuditLogDto.AuditDetail> findLogByAccountResult(AuditLogDto.MenuUserSearchReq searchReq, Long accountId); Page<AuditLogDto.AuditDetail> findLogByAccountResult(
AuditLogDto.MenuUserSearchReq searchReq, Long accountId);
} }

View File

@@ -1,33 +1,32 @@
package com.kamco.cd.kamcoback.postgres.repository.log; package com.kamco.cd.kamcoback.postgres.repository.log;
import static com.kamco.cd.kamcoback.postgres.entity.QAuditLogEntity.auditLogEntity;
import static com.kamco.cd.kamcoback.postgres.entity.QErrorLogEntity.errorLogEntity;
import static com.kamco.cd.kamcoback.postgres.entity.QMenuEntity.menuEntity;
import static com.kamco.cd.kamcoback.postgres.entity.QUserEntity.userEntity;
import com.kamco.cd.kamcoback.log.dto.AuditLogDto; import com.kamco.cd.kamcoback.log.dto.AuditLogDto;
import com.kamco.cd.kamcoback.log.dto.ErrorLogDto; import com.kamco.cd.kamcoback.log.dto.ErrorLogDto;
import com.kamco.cd.kamcoback.log.dto.EventStatus; import com.kamco.cd.kamcoback.log.dto.EventStatus;
import com.kamco.cd.kamcoback.log.dto.EventType; import com.kamco.cd.kamcoback.log.dto.EventType;
import com.kamco.cd.kamcoback.postgres.entity.AuditLogEntity; import com.kamco.cd.kamcoback.postgres.entity.AuditLogEntity;
import com.kamco.cd.kamcoback.postgres.entity.QMenuEntity;
import com.querydsl.core.types.Projections; import com.querydsl.core.types.Projections;
import com.querydsl.core.types.dsl.*; import com.querydsl.core.types.dsl.*;
import com.querydsl.jpa.impl.JPAQuery;
import com.querydsl.jpa.impl.JPAQueryFactory; import com.querydsl.jpa.impl.JPAQueryFactory;
import io.micrometer.common.util.StringUtils; import io.micrometer.common.util.StringUtils;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.support.QuerydslRepositorySupport;
import java.time.LocalDate; import java.time.LocalDate;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.time.ZonedDateTime; import java.time.ZonedDateTime;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.support.QuerydslRepositorySupport;
import static com.kamco.cd.kamcoback.postgres.entity.QUserEntity.userEntity; public class AuditLogRepositoryImpl extends QuerydslRepositorySupport
import static com.kamco.cd.kamcoback.postgres.entity.QAuditLogEntity.auditLogEntity; implements AuditLogRepositoryCustom {
import static com.kamco.cd.kamcoback.postgres.entity.QErrorLogEntity.errorLogEntity;
import static com.kamco.cd.kamcoback.postgres.entity.QMenuEntity.menuEntity;
import com.kamco.cd.kamcoback.postgres.entity.QMenuEntity;
public class AuditLogRepositoryImpl extends QuerydslRepositorySupport implements AuditLogRepositoryCustom {
private final JPAQueryFactory queryFactory; private final JPAQueryFactory queryFactory;
private final StringExpression NULL_STRING = Expressions.stringTemplate("cast(null as text)"); private final StringExpression NULL_STRING = Expressions.stringTemplate("cast(null as text)");
@@ -37,304 +36,311 @@ public class AuditLogRepositoryImpl extends QuerydslRepositorySupport implements
} }
@Override @Override
public Page<AuditLogDto.AuditList> findLogByDaily(AuditLogDto.DailySearchReq searchReq, LocalDate startDate, LocalDate endDate) { public Page<AuditLogDto.AuditList> findLogByDaily(
AuditLogDto.DailySearchReq searchReq, LocalDate startDate, LocalDate endDate) {
DateTimeExpression<LocalDateTime> groupDateTime = DateTimeExpression<LocalDateTime> groupDateTime =
Expressions.dateTimeTemplate(LocalDateTime.class, "date_trunc('day', {0})", auditLogEntity.createdDate); Expressions.dateTimeTemplate(
LocalDateTime.class, "date_trunc('day', {0})", auditLogEntity.createdDate);
Pageable pageable = searchReq.toPageable(); Pageable pageable = searchReq.toPageable();
List<AuditLogDto.AuditList> foundContent = queryFactory List<AuditLogDto.AuditList> foundContent =
.select( queryFactory
Projections.constructor( .select(
AuditLogDto.AuditList.class, Projections.constructor(
groupDateTime.as("baseDate"), AuditLogDto.AuditList.class,
readCount().as("readCount"), groupDateTime.as("baseDate"),
cudCount().as("cudCount"), readCount().as("readCount"),
printCount().as("printCount"), cudCount().as("cudCount"),
downloadCount().as("downloadCount"), printCount().as("printCount"),
auditLogEntity.count().as("totalCount") downloadCount().as("downloadCount"),
) auditLogEntity.count().as("totalCount")))
) .from(auditLogEntity)
.from(auditLogEntity) .where(eventEndedAtBetween(startDate, endDate))
.where( .groupBy(groupDateTime)
eventEndedAtBetween(startDate, endDate) .offset(pageable.getOffset())
) .limit(pageable.getPageSize())
.groupBy(groupDateTime) .orderBy(groupDateTime.desc())
.offset(pageable.getOffset()) .fetch();
.limit(pageable.getPageSize())
.orderBy(groupDateTime.desc())
.fetch();
Long countQuery = queryFactory Long countQuery =
.select(groupDateTime.countDistinct()) queryFactory
.from(auditLogEntity) .select(groupDateTime.countDistinct())
.where( .from(auditLogEntity)
eventEndedAtBetween(startDate, endDate) .where(eventEndedAtBetween(startDate, endDate))
) .fetchOne();
.fetchOne();
return new PageImpl<>(foundContent, pageable, countQuery); return new PageImpl<>(foundContent, pageable, countQuery);
} }
@Override @Override
public Page<AuditLogDto.AuditList> findLogByMenu(AuditLogDto.MenuUserSearchReq searchReq, String searchValue) { public Page<AuditLogDto.AuditList> findLogByMenu(
AuditLogDto.MenuUserSearchReq searchReq, String searchValue) {
Pageable pageable = searchReq.toPageable(); Pageable pageable = searchReq.toPageable();
List<AuditLogDto.AuditList> foundContent = queryFactory List<AuditLogDto.AuditList> foundContent =
.select( queryFactory
Projections.constructor( .select(
AuditLogDto.AuditList.class, Projections.constructor(
auditLogEntity.menuUid.as("menuId"), AuditLogDto.AuditList.class,
menuEntity.menuNm.max().as("menuName"), auditLogEntity.menuUid.as("menuId"),
readCount().as("readCount"), menuEntity.menuNm.max().as("menuName"),
cudCount().as("cudCount"), readCount().as("readCount"),
printCount().as("printCount"), cudCount().as("cudCount"),
downloadCount().as("downloadCount"), printCount().as("printCount"),
auditLogEntity.count().as("totalCount") downloadCount().as("downloadCount"),
) auditLogEntity.count().as("totalCount")))
) .from(auditLogEntity)
.from(auditLogEntity) .leftJoin(menuEntity)
.leftJoin(menuEntity).on(auditLogEntity.menuUid.eq(menuEntity.menuUid)) .on(auditLogEntity.menuUid.eq(menuEntity.menuUid))
.where( .where(menuNameEquals(searchValue))
menuNameEquals(searchValue) .groupBy(auditLogEntity.menuUid)
) .offset(pageable.getOffset())
.groupBy(auditLogEntity.menuUid) .limit(pageable.getPageSize())
.offset(pageable.getOffset()) .orderBy(auditLogEntity.createdDate.max().desc())
.limit(pageable.getPageSize()) .fetch();
.orderBy(auditLogEntity.createdDate.max().desc())
.fetch();
// count query group by 를 지정하면 하나의 row 가 아니라 그룹핑된 여러 row 가 나올 수 있다. // count query group by 를 지정하면 하나의 row 가 아니라 그룹핑된 여러 row 가 나올 수 있다.
// select query 의 group by 대상의 컬럼을 count query 에선 select distinct 로 처리 한다. // select query 의 group by 대상의 컬럼을 count query 에선 select distinct 로 처리 한다.
Long countQuery = queryFactory Long countQuery =
.select(auditLogEntity.menuUid.countDistinct()) queryFactory
.from(auditLogEntity) .select(auditLogEntity.menuUid.countDistinct())
.leftJoin(menuEntity).on(auditLogEntity.menuUid.eq(menuEntity.menuUid)) .from(auditLogEntity)
.where(menuNameEquals(searchValue)) .leftJoin(menuEntity)
.fetchOne(); .on(auditLogEntity.menuUid.eq(menuEntity.menuUid))
.where(menuNameEquals(searchValue))
.fetchOne();
return new PageImpl<>(foundContent, pageable, countQuery); return new PageImpl<>(foundContent, pageable, countQuery);
} }
@Override @Override
public Page<AuditLogDto.AuditList> findLogByAccount(AuditLogDto.MenuUserSearchReq searchReq, String searchValue) { public Page<AuditLogDto.AuditList> findLogByAccount(
AuditLogDto.MenuUserSearchReq searchReq, String searchValue) {
Pageable pageable = searchReq.toPageable(); Pageable pageable = searchReq.toPageable();
List<AuditLogDto.AuditList> foundContent = queryFactory List<AuditLogDto.AuditList> foundContent =
.select( queryFactory
Projections.constructor( .select(
AuditLogDto.AuditList.class, Projections.constructor(
auditLogEntity.userUid.as("accountId"), AuditLogDto.AuditList.class,
userEntity.userId.as("loginId"), auditLogEntity.userUid.as("accountId"),
userEntity.userNm.as("username"), userEntity.userId.as("loginId"),
readCount().as("readCount"), userEntity.userNm.as("username"),
cudCount().as("cudCount"), readCount().as("readCount"),
printCount().as("printCount"), cudCount().as("cudCount"),
downloadCount().as("downloadCount"), printCount().as("printCount"),
auditLogEntity.count().as("totalCount") downloadCount().as("downloadCount"),
) auditLogEntity.count().as("totalCount")))
) .from(auditLogEntity)
.from(auditLogEntity) .leftJoin(userEntity)
.leftJoin(userEntity).on(auditLogEntity.userUid.eq(userEntity.id)) .on(auditLogEntity.userUid.eq(userEntity.id))
.where( .where(loginIdOrUsernameContains(searchValue))
loginIdOrUsernameContains(searchValue) .groupBy(auditLogEntity.userUid, userEntity.userId, userEntity.userNm)
) .offset(pageable.getOffset())
.groupBy(auditLogEntity.userUid, userEntity.userId, userEntity.userNm) .limit(pageable.getPageSize())
.offset(pageable.getOffset()) // .orderBy(auditLogEntity.eventEndedAt.max().desc())
.limit(pageable.getPageSize()) .fetch();
// .orderBy(auditLogEntity.eventEndedAt.max().desc())
.fetch();
Long countQuery = queryFactory Long countQuery =
.select(auditLogEntity.userUid.countDistinct()) queryFactory
.from(auditLogEntity) .select(auditLogEntity.userUid.countDistinct())
.leftJoin(userEntity).on(auditLogEntity.userUid.eq(userEntity.id)) .from(auditLogEntity)
.where(loginIdOrUsernameContains(searchValue)) .leftJoin(userEntity)
.fetchOne(); .on(auditLogEntity.userUid.eq(userEntity.id))
.where(loginIdOrUsernameContains(searchValue))
.fetchOne();
return new PageImpl<>(foundContent, pageable, countQuery); return new PageImpl<>(foundContent, pageable, countQuery);
} }
@Override @Override
public Page<AuditLogDto.AuditDetail> findLogByDailyResult(AuditLogDto.DailySearchReq searchReq, LocalDate logDate) { public Page<AuditLogDto.AuditDetail> findLogByDailyResult(
AuditLogDto.DailySearchReq searchReq, LocalDate logDate) {
Pageable pageable = searchReq.toPageable(); Pageable pageable = searchReq.toPageable();
QMenuEntity parent = new QMenuEntity("parent"); QMenuEntity parent = new QMenuEntity("parent");
// 1depth menu name // 1depth menu name
StringExpression parentMenuName = StringExpression parentMenuName =
new CaseBuilder() new CaseBuilder()
.when(parent.menuUid.isNull()).then(menuEntity.menuNm) .when(parent.menuUid.isNull())
.otherwise(parent.menuNm); .then(menuEntity.menuNm)
.otherwise(parent.menuNm);
// 2depth menu name // 2depth menu name
StringExpression menuName = StringExpression menuName =
new CaseBuilder() new CaseBuilder()
.when(parent.menuUid.isNull()).then(NULL_STRING) .when(parent.menuUid.isNull())
.otherwise(menuEntity.menuNm); .then(NULL_STRING)
.otherwise(menuEntity.menuNm);
List<AuditLogDto.AuditDetail> foundContent = queryFactory List<AuditLogDto.AuditDetail> foundContent =
.select( queryFactory
Projections.constructor( .select(
AuditLogDto.AuditDetail.class, Projections.constructor(
auditLogEntity.id.as("logId"), AuditLogDto.AuditDetail.class,
userEntity.userNm.as("userName"), auditLogEntity.id.as("logId"),
userEntity.userId.as("loginId"), userEntity.userNm.as("userName"),
menuEntity.menuNm.as("menuName"), userEntity.userId.as("loginId"),
auditLogEntity.eventType.as("eventType"), menuEntity.menuNm.as("menuName"),
Projections.constructor( auditLogEntity.eventType.as("eventType"),
AuditLogDto.LogDetail.class, Projections.constructor(
Expressions.constant("한국자산관리공사"), //serviceName AuditLogDto.LogDetail.class,
parentMenuName.as("parentMenuName"), Expressions.constant("한국자산관리공사"), // serviceName
menuName, parentMenuName.as("parentMenuName"),
menuEntity.menuUrl.as("menuUrl"), menuName,
menuEntity.description.as("menuDescription"), menuEntity.menuUrl.as("menuUrl"),
menuEntity.menuOrder.as("sortOrder"), menuEntity.description.as("menuDescription"),
menuEntity.isUse.as("used") menuEntity.menuOrder.as("sortOrder"),
) menuEntity.isUse.as("used"))))
) .from(auditLogEntity)
) .leftJoin(menuEntity)
.from(auditLogEntity) .on(auditLogEntity.menuUid.eq(menuEntity.menuUid))
.leftJoin(menuEntity).on(auditLogEntity.menuUid.eq(menuEntity.menuUid)) .leftJoin(menuEntity.parent, parent)
.leftJoin(menuEntity.parent, parent) .leftJoin(userEntity)
.leftJoin(userEntity).on(auditLogEntity.userUid.eq(userEntity.id)) .on(auditLogEntity.userUid.eq(userEntity.id))
.where( .where(eventEndedAtEqDate(logDate))
eventEndedAtEqDate(logDate) .offset(pageable.getOffset())
) .limit(pageable.getPageSize())
.offset(pageable.getOffset()) .orderBy(auditLogEntity.createdDate.desc())
.limit(pageable.getPageSize()) .fetch();
.orderBy(auditLogEntity.createdDate.desc())
.fetch();
Long countQuery = queryFactory Long countQuery =
.select(auditLogEntity.id.countDistinct()) queryFactory
.from(auditLogEntity) .select(auditLogEntity.id.countDistinct())
.leftJoin(menuEntity).on(auditLogEntity.menuUid.eq(menuEntity.menuUid)) .from(auditLogEntity)
.leftJoin(menuEntity.parent, parent) .leftJoin(menuEntity)
.leftJoin(userEntity).on(auditLogEntity.userUid.eq(userEntity.id)) .on(auditLogEntity.menuUid.eq(menuEntity.menuUid))
.where( .leftJoin(menuEntity.parent, parent)
eventEndedAtEqDate(logDate) .leftJoin(userEntity)
) .on(auditLogEntity.userUid.eq(userEntity.id))
.fetchOne(); .where(eventEndedAtEqDate(logDate))
.fetchOne();
return new PageImpl<>(foundContent, pageable, countQuery); return new PageImpl<>(foundContent, pageable, countQuery);
} }
@Override @Override
public Page<AuditLogDto.AuditDetail> findLogByMenuResult(AuditLogDto.MenuUserSearchReq searchReq, String menuUid) { public Page<AuditLogDto.AuditDetail> findLogByMenuResult(
AuditLogDto.MenuUserSearchReq searchReq, String menuUid) {
Pageable pageable = searchReq.toPageable(); Pageable pageable = searchReq.toPageable();
QMenuEntity parent = new QMenuEntity("parent"); QMenuEntity parent = new QMenuEntity("parent");
// 1depth menu name // 1depth menu name
StringExpression parentMenuName = StringExpression parentMenuName =
new CaseBuilder() new CaseBuilder()
.when(parent.menuUid.isNull()).then(menuEntity.menuNm) .when(parent.menuUid.isNull())
.otherwise(parent.menuNm); .then(menuEntity.menuNm)
.otherwise(parent.menuNm);
// 2depth menu name // 2depth menu name
StringExpression menuName = StringExpression menuName =
new CaseBuilder() new CaseBuilder()
.when(parent.menuUid.isNull()).then(NULL_STRING) .when(parent.menuUid.isNull())
.otherwise(menuEntity.menuNm); .then(NULL_STRING)
.otherwise(menuEntity.menuNm);
List<AuditLogDto.AuditDetail> foundContent = queryFactory List<AuditLogDto.AuditDetail> foundContent =
.select( queryFactory
Projections.constructor( .select(
AuditLogDto.AuditDetail.class, Projections.constructor(
auditLogEntity.id.as("logId"), AuditLogDto.AuditDetail.class,
auditLogEntity.createdDate.as("logDateTime"), auditLogEntity.id.as("logId"),
userEntity.userNm.as("userName"), auditLogEntity.createdDate.as("logDateTime"),
userEntity.userId.as("loginId"), userEntity.userNm.as("userName"),
auditLogEntity.eventType.as("eventType"), userEntity.userId.as("loginId"),
Projections.constructor( auditLogEntity.eventType.as("eventType"),
AuditLogDto.LogDetail.class, Projections.constructor(
Expressions.constant("한국자산관리공사"), //serviceName AuditLogDto.LogDetail.class,
parentMenuName.as("parentMenuName"), Expressions.constant("한국자산관리공사"), // serviceName
menuName, parentMenuName.as("parentMenuName"),
menuEntity.menuUrl.as("menuUrl"), menuName,
menuEntity.description.as("menuDescription"), menuEntity.menuUrl.as("menuUrl"),
menuEntity.menuOrder.as("sortOrder"), menuEntity.description.as("menuDescription"),
menuEntity.isUse.as("used") menuEntity.menuOrder.as("sortOrder"),
) menuEntity.isUse.as("used"))))
) .from(auditLogEntity)
) .leftJoin(menuEntity)
.from(auditLogEntity) .on(auditLogEntity.menuUid.eq(menuEntity.menuUid))
.leftJoin(menuEntity).on(auditLogEntity.menuUid.eq(menuEntity.menuUid)) .leftJoin(menuEntity.parent, parent)
.leftJoin(menuEntity.parent, parent) .leftJoin(userEntity)
.leftJoin(userEntity).on(auditLogEntity.userUid.eq(userEntity.id)) .on(auditLogEntity.userUid.eq(userEntity.id))
.where( .where(menuUidEq(menuUid))
menuUidEq(menuUid) .offset(pageable.getOffset())
) .limit(pageable.getPageSize())
.offset(pageable.getOffset()) .orderBy(auditLogEntity.createdDate.desc())
.limit(pageable.getPageSize()) .fetch();
.orderBy(auditLogEntity.createdDate.desc())
.fetch();
Long countQuery = queryFactory Long countQuery =
.select(auditLogEntity.id.countDistinct()) queryFactory
.from(auditLogEntity) .select(auditLogEntity.id.countDistinct())
.leftJoin(menuEntity).on(auditLogEntity.menuUid.eq(menuEntity.menuUid)) .from(auditLogEntity)
.leftJoin(menuEntity.parent, parent) .leftJoin(menuEntity)
.leftJoin(userEntity).on(auditLogEntity.userUid.eq(userEntity.id)) .on(auditLogEntity.menuUid.eq(menuEntity.menuUid))
.where( .leftJoin(menuEntity.parent, parent)
menuUidEq(menuUid) .leftJoin(userEntity)
).fetchOne(); .on(auditLogEntity.userUid.eq(userEntity.id))
.where(menuUidEq(menuUid))
.fetchOne();
return new PageImpl<>(foundContent, pageable, countQuery); return new PageImpl<>(foundContent, pageable, countQuery);
} }
@Override @Override
public Page<AuditLogDto.AuditDetail> findLogByAccountResult(AuditLogDto.MenuUserSearchReq searchReq, Long userUid) { public Page<AuditLogDto.AuditDetail> findLogByAccountResult(
AuditLogDto.MenuUserSearchReq searchReq, Long userUid) {
Pageable pageable = searchReq.toPageable(); Pageable pageable = searchReq.toPageable();
QMenuEntity parent = new QMenuEntity("parent"); QMenuEntity parent = new QMenuEntity("parent");
// 1depth menu name // 1depth menu name
StringExpression parentMenuName = StringExpression parentMenuName =
new CaseBuilder() new CaseBuilder()
.when(parent.menuUid.isNull()).then(menuEntity.menuNm) .when(parent.menuUid.isNull())
.otherwise(parent.menuNm); .then(menuEntity.menuNm)
.otherwise(parent.menuNm);
// 2depth menu name // 2depth menu name
StringExpression menuName = StringExpression menuName =
new CaseBuilder() new CaseBuilder()
.when(parent.menuUid.isNull()).then(NULL_STRING) .when(parent.menuUid.isNull())
.otherwise(menuEntity.menuNm); .then(NULL_STRING)
.otherwise(menuEntity.menuNm);
List<AuditLogDto.AuditDetail> foundContent = queryFactory List<AuditLogDto.AuditDetail> foundContent =
.select( queryFactory
Projections.constructor( .select(
AuditLogDto.AuditDetail.class, Projections.constructor(
auditLogEntity.id.as("logId"), AuditLogDto.AuditDetail.class,
auditLogEntity.createdDate.as("logDateTime"), auditLogEntity.id.as("logId"),
menuEntity.menuNm.as("menuName"), auditLogEntity.createdDate.as("logDateTime"),
auditLogEntity.eventType.as("eventType"), menuEntity.menuNm.as("menuName"),
Projections.constructor( auditLogEntity.eventType.as("eventType"),
AuditLogDto.LogDetail.class, Projections.constructor(
Expressions.constant("한국자산관리공사"), //serviceName AuditLogDto.LogDetail.class,
parentMenuName.as("parentMenuName"), Expressions.constant("한국자산관리공사"), // serviceName
menuName, parentMenuName.as("parentMenuName"),
menuEntity.menuUrl.as("menuUrl"), menuName,
menuEntity.description.as("menuDescription"), menuEntity.menuUrl.as("menuUrl"),
menuEntity.menuOrder.as("sortOrder"), menuEntity.description.as("menuDescription"),
menuEntity.isUse.as("used") menuEntity.menuOrder.as("sortOrder"),
) menuEntity.isUse.as("used"))))
) .from(auditLogEntity)
) .leftJoin(menuEntity)
.from(auditLogEntity) .on(auditLogEntity.menuUid.eq(menuEntity.menuUid))
.leftJoin(menuEntity).on(auditLogEntity.menuUid.eq(menuEntity.menuUid)) .leftJoin(menuEntity.parent, parent)
.leftJoin(menuEntity.parent, parent) .leftJoin(userEntity)
.leftJoin(userEntity).on(auditLogEntity.userUid.eq(userEntity.id)) .on(auditLogEntity.userUid.eq(userEntity.id))
.where( .where(userUidEq(userUid))
userUidEq(userUid) .offset(pageable.getOffset())
) .limit(pageable.getPageSize())
.offset(pageable.getOffset()) .orderBy(auditLogEntity.createdDate.desc())
.limit(pageable.getPageSize()) .fetch();
.orderBy(auditLogEntity.createdDate.desc())
.fetch();
Long countQuery = queryFactory Long countQuery =
.select(auditLogEntity.id.countDistinct()) queryFactory
.from(auditLogEntity) .select(auditLogEntity.id.countDistinct())
.leftJoin(menuEntity).on(auditLogEntity.menuUid.eq(menuEntity.menuUid)) .from(auditLogEntity)
.leftJoin(menuEntity.parent, parent) .leftJoin(menuEntity)
.leftJoin(userEntity).on(auditLogEntity.userUid.eq(userEntity.id)) .on(auditLogEntity.menuUid.eq(menuEntity.menuUid))
.where( .leftJoin(menuEntity.parent, parent)
userUidEq(userUid) .leftJoin(userEntity)
) .on(auditLogEntity.userUid.eq(userEntity.id))
.fetchOne(); .where(userUidEq(userUid))
.fetchOne();
return new PageImpl<>(foundContent, pageable, countQuery); return new PageImpl<>(foundContent, pageable, countQuery);
} }
@@ -345,8 +351,10 @@ public class AuditLogRepositoryImpl extends QuerydslRepositorySupport implements
} }
LocalDateTime startDateTime = startDate.atStartOfDay(); LocalDateTime startDateTime = startDate.atStartOfDay();
LocalDateTime endDateTime = endDate.plusDays(1).atStartOfDay(); LocalDateTime endDateTime = endDate.plusDays(1).atStartOfDay();
return auditLogEntity.createdDate.goe(ZonedDateTime.from(startDateTime)) return auditLogEntity
.and(auditLogEntity.createdDate.lt(ZonedDateTime.from(endDateTime))); .createdDate
.goe(ZonedDateTime.from(startDateTime))
.and(auditLogEntity.createdDate.lt(ZonedDateTime.from(endDateTime)));
} }
private BooleanExpression menuNameEquals(String searchValue) { private BooleanExpression menuNameEquals(String searchValue) {
@@ -383,7 +391,8 @@ public class AuditLogRepositoryImpl extends QuerydslRepositorySupport implements
private BooleanExpression eventEndedAtEqDate(LocalDate logDate) { private BooleanExpression eventEndedAtEqDate(LocalDate logDate) {
DateTimeExpression<LocalDateTime> eventEndedDate = DateTimeExpression<LocalDateTime> eventEndedDate =
Expressions.dateTimeTemplate(LocalDateTime.class, "date_trunc('day', {0})", auditLogEntity.createdDate); Expressions.dateTimeTemplate(
LocalDateTime.class, "date_trunc('day', {0})", auditLogEntity.createdDate);
LocalDateTime comparisonDate = logDate.atStartOfDay(); LocalDateTime comparisonDate = logDate.atStartOfDay();
return eventEndedDate.eq(comparisonDate); return eventEndedDate.eq(comparisonDate);
@@ -399,29 +408,33 @@ public class AuditLogRepositoryImpl extends QuerydslRepositorySupport implements
private NumberExpression<Integer> readCount() { private NumberExpression<Integer> readCount() {
return new CaseBuilder() return new CaseBuilder()
.when(auditLogEntity.eventType.eq(EventType.READ)).then(1) .when(auditLogEntity.eventType.eq(EventType.READ))
.otherwise(0) .then(1)
.sum(); .otherwise(0)
.sum();
} }
private NumberExpression<Integer> cudCount() { private NumberExpression<Integer> cudCount() {
return new CaseBuilder() return new CaseBuilder()
.when(auditLogEntity.eventType.in(EventType.CREATE, EventType.UPDATE, EventType.DELETE)).then(1) .when(auditLogEntity.eventType.in(EventType.CREATE, EventType.UPDATE, EventType.DELETE))
.otherwise(0) .then(1)
.sum(); .otherwise(0)
.sum();
} }
private NumberExpression<Integer> printCount() { private NumberExpression<Integer> printCount() {
return new CaseBuilder() return new CaseBuilder()
.when(auditLogEntity.eventType.eq(EventType.PRINT)).then(1) .when(auditLogEntity.eventType.eq(EventType.PRINT))
.otherwise(0) .then(1)
.sum(); .otherwise(0)
.sum();
} }
private NumberExpression<Integer> downloadCount() { private NumberExpression<Integer> downloadCount() {
return new CaseBuilder() return new CaseBuilder()
.when(auditLogEntity.eventType.eq(EventType.DOWNLOAD)).then(1) .when(auditLogEntity.eventType.eq(EventType.DOWNLOAD))
.otherwise(0) .then(1)
.sum(); .otherwise(0)
.sum();
} }
} }

View File

@@ -3,4 +3,5 @@ package com.kamco.cd.kamcoback.postgres.repository.log;
import com.kamco.cd.kamcoback.postgres.entity.ErrorLogEntity; import com.kamco.cd.kamcoback.postgres.entity.ErrorLogEntity;
import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaRepository;
public interface ErrorLogRepository extends JpaRepository<ErrorLogEntity, Long>, ErrorLogRepositoryCustom {} public interface ErrorLogRepository
extends JpaRepository<ErrorLogEntity, Long>, ErrorLogRepositoryCustom {}

View File

@@ -1,12 +1,8 @@
package com.kamco.cd.kamcoback.postgres.repository.log; package com.kamco.cd.kamcoback.postgres.repository.log;
import com.kamco.cd.kamcoback.log.dto.AuditLogDto;
import com.kamco.cd.kamcoback.log.dto.ErrorLogDto; import com.kamco.cd.kamcoback.log.dto.ErrorLogDto;
import com.kamco.cd.kamcoback.postgres.entity.AuditLogEntity;
import org.springframework.data.domain.Page; import org.springframework.data.domain.Page;
import java.time.LocalDate;
public interface ErrorLogRepositoryCustom { public interface ErrorLogRepositoryCustom {
public Page<ErrorLogDto.Basic> findLogByError(ErrorLogDto.ErrorSearchReq searchReq); public Page<ErrorLogDto.Basic> findLogByError(ErrorLogDto.ErrorSearchReq searchReq);
} }

View File

@@ -1,5 +1,10 @@
package com.kamco.cd.kamcoback.postgres.repository.log; package com.kamco.cd.kamcoback.postgres.repository.log;
import static com.kamco.cd.kamcoback.postgres.entity.QAuditLogEntity.auditLogEntity;
import static com.kamco.cd.kamcoback.postgres.entity.QErrorLogEntity.errorLogEntity;
import static com.kamco.cd.kamcoback.postgres.entity.QMenuEntity.menuEntity;
import static com.kamco.cd.kamcoback.postgres.entity.QUserEntity.userEntity;
import com.kamco.cd.kamcoback.log.dto.ErrorLogDto; import com.kamco.cd.kamcoback.log.dto.ErrorLogDto;
import com.kamco.cd.kamcoback.log.dto.EventStatus; import com.kamco.cd.kamcoback.log.dto.EventStatus;
import com.kamco.cd.kamcoback.log.dto.EventType; import com.kamco.cd.kamcoback.log.dto.EventType;
@@ -9,23 +14,18 @@ import com.querydsl.core.types.dsl.BooleanExpression;
import com.querydsl.core.types.dsl.Expressions; import com.querydsl.core.types.dsl.Expressions;
import com.querydsl.core.types.dsl.StringExpression; import com.querydsl.core.types.dsl.StringExpression;
import com.querydsl.jpa.impl.JPAQueryFactory; import com.querydsl.jpa.impl.JPAQueryFactory;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.support.QuerydslRepositorySupport;
import java.time.LocalDate; import java.time.LocalDate;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.time.ZonedDateTime; import java.time.ZonedDateTime;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.support.QuerydslRepositorySupport;
import static com.kamco.cd.kamcoback.postgres.entity.QAuditLogEntity.auditLogEntity; public class ErrorLogRepositoryImpl extends QuerydslRepositorySupport
import static com.kamco.cd.kamcoback.postgres.entity.QErrorLogEntity.errorLogEntity; implements ErrorLogRepositoryCustom {
import static com.kamco.cd.kamcoback.postgres.entity.QMenuEntity.menuEntity;
import static com.kamco.cd.kamcoback.postgres.entity.QUserEntity.userEntity;
public class ErrorLogRepositoryImpl extends QuerydslRepositorySupport implements ErrorLogRepositoryCustom {
private final JPAQueryFactory queryFactory; private final JPAQueryFactory queryFactory;
private final StringExpression NULL_STRING = Expressions.stringTemplate("cast(null as text)"); private final StringExpression NULL_STRING = Expressions.stringTemplate("cast(null as text)");
@@ -37,52 +37,57 @@ public class ErrorLogRepositoryImpl extends QuerydslRepositorySupport implements
@Override @Override
public Page<ErrorLogDto.Basic> findLogByError(ErrorLogDto.ErrorSearchReq searchReq) { public Page<ErrorLogDto.Basic> findLogByError(ErrorLogDto.ErrorSearchReq searchReq) {
Pageable pageable = searchReq.toPageable(); Pageable pageable = searchReq.toPageable();
List<ErrorLogDto.Basic> foundContent = queryFactory List<ErrorLogDto.Basic> foundContent =
.select( queryFactory
Projections.constructor( .select(
ErrorLogDto.Basic.class, Projections.constructor(
errorLogEntity.id.as("logId"), ErrorLogDto.Basic.class,
Expressions.constant("한국자산관리공사"), //serviceName errorLogEntity.id.as("logId"),
menuEntity.menuNm.as("menuName"), Expressions.constant("한국자산관리공사"), // serviceName
userEntity.userId.as("loginId"), menuEntity.menuNm.as("menuName"),
userEntity.userNm.as("userName"), userEntity.userId.as("loginId"),
errorLogEntity.errorType.as("eventType"), userEntity.userNm.as("userName"),
errorLogEntity.errorMessage.as("errorName"), // 기존에는 errorName 값이 있었는데 신규 테이블에는 없음. 에러 메세지와 동일 errorLogEntity.errorType.as("eventType"),
errorLogEntity.errorLevel.as("errorLevel"), errorLogEntity.errorMessage.as(
errorLogEntity.errorCode.as("errorCode"), "errorName"), // 기존에는 errorName 값이 있었는데 신규 테이블에는 없음. 에러 메세지와 동일
errorLogEntity.errorMessage.as("errorMessage"), errorLogEntity.errorLevel.as("errorLevel"),
errorLogEntity.stackTrace.as("errorDetail"), errorLogEntity.errorCode.as("errorCode"),
errorLogEntity.createdDate errorLogEntity.errorMessage.as("errorMessage"),
) errorLogEntity.stackTrace.as("errorDetail"),
) errorLogEntity.createdDate))
.from(errorLogEntity) .from(errorLogEntity)
.leftJoin(auditLogEntity).on(errorLogEntity.id.eq(auditLogEntity.errorLogUid)) .leftJoin(auditLogEntity)
.leftJoin(menuEntity).on(auditLogEntity.menuUid.eq(menuEntity.menuUid)) .on(errorLogEntity.id.eq(auditLogEntity.errorLogUid))
.leftJoin(userEntity).on(errorLogEntity.handlerUid.eq(userEntity.id)) .leftJoin(menuEntity)
.where( .on(auditLogEntity.menuUid.eq(menuEntity.menuUid))
eventStatusEqFailed(), .leftJoin(userEntity)
eventEndedAtBetween(searchReq.getStartDate(), searchReq.getEndDate()), .on(errorLogEntity.handlerUid.eq(userEntity.id))
eventTypeEq(searchReq.getEventType()), .where(
errorLevelEq(searchReq.getErrorLevel()) eventStatusEqFailed(),
) eventEndedAtBetween(searchReq.getStartDate(), searchReq.getEndDate()),
.offset(pageable.getOffset()) eventTypeEq(searchReq.getEventType()),
.limit(pageable.getPageSize()) errorLevelEq(searchReq.getErrorLevel()))
.orderBy(errorLogEntity.createdDate.desc()) .offset(pageable.getOffset())
.fetch(); .limit(pageable.getPageSize())
.orderBy(errorLogEntity.createdDate.desc())
.fetch();
Long countQuery = queryFactory Long countQuery =
.select(errorLogEntity.id.countDistinct()) queryFactory
.from(errorLogEntity) .select(errorLogEntity.id.countDistinct())
.leftJoin(auditLogEntity).on(errorLogEntity.id.eq(auditLogEntity.errorLogUid)) .from(errorLogEntity)
.leftJoin(menuEntity).on(auditLogEntity.menuUid.eq(menuEntity.menuUid)) .leftJoin(auditLogEntity)
.leftJoin(userEntity).on(errorLogEntity.handlerUid.eq(userEntity.id)) .on(errorLogEntity.id.eq(auditLogEntity.errorLogUid))
.where( .leftJoin(menuEntity)
eventStatusEqFailed(), .on(auditLogEntity.menuUid.eq(menuEntity.menuUid))
eventEndedAtBetween(searchReq.getStartDate(), searchReq.getEndDate()), .leftJoin(userEntity)
eventTypeEq(searchReq.getEventType()), .on(errorLogEntity.handlerUid.eq(userEntity.id))
errorLevelEq(searchReq.getErrorLevel()) .where(
) eventStatusEqFailed(),
.fetchOne(); eventEndedAtBetween(searchReq.getStartDate(), searchReq.getEndDate()),
eventTypeEq(searchReq.getEventType()),
errorLevelEq(searchReq.getErrorLevel()))
.fetchOne();
return new PageImpl<>(foundContent, pageable, countQuery); return new PageImpl<>(foundContent, pageable, countQuery);
} }
@@ -93,8 +98,10 @@ public class ErrorLogRepositoryImpl extends QuerydslRepositorySupport implements
} }
LocalDateTime startDateTime = startDate.atStartOfDay(); LocalDateTime startDateTime = startDate.atStartOfDay();
LocalDateTime endDateTime = endDate.plusDays(1).atStartOfDay(); LocalDateTime endDateTime = endDate.plusDays(1).atStartOfDay();
return auditLogEntity.createdDate.goe(ZonedDateTime.from(startDateTime)) return auditLogEntity
.and(auditLogEntity.createdDate.lt(ZonedDateTime.from(endDateTime))); .createdDate
.goe(ZonedDateTime.from(startDateTime))
.and(auditLogEntity.createdDate.lt(ZonedDateTime.from(endDateTime)));
} }
private BooleanExpression eventStatusEqFailed() { private BooleanExpression eventStatusEqFailed() {