feat: format error

This commit is contained in:
2025-11-20 14:50:02 +09:00
parent 5c030869fd
commit 04678b6b6e
33 changed files with 1031 additions and 852 deletions

View File

@@ -63,17 +63,19 @@ public class CommonCodeApiController {
}) })
@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(
responseCode = "201",
description = "공통코드 저장 성공",
content =
@Content( @Content(
mediaType = "application/json", mediaType = "application/json",
schema = @Schema(implementation = Long.class))), schema = @Schema(implementation = Long.class))),
@@ -91,14 +93,18 @@ public class CommonCodeApiController {
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(
responseCode = "204",
description = "공통코드 수정 성공",
content =
@Content( @Content(
mediaType = "application/json", mediaType = "application/json",
schema = @Schema(implementation = Long.class))), schema = @Schema(implementation = Long.class))),
@@ -115,7 +121,9 @@ public class CommonCodeApiController {
@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);
} }
@@ -123,7 +131,10 @@ public class CommonCodeApiController {
@Operation(summary = "삭제", description = "공통코드를 삭제 합니다.") @Operation(summary = "삭제", description = "공통코드를 삭제 합니다.")
@ApiResponses( @ApiResponses(
value = { value = {
@ApiResponse(responseCode = "204", description = "공통코드 삭제 성공", content = @ApiResponse(
responseCode = "204",
description = "공통코드 삭제 성공",
content =
@Content( @Content(
mediaType = "application/json", mediaType = "application/json",
schema = @Schema(implementation = Long.class))), schema = @Schema(implementation = Long.class))),
@@ -136,7 +147,8 @@ public class CommonCodeApiController {
@io.swagger.v3.oas.annotations.parameters.RequestBody( @io.swagger.v3.oas.annotations.parameters.RequestBody(
description = "공통코드 삭제 요청 정보", description = "공통코드 삭제 요청 정보",
required = true) required = true)
@PathVariable Long id) { @PathVariable
Long id) {
commonCodeService.remove(id); commonCodeService.remove(id);
return ApiResponseDto.deleteOk(id); return ApiResponseDto.deleteOk(id);
} }
@@ -144,7 +156,10 @@ public class CommonCodeApiController {
@Operation(summary = "순서 변경", description = "공통코드 순서를 변경 합니다.") @Operation(summary = "순서 변경", description = "공통코드 순서를 변경 합니다.")
@ApiResponses( @ApiResponses(
value = { value = {
@ApiResponse(responseCode = "204", description = "공통코드 순서 변경 성공", content = @ApiResponse(
responseCode = "204",
description = "공통코드 순서 변경 성공",
content =
@Content( @Content(
mediaType = "application/json", mediaType = "application/json",
schema = @Schema(implementation = Long.class))), schema = @Schema(implementation = Long.class))),
@@ -161,7 +176,9 @@ public class CommonCodeApiController {
@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
@Valid
CommonCodeDto.OrderReq req) {
commonCodeService.updateOrder(req); commonCodeService.updateOrder(req);
return ApiResponseDto.deleteOk(null); return ApiResponseDto.deleteOk(null);
} }
@@ -169,7 +186,10 @@ public class CommonCodeApiController {
@Operation(summary = "code 기반 조회", description = "code 기반 조회") @Operation(summary = "code 기반 조회", description = "code 기반 조회")
@ApiResponses( @ApiResponses(
value = { value = {
@ApiResponse(responseCode = "200", description = "공통코드 순서 변경 성공", content = @ApiResponse(
responseCode = "200",
description = "공통코드 순서 변경 성공",
content =
@Content( @Content(
mediaType = "application/json", mediaType = "application/json",
schema = @Schema(implementation = Long.class))), schema = @Schema(implementation = Long.class))),
@@ -182,7 +202,8 @@ public class CommonCodeApiController {
@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,11 +73,9 @@ 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,

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 =
Arrays.stream(stackTrace)
.limit(10) .limit(10)
.map(StackTraceElement::toString) .map(StackTraceElement::toString)
.collect(Collectors.joining("\n")); .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,12 +58,14 @@ 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 =
paramMap.entrySet().stream()
.map(e -> e.getKey() + "=" + String.join(",", e.getValue())) .map(e -> e.getKey() + "=" + String.join(",", e.getValue()))
.collect(Collectors.joining("&")); .collect(Collectors.joining("&"));
@@ -75,7 +76,7 @@ public class ApiLogFunction {
&& 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) {
@@ -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
@@ -29,15 +27,12 @@ public class AuditLogApiController {
@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);
} }
@@ -47,81 +42,67 @@ public class AuditLogApiController {
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,7 +23,6 @@ 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,
@@ -37,9 +30,10 @@ public class ErrorLogApiController {
@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,8 +30,7 @@ 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,
@@ -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,11 +29,9 @@ 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,
@@ -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;
@@ -112,10 +113,13 @@ public class ErrorLogDto {
} }
@Override @Override
public String getId() { return name(); } public String getId() {
return name();
@Override
public String getText() { return desc; }
} }
@Override
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;
@@ -69,16 +77,24 @@ public class AuditLogEntity extends CommonCreateEntity {
} }
@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;
@@ -92,7 +94,6 @@ public class CommonCodeEntity extends CommonDateEntity {
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;
@@ -34,13 +32,9 @@ public class CommonCodeRepositoryImpl extends QuerydslRepositorySupport implemen
.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),
commonCodeEntity.deleted.isFalse()
)
.orderBy(commonCodeEntity.order.asc(), child.order.asc()) .orderBy(commonCodeEntity.order.asc(), child.order.asc())
.fetchOne() .fetchOne());
);
} }
@Override @Override
@@ -55,11 +49,9 @@ public class CommonCodeRepositoryImpl extends QuerydslRepositorySupport implemen
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
@@ -69,24 +61,23 @@ public class CommonCodeRepositoryImpl extends QuerydslRepositorySupport implemen
.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(),
commonCodeEntity.deleted.isFalse()
)
.orderBy(commonCodeEntity.order.asc(), child.order.asc()) .orderBy(commonCodeEntity.order.asc(), child.order.asc())
.fetch(); .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(
commonCodeEntity -> {
Integer order = orderMap.get(commonCodeEntity.getId()); Integer order = orderMap.get(commonCodeEntity.getId());
if(order != null) { if (order != null) {
commonCodeEntity.updateOrder(order); commonCodeEntity.updateOrder(order);
} }
}); });
@@ -95,10 +86,7 @@ public class CommonCodeRepositoryImpl extends QuerydslRepositorySupport implemen
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),
commonCodeEntity.deleted.isFalse()
)
.fetch(); .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,12 +36,15 @@ 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 =
queryFactory
.select( .select(
Projections.constructor( Projections.constructor(
AuditLogDto.AuditList.class, AuditLogDto.AuditList.class,
@@ -51,34 +53,31 @@ public class AuditLogRepositoryImpl extends QuerydslRepositorySupport implements
cudCount().as("cudCount"), cudCount().as("cudCount"),
printCount().as("printCount"), printCount().as("printCount"),
downloadCount().as("downloadCount"), downloadCount().as("downloadCount"),
auditLogEntity.count().as("totalCount") auditLogEntity.count().as("totalCount")))
)
)
.from(auditLogEntity) .from(auditLogEntity)
.where( .where(eventEndedAtBetween(startDate, endDate))
eventEndedAtBetween(startDate, endDate)
)
.groupBy(groupDateTime) .groupBy(groupDateTime)
.offset(pageable.getOffset()) .offset(pageable.getOffset())
.limit(pageable.getPageSize()) .limit(pageable.getPageSize())
.orderBy(groupDateTime.desc()) .orderBy(groupDateTime.desc())
.fetch(); .fetch();
Long countQuery = queryFactory Long countQuery =
queryFactory
.select(groupDateTime.countDistinct()) .select(groupDateTime.countDistinct())
.from(auditLogEntity) .from(auditLogEntity)
.where( .where(eventEndedAtBetween(startDate, endDate))
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 =
queryFactory
.select( .select(
Projections.constructor( Projections.constructor(
AuditLogDto.AuditList.class, AuditLogDto.AuditList.class,
@@ -88,14 +87,11 @@ public class AuditLogRepositoryImpl extends QuerydslRepositorySupport implements
cudCount().as("cudCount"), cudCount().as("cudCount"),
printCount().as("printCount"), printCount().as("printCount"),
downloadCount().as("downloadCount"), downloadCount().as("downloadCount"),
auditLogEntity.count().as("totalCount") auditLogEntity.count().as("totalCount")))
)
)
.from(auditLogEntity) .from(auditLogEntity)
.leftJoin(menuEntity).on(auditLogEntity.menuUid.eq(menuEntity.menuUid)) .leftJoin(menuEntity)
.where( .on(auditLogEntity.menuUid.eq(menuEntity.menuUid))
menuNameEquals(searchValue) .where(menuNameEquals(searchValue))
)
.groupBy(auditLogEntity.menuUid) .groupBy(auditLogEntity.menuUid)
.offset(pageable.getOffset()) .offset(pageable.getOffset())
.limit(pageable.getPageSize()) .limit(pageable.getPageSize())
@@ -104,10 +100,12 @@ public class AuditLogRepositoryImpl extends QuerydslRepositorySupport implements
// 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 =
queryFactory
.select(auditLogEntity.menuUid.countDistinct()) .select(auditLogEntity.menuUid.countDistinct())
.from(auditLogEntity) .from(auditLogEntity)
.leftJoin(menuEntity).on(auditLogEntity.menuUid.eq(menuEntity.menuUid)) .leftJoin(menuEntity)
.on(auditLogEntity.menuUid.eq(menuEntity.menuUid))
.where(menuNameEquals(searchValue)) .where(menuNameEquals(searchValue))
.fetchOne(); .fetchOne();
@@ -115,9 +113,11 @@ public class AuditLogRepositoryImpl extends QuerydslRepositorySupport implements
} }
@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 =
queryFactory
.select( .select(
Projections.constructor( Projections.constructor(
AuditLogDto.AuditList.class, AuditLogDto.AuditList.class,
@@ -128,24 +128,23 @@ public class AuditLogRepositoryImpl extends QuerydslRepositorySupport implements
cudCount().as("cudCount"), cudCount().as("cudCount"),
printCount().as("printCount"), printCount().as("printCount"),
downloadCount().as("downloadCount"), downloadCount().as("downloadCount"),
auditLogEntity.count().as("totalCount") auditLogEntity.count().as("totalCount")))
)
)
.from(auditLogEntity) .from(auditLogEntity)
.leftJoin(userEntity).on(auditLogEntity.userUid.eq(userEntity.id)) .leftJoin(userEntity)
.where( .on(auditLogEntity.userUid.eq(userEntity.id))
loginIdOrUsernameContains(searchValue) .where(loginIdOrUsernameContains(searchValue))
)
.groupBy(auditLogEntity.userUid, userEntity.userId, userEntity.userNm) .groupBy(auditLogEntity.userUid, userEntity.userId, userEntity.userNm)
.offset(pageable.getOffset()) .offset(pageable.getOffset())
.limit(pageable.getPageSize()) .limit(pageable.getPageSize())
// .orderBy(auditLogEntity.eventEndedAt.max().desc()) // .orderBy(auditLogEntity.eventEndedAt.max().desc())
.fetch(); .fetch();
Long countQuery = queryFactory Long countQuery =
queryFactory
.select(auditLogEntity.userUid.countDistinct()) .select(auditLogEntity.userUid.countDistinct())
.from(auditLogEntity) .from(auditLogEntity)
.leftJoin(userEntity).on(auditLogEntity.userUid.eq(userEntity.id)) .leftJoin(userEntity)
.on(auditLogEntity.userUid.eq(userEntity.id))
.where(loginIdOrUsernameContains(searchValue)) .where(loginIdOrUsernameContains(searchValue))
.fetchOne(); .fetchOne();
@@ -153,22 +152,26 @@ public class AuditLogRepositoryImpl extends QuerydslRepositorySupport implements
} }
@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())
.then(menuEntity.menuNm)
.otherwise(parent.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())
.then(NULL_STRING)
.otherwise(menuEntity.menuNm); .otherwise(menuEntity.menuNm);
List<AuditLogDto.AuditDetail> foundContent = queryFactory List<AuditLogDto.AuditDetail> foundContent =
queryFactory
.select( .select(
Projections.constructor( Projections.constructor(
AuditLogDto.AuditDetail.class, AuditLogDto.AuditDetail.class,
@@ -179,59 +182,61 @@ public class AuditLogRepositoryImpl extends QuerydslRepositorySupport implements
auditLogEntity.eventType.as("eventType"), auditLogEntity.eventType.as("eventType"),
Projections.constructor( Projections.constructor(
AuditLogDto.LogDetail.class, AuditLogDto.LogDetail.class,
Expressions.constant("한국자산관리공사"), //serviceName Expressions.constant("한국자산관리공사"), // serviceName
parentMenuName.as("parentMenuName"), parentMenuName.as("parentMenuName"),
menuName, menuName,
menuEntity.menuUrl.as("menuUrl"), menuEntity.menuUrl.as("menuUrl"),
menuEntity.description.as("menuDescription"), menuEntity.description.as("menuDescription"),
menuEntity.menuOrder.as("sortOrder"), menuEntity.menuOrder.as("sortOrder"),
menuEntity.isUse.as("used") menuEntity.isUse.as("used"))))
)
)
)
.from(auditLogEntity) .from(auditLogEntity)
.leftJoin(menuEntity).on(auditLogEntity.menuUid.eq(menuEntity.menuUid)) .leftJoin(menuEntity)
.on(auditLogEntity.menuUid.eq(menuEntity.menuUid))
.leftJoin(menuEntity.parent, parent) .leftJoin(menuEntity.parent, parent)
.leftJoin(userEntity).on(auditLogEntity.userUid.eq(userEntity.id)) .leftJoin(userEntity)
.where( .on(auditLogEntity.userUid.eq(userEntity.id))
eventEndedAtEqDate(logDate) .where(eventEndedAtEqDate(logDate))
)
.offset(pageable.getOffset()) .offset(pageable.getOffset())
.limit(pageable.getPageSize()) .limit(pageable.getPageSize())
.orderBy(auditLogEntity.createdDate.desc()) .orderBy(auditLogEntity.createdDate.desc())
.fetch(); .fetch();
Long countQuery = queryFactory Long countQuery =
queryFactory
.select(auditLogEntity.id.countDistinct()) .select(auditLogEntity.id.countDistinct())
.from(auditLogEntity) .from(auditLogEntity)
.leftJoin(menuEntity).on(auditLogEntity.menuUid.eq(menuEntity.menuUid)) .leftJoin(menuEntity)
.on(auditLogEntity.menuUid.eq(menuEntity.menuUid))
.leftJoin(menuEntity.parent, parent) .leftJoin(menuEntity.parent, parent)
.leftJoin(userEntity).on(auditLogEntity.userUid.eq(userEntity.id)) .leftJoin(userEntity)
.where( .on(auditLogEntity.userUid.eq(userEntity.id))
eventEndedAtEqDate(logDate) .where(eventEndedAtEqDate(logDate))
)
.fetchOne(); .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())
.then(menuEntity.menuNm)
.otherwise(parent.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())
.then(NULL_STRING)
.otherwise(menuEntity.menuNm); .otherwise(menuEntity.menuNm);
List<AuditLogDto.AuditDetail> foundContent = queryFactory List<AuditLogDto.AuditDetail> foundContent =
queryFactory
.select( .select(
Projections.constructor( Projections.constructor(
AuditLogDto.AuditDetail.class, AuditLogDto.AuditDetail.class,
@@ -242,58 +247,61 @@ public class AuditLogRepositoryImpl extends QuerydslRepositorySupport implements
auditLogEntity.eventType.as("eventType"), auditLogEntity.eventType.as("eventType"),
Projections.constructor( Projections.constructor(
AuditLogDto.LogDetail.class, AuditLogDto.LogDetail.class,
Expressions.constant("한국자산관리공사"), //serviceName Expressions.constant("한국자산관리공사"), // serviceName
parentMenuName.as("parentMenuName"), parentMenuName.as("parentMenuName"),
menuName, menuName,
menuEntity.menuUrl.as("menuUrl"), menuEntity.menuUrl.as("menuUrl"),
menuEntity.description.as("menuDescription"), menuEntity.description.as("menuDescription"),
menuEntity.menuOrder.as("sortOrder"), menuEntity.menuOrder.as("sortOrder"),
menuEntity.isUse.as("used") menuEntity.isUse.as("used"))))
)
)
)
.from(auditLogEntity) .from(auditLogEntity)
.leftJoin(menuEntity).on(auditLogEntity.menuUid.eq(menuEntity.menuUid)) .leftJoin(menuEntity)
.on(auditLogEntity.menuUid.eq(menuEntity.menuUid))
.leftJoin(menuEntity.parent, parent) .leftJoin(menuEntity.parent, parent)
.leftJoin(userEntity).on(auditLogEntity.userUid.eq(userEntity.id)) .leftJoin(userEntity)
.where( .on(auditLogEntity.userUid.eq(userEntity.id))
menuUidEq(menuUid) .where(menuUidEq(menuUid))
)
.offset(pageable.getOffset()) .offset(pageable.getOffset())
.limit(pageable.getPageSize()) .limit(pageable.getPageSize())
.orderBy(auditLogEntity.createdDate.desc()) .orderBy(auditLogEntity.createdDate.desc())
.fetch(); .fetch();
Long countQuery = queryFactory Long countQuery =
queryFactory
.select(auditLogEntity.id.countDistinct()) .select(auditLogEntity.id.countDistinct())
.from(auditLogEntity) .from(auditLogEntity)
.leftJoin(menuEntity).on(auditLogEntity.menuUid.eq(menuEntity.menuUid)) .leftJoin(menuEntity)
.on(auditLogEntity.menuUid.eq(menuEntity.menuUid))
.leftJoin(menuEntity.parent, parent) .leftJoin(menuEntity.parent, parent)
.leftJoin(userEntity).on(auditLogEntity.userUid.eq(userEntity.id)) .leftJoin(userEntity)
.where( .on(auditLogEntity.userUid.eq(userEntity.id))
menuUidEq(menuUid) .where(menuUidEq(menuUid))
).fetchOne(); .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())
.then(menuEntity.menuNm)
.otherwise(parent.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())
.then(NULL_STRING)
.otherwise(menuEntity.menuNm); .otherwise(menuEntity.menuNm);
List<AuditLogDto.AuditDetail> foundContent = queryFactory List<AuditLogDto.AuditDetail> foundContent =
queryFactory
.select( .select(
Projections.constructor( Projections.constructor(
AuditLogDto.AuditDetail.class, AuditLogDto.AuditDetail.class,
@@ -303,37 +311,35 @@ public class AuditLogRepositoryImpl extends QuerydslRepositorySupport implements
auditLogEntity.eventType.as("eventType"), auditLogEntity.eventType.as("eventType"),
Projections.constructor( Projections.constructor(
AuditLogDto.LogDetail.class, AuditLogDto.LogDetail.class,
Expressions.constant("한국자산관리공사"), //serviceName Expressions.constant("한국자산관리공사"), // serviceName
parentMenuName.as("parentMenuName"), parentMenuName.as("parentMenuName"),
menuName, menuName,
menuEntity.menuUrl.as("menuUrl"), menuEntity.menuUrl.as("menuUrl"),
menuEntity.description.as("menuDescription"), menuEntity.description.as("menuDescription"),
menuEntity.menuOrder.as("sortOrder"), menuEntity.menuOrder.as("sortOrder"),
menuEntity.isUse.as("used") menuEntity.isUse.as("used"))))
)
)
)
.from(auditLogEntity) .from(auditLogEntity)
.leftJoin(menuEntity).on(auditLogEntity.menuUid.eq(menuEntity.menuUid)) .leftJoin(menuEntity)
.on(auditLogEntity.menuUid.eq(menuEntity.menuUid))
.leftJoin(menuEntity.parent, parent) .leftJoin(menuEntity.parent, parent)
.leftJoin(userEntity).on(auditLogEntity.userUid.eq(userEntity.id)) .leftJoin(userEntity)
.where( .on(auditLogEntity.userUid.eq(userEntity.id))
userUidEq(userUid) .where(userUidEq(userUid))
)
.offset(pageable.getOffset()) .offset(pageable.getOffset())
.limit(pageable.getPageSize()) .limit(pageable.getPageSize())
.orderBy(auditLogEntity.createdDate.desc()) .orderBy(auditLogEntity.createdDate.desc())
.fetch(); .fetch();
Long countQuery = queryFactory Long countQuery =
queryFactory
.select(auditLogEntity.id.countDistinct()) .select(auditLogEntity.id.countDistinct())
.from(auditLogEntity) .from(auditLogEntity)
.leftJoin(menuEntity).on(auditLogEntity.menuUid.eq(menuEntity.menuUid)) .leftJoin(menuEntity)
.on(auditLogEntity.menuUid.eq(menuEntity.menuUid))
.leftJoin(menuEntity.parent, parent) .leftJoin(menuEntity.parent, parent)
.leftJoin(userEntity).on(auditLogEntity.userUid.eq(userEntity.id)) .leftJoin(userEntity)
.where( .on(auditLogEntity.userUid.eq(userEntity.id))
userUidEq(userUid) .where(userUidEq(userUid))
)
.fetchOne(); .fetchOne();
return new PageImpl<>(foundContent, pageable, countQuery); return new PageImpl<>(foundContent, pageable, countQuery);
@@ -345,7 +351,9 @@ 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
.createdDate
.goe(ZonedDateTime.from(startDateTime))
.and(auditLogEntity.createdDate.lt(ZonedDateTime.from(endDateTime))); .and(auditLogEntity.createdDate.lt(ZonedDateTime.from(endDateTime)));
} }
@@ -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,28 +408,32 @@ 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))
.then(1)
.otherwise(0) .otherwise(0)
.sum(); .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))
.then(1)
.otherwise(0) .otherwise(0)
.sum(); .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))
.then(1)
.otherwise(0) .otherwise(0)
.sum(); .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))
.then(1)
.otherwise(0) .otherwise(0)
.sum(); .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,51 +37,56 @@ 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 =
queryFactory
.select( .select(
Projections.constructor( Projections.constructor(
ErrorLogDto.Basic.class, ErrorLogDto.Basic.class,
errorLogEntity.id.as("logId"), errorLogEntity.id.as("logId"),
Expressions.constant("한국자산관리공사"), //serviceName Expressions.constant("한국자산관리공사"), // serviceName
menuEntity.menuNm.as("menuName"), menuEntity.menuNm.as("menuName"),
userEntity.userId.as("loginId"), userEntity.userId.as("loginId"),
userEntity.userNm.as("userName"), userEntity.userNm.as("userName"),
errorLogEntity.errorType.as("eventType"), errorLogEntity.errorType.as("eventType"),
errorLogEntity.errorMessage.as("errorName"), // 기존에는 errorName 값이 있었는데 신규 테이블에는 없음. 에러 메세지와 동일 errorLogEntity.errorMessage.as(
"errorName"), // 기존에는 errorName 값이 있었는데 신규 테이블에는 없음. 에러 메세지와 동일
errorLogEntity.errorLevel.as("errorLevel"), errorLogEntity.errorLevel.as("errorLevel"),
errorLogEntity.errorCode.as("errorCode"), errorLogEntity.errorCode.as("errorCode"),
errorLogEntity.errorMessage.as("errorMessage"), errorLogEntity.errorMessage.as("errorMessage"),
errorLogEntity.stackTrace.as("errorDetail"), errorLogEntity.stackTrace.as("errorDetail"),
errorLogEntity.createdDate 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)
.on(auditLogEntity.menuUid.eq(menuEntity.menuUid))
.leftJoin(userEntity)
.on(errorLogEntity.handlerUid.eq(userEntity.id))
.where( .where(
eventStatusEqFailed(), eventStatusEqFailed(),
eventEndedAtBetween(searchReq.getStartDate(), searchReq.getEndDate()), eventEndedAtBetween(searchReq.getStartDate(), searchReq.getEndDate()),
eventTypeEq(searchReq.getEventType()), eventTypeEq(searchReq.getEventType()),
errorLevelEq(searchReq.getErrorLevel()) errorLevelEq(searchReq.getErrorLevel()))
)
.offset(pageable.getOffset()) .offset(pageable.getOffset())
.limit(pageable.getPageSize()) .limit(pageable.getPageSize())
.orderBy(errorLogEntity.createdDate.desc()) .orderBy(errorLogEntity.createdDate.desc())
.fetch(); .fetch();
Long countQuery = queryFactory Long countQuery =
queryFactory
.select(errorLogEntity.id.countDistinct()) .select(errorLogEntity.id.countDistinct())
.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)
.on(auditLogEntity.menuUid.eq(menuEntity.menuUid))
.leftJoin(userEntity)
.on(errorLogEntity.handlerUid.eq(userEntity.id))
.where( .where(
eventStatusEqFailed(), eventStatusEqFailed(),
eventEndedAtBetween(searchReq.getStartDate(), searchReq.getEndDate()), eventEndedAtBetween(searchReq.getStartDate(), searchReq.getEndDate()),
eventTypeEq(searchReq.getEventType()), eventTypeEq(searchReq.getEventType()),
errorLevelEq(searchReq.getErrorLevel()) errorLevelEq(searchReq.getErrorLevel()))
)
.fetchOne(); .fetchOne();
return new PageImpl<>(foundContent, pageable, countQuery); return new PageImpl<>(foundContent, pageable, countQuery);
@@ -93,7 +98,9 @@ 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
.createdDate
.goe(ZonedDateTime.from(startDateTime))
.and(auditLogEntity.createdDate.lt(ZonedDateTime.from(endDateTime))); .and(auditLogEntity.createdDate.lt(ZonedDateTime.from(endDateTime)));
} }