From eeef8c8d324aed4cc082da616811dac109046710 Mon Sep 17 00:00:00 2001 From: "gayoun.park" Date: Fri, 5 Dec 2025 12:07:03 +0900 Subject: [PATCH] =?UTF-8?q?=EA=B3=B5=ED=86=B5=EC=BD=94=EB=93=9C=20?= =?UTF-8?q?=EC=82=AD=EC=A0=9C=20API=20=EC=BB=A4=EB=B0=8B,=20=EC=82=AD?= =?UTF-8?q?=EC=A0=9C=EC=9D=BC=EC=8B=9C=20=EC=BB=AC=EB=9F=BC=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80,=20=EC=97=90=EB=9F=AC=EB=A1=9C=EA=B7=B8=EC=97=90=20us?= =?UTF-8?q?erId=20=ED=86=A0=ED=81=B0=EC=9C=BC=EB=A1=9C=20=EB=A1=9C?= =?UTF-8?q?=EC=A7=81=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../code/CommonCodeApiController.java | 7 ++-- .../cd/kamcoback/code/dto/CommonCodeDto.java | 8 +++- .../code/service/CommonCodeService.java | 5 ++- .../config/GlobalExceptionHandler.java | 21 +++++++++- .../kamcoback/config/api/ApiResponseDto.java | 41 +++++++++++++++++++ .../postgres/core/CommonCodeCoreService.java | 33 +++++++++++---- .../postgres/entity/CommonCodeEntity.java | 15 ++++++- .../code/CommonCodeRepositoryImpl.java | 23 ++++++++--- 8 files changed, 130 insertions(+), 23 deletions(-) diff --git a/src/main/java/com/kamco/cd/kamcoback/code/CommonCodeApiController.java b/src/main/java/com/kamco/cd/kamcoback/code/CommonCodeApiController.java index d6eb6903..cb3a0f7c 100644 --- a/src/main/java/com/kamco/cd/kamcoback/code/CommonCodeApiController.java +++ b/src/main/java/com/kamco/cd/kamcoback/code/CommonCodeApiController.java @@ -30,7 +30,7 @@ import org.springframework.web.bind.annotation.RestController; @Tag(name = "공통코드 관리", description = "공통코드 관리 API") @RestController @RequiredArgsConstructor -@RequestMapping({"/demo/code", "/api/code"}) +@RequestMapping("/api/code") public class CommonCodeApiController { private final CommonCodeService commonCodeService; @@ -148,14 +148,13 @@ public class CommonCodeApiController { @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content) }) @DeleteMapping("/{id}") - public ApiResponseDto remove( + public ApiResponseDto remove( @io.swagger.v3.oas.annotations.parameters.RequestBody( description = "공통코드 삭제 요청 정보", required = true) @PathVariable Long id) { - commonCodeService.remove(id); - return ApiResponseDto.deleteOk(id); + return ApiResponseDto.okObject(commonCodeService.removeCode(id)); } @Operation(summary = "순서 변경", description = "공통코드 순서를 변경 합니다.") diff --git a/src/main/java/com/kamco/cd/kamcoback/code/dto/CommonCodeDto.java b/src/main/java/com/kamco/cd/kamcoback/code/dto/CommonCodeDto.java index 2b9c7e5a..88d22a85 100644 --- a/src/main/java/com/kamco/cd/kamcoback/code/dto/CommonCodeDto.java +++ b/src/main/java/com/kamco/cd/kamcoback/code/dto/CommonCodeDto.java @@ -90,6 +90,9 @@ public class CommonCodeDto { private String props2; private String props3; + @JsonFormatDttm + private ZonedDateTime deletedDttm; + public Basic( Long id, String code, @@ -103,7 +106,9 @@ public class CommonCodeDto { ZonedDateTime updatedDttm, String props1, String props2, - String props3) { + String props3, + ZonedDateTime deletedDttm + ) { this.id = id; this.code = code; this.description = description; @@ -117,6 +122,7 @@ public class CommonCodeDto { this.props1 = props1; this.props2 = props2; this.props3 = props3; + this.deletedDttm = deletedDttm; } } } diff --git a/src/main/java/com/kamco/cd/kamcoback/code/service/CommonCodeService.java b/src/main/java/com/kamco/cd/kamcoback/code/service/CommonCodeService.java index 7ae65f90..b51eca0b 100644 --- a/src/main/java/com/kamco/cd/kamcoback/code/service/CommonCodeService.java +++ b/src/main/java/com/kamco/cd/kamcoback/code/service/CommonCodeService.java @@ -4,6 +4,7 @@ import com.kamco.cd.kamcoback.code.dto.CommonCodeDto.AddReq; import com.kamco.cd.kamcoback.code.dto.CommonCodeDto.Basic; import com.kamco.cd.kamcoback.code.dto.CommonCodeDto.ModifyReq; import com.kamco.cd.kamcoback.code.dto.CommonCodeDto.OrderReq; +import com.kamco.cd.kamcoback.config.api.ApiResponseDto; import com.kamco.cd.kamcoback.postgres.core.CommonCodeCoreService; import java.util.List; import lombok.RequiredArgsConstructor; @@ -64,8 +65,8 @@ public class CommonCodeService { * @param id 코드 아이디 */ @Transactional - public void remove(Long id) { - commonCodeCoreService.remove(id); + public ApiResponseDto.ResponseObj removeCode(Long id) { + return commonCodeCoreService.removeCode(id); } /** diff --git a/src/main/java/com/kamco/cd/kamcoback/config/GlobalExceptionHandler.java b/src/main/java/com/kamco/cd/kamcoback/config/GlobalExceptionHandler.java index cb75db03..63f5b926 100644 --- a/src/main/java/com/kamco/cd/kamcoback/config/GlobalExceptionHandler.java +++ b/src/main/java/com/kamco/cd/kamcoback/config/GlobalExceptionHandler.java @@ -1,5 +1,6 @@ package com.kamco.cd.kamcoback.config; +import com.kamco.cd.kamcoback.auth.CustomUserDetails; import com.kamco.cd.kamcoback.common.exception.CustomApiException; import com.kamco.cd.kamcoback.config.api.ApiLogFunction; import com.kamco.cd.kamcoback.config.api.ApiResponseDto; @@ -23,6 +24,7 @@ import org.springframework.dao.DuplicateKeyException; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.http.converter.HttpMessageNotReadableException; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.web.bind.MethodArgumentNotValidException; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseStatus; @@ -370,8 +372,23 @@ public class GlobalExceptionHandler { HttpStatus httpStatus, ErrorLogDto.LogErrorLevel logErrorLevel, StackTraceElement[] stackTrace) { - // TODO : 로그인 개발되면 이것도 연결해야 함 - Long userid = Long.valueOf(Optional.ofNullable(ApiLogFunction.getUserId(request)).orElse("1")); + + Long userid = null; + + /** + * servletRequest.getUserPrincipal() instanceof UsernamePasswordAuthenticationToken auth + * 이 요청이 JWT 인증을 통과한 요청인가? 그리고 Spring Security Authentication 객체가 UsernamePasswordAuthenticationToken 타입인가? 체크 + */ + /** + * auth.getPrincipal() instanceof CustomUserDetails customUserDetails + * principal 안에 들어있는 객체가 내가 만든 CustomUserDetails 타입인가? 체크 + */ + if (request.getUserPrincipal() instanceof UsernamePasswordAuthenticationToken auth + && auth.getPrincipal() instanceof CustomUserDetails customUserDetails) { + + // audit 에는 long 타입 user_id가 들어가지만 토큰 sub은 uuid여서 user_id 가져오기 + userid = customUserDetails.getMember().getId(); + } String stackTraceStr = Arrays.stream(stackTrace) diff --git a/src/main/java/com/kamco/cd/kamcoback/config/api/ApiResponseDto.java b/src/main/java/com/kamco/cd/kamcoback/config/api/ApiResponseDto.java index 8c40b5eb..73d665b7 100644 --- a/src/main/java/com/kamco/cd/kamcoback/config/api/ApiResponseDto.java +++ b/src/main/java/com/kamco/cd/kamcoback/config/api/ApiResponseDto.java @@ -67,6 +67,14 @@ public class ApiResponseDto { return new ApiResponseDto<>(data, HttpStatus.OK); } + public static ApiResponseDto okObject(ResponseObj data) { + if (data.getFlag().equals(SuccFailCode.SUCCESS)) { + return new ApiResponseDto<>(data, HttpStatus.OK); + } else{ + return new ApiResponseDto<>(data.getCode(), data.getMessage(), HttpStatus.OK); + } + } + public static ApiResponseDto deleteOk(T data) { return new ApiResponseDto<>(data, HttpStatus.NO_CONTENT); } @@ -106,6 +114,39 @@ public class ApiResponseDto { } } + @Getter + public static class ResponseObj { + + private final SuccFailCode flag; + private final ApiResponseCode code; + private final String message; + + public ResponseObj(SuccFailCode flag, ApiResponseCode code, String message) { + this.flag = flag; + this.code = code; + this.message = message; + } + } + + @Getter + @RequiredArgsConstructor + public enum SuccFailCode implements EnumType { + SUCCESS("성공"), + FAIL("실패"); + + private final String desc; + + @Override + public String getId() { + return name(); + } + + @Override + public String getText() { + return desc; + } + } + @Getter @RequiredArgsConstructor public enum ApiResponseCode implements EnumType { diff --git a/src/main/java/com/kamco/cd/kamcoback/postgres/core/CommonCodeCoreService.java b/src/main/java/com/kamco/cd/kamcoback/postgres/core/CommonCodeCoreService.java index 87d12703..a2779bd9 100644 --- a/src/main/java/com/kamco/cd/kamcoback/postgres/core/CommonCodeCoreService.java +++ b/src/main/java/com/kamco/cd/kamcoback/postgres/core/CommonCodeCoreService.java @@ -3,17 +3,21 @@ package com.kamco.cd.kamcoback.postgres.core; import com.kamco.cd.kamcoback.code.dto.CommonCodeDto; import com.kamco.cd.kamcoback.code.dto.CommonCodeDto.Basic; import com.kamco.cd.kamcoback.common.service.BaseCoreService; +import com.kamco.cd.kamcoback.config.api.ApiResponseDto.ApiResponseCode; +import com.kamco.cd.kamcoback.config.api.ApiResponseDto.ResponseObj; +import com.kamco.cd.kamcoback.config.api.ApiResponseDto.SuccFailCode; import com.kamco.cd.kamcoback.postgres.entity.CommonCodeEntity; import com.kamco.cd.kamcoback.postgres.repository.code.CommonCodeRepository; import com.kamco.cd.kamcoback.zoo.dto.AnimalDto.SearchReq; import jakarta.persistence.EntityNotFoundException; -import java.util.List; -import java.util.Optional; import lombok.RequiredArgsConstructor; import org.springframework.dao.DuplicateKeyException; import org.springframework.data.domain.Page; import org.springframework.stereotype.Service; +import java.util.List; +import java.util.Optional; + @Service @RequiredArgsConstructor public class CommonCodeCoreService @@ -92,7 +96,9 @@ public class CommonCodeCoreService found.getDeleted(), req.getProps1(), req.getProps2(), - req.getProps3()); + req.getProps3(), + null + ); return commonCodeRepository.save(entity).toDto(); } @@ -116,17 +122,30 @@ public class CommonCodeCoreService return commonCodeRepository.getCode(parentCodeCd, childCodeCd); } - @Override - public void remove(Long id) { + /** + * 공통코드 삭제 + * @param id + * @return + */ + public ResponseObj removeCode(Long id) { CommonCodeEntity entity = commonCodeRepository .findByCodeId(id) .orElseThrow(() -> new EntityNotFoundException("code를 찾을 수 없습니다. id " + id)); - // 하위 코드 deleted = false 업데이트 - entity.getChildren().forEach(CommonCodeEntity::deleted); + // 하위코드가 있으면 삭제 불가 + if(!entity.getChildren().isEmpty()){ + return new ResponseObj(SuccFailCode.FAIL, ApiResponseCode.UNPROCESSABLE_ENTITY,"하위에 다른 공통코드를 가지고 있습니다.
하위공통 코드를 이동한 후 삭제할 수 있습니다."); + } + // id 코드 deleted = false 업데이트 entity.deleted(); + return new ResponseObj(SuccFailCode.SUCCESS, ApiResponseCode.OK, "삭제되었습니다."); + } + + @Override + public void remove(Long aLong) { + //미사용 } @Override diff --git a/src/main/java/com/kamco/cd/kamcoback/postgres/entity/CommonCodeEntity.java b/src/main/java/com/kamco/cd/kamcoback/postgres/entity/CommonCodeEntity.java index e8c3e319..cc92b6e3 100644 --- a/src/main/java/com/kamco/cd/kamcoback/postgres/entity/CommonCodeEntity.java +++ b/src/main/java/com/kamco/cd/kamcoback/postgres/entity/CommonCodeEntity.java @@ -15,6 +15,8 @@ import jakarta.persistence.OneToMany; import jakarta.persistence.Table; import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.Size; + +import java.time.ZonedDateTime; import java.util.ArrayList; import java.util.List; import lombok.AccessLevel; @@ -73,6 +75,9 @@ public class CommonCodeEntity extends CommonDateEntity { @Column(name = "props3") private String props3; + @Column(name = "deleted_dttm") + private ZonedDateTime deletedDttm; + public CommonCodeEntity( String code, String name, @@ -102,7 +107,9 @@ public class CommonCodeEntity extends CommonDateEntity { Boolean deleted, String props1, String props2, - String props3) { + String props3, + ZonedDateTime deletedDttm + ) { this.id = id; this.code = code; this.name = name; @@ -113,6 +120,7 @@ public class CommonCodeEntity extends CommonDateEntity { this.props1 = props1; this.props2 = props2; this.props3 = props3; + this.deletedDttm = deletedDttm; } public CommonCodeDto.Basic toDto() { @@ -129,7 +137,9 @@ public class CommonCodeEntity extends CommonDateEntity { super.getModifiedDate(), this.props1, this.props2, - this.props3); + this.props3, + this.deletedDttm + ); } public void addParent(CommonCodeEntity parent) { @@ -142,6 +152,7 @@ public class CommonCodeEntity extends CommonDateEntity { public void deleted() { this.deleted = true; + this.deletedDttm = ZonedDateTime.now(); } public void updateOrder(int order) { diff --git a/src/main/java/com/kamco/cd/kamcoback/postgres/repository/code/CommonCodeRepositoryImpl.java b/src/main/java/com/kamco/cd/kamcoback/postgres/repository/code/CommonCodeRepositoryImpl.java index 8e5bebb7..1d35e44c 100644 --- a/src/main/java/com/kamco/cd/kamcoback/postgres/repository/code/CommonCodeRepositoryImpl.java +++ b/src/main/java/com/kamco/cd/kamcoback/postgres/repository/code/CommonCodeRepositoryImpl.java @@ -29,7 +29,11 @@ public class CommonCodeRepositoryImpl implements CommonCodeRepositoryCustom { .selectFrom(commonCodeEntity) .leftJoin(commonCodeEntity.children, child) .fetchJoin() - .where(commonCodeEntity.id.eq(id), commonCodeEntity.deleted.isFalse()) + .where( + commonCodeEntity.id.eq(id), + commonCodeEntity.deleted.isFalse().or(commonCodeEntity.deleted.isNull()), + child.deleted.isFalse().or(child.deleted.isNull()) + ) .orderBy(commonCodeEntity.order.asc(), child.order.asc()) .fetchOne()); } @@ -46,7 +50,9 @@ public class CommonCodeRepositoryImpl implements CommonCodeRepositoryCustom { commonCodeEntity.parent.isNull(), commonCodeEntity.code.eq(code), commonCodeEntity.used.isTrue(), - commonCodeEntity.deleted.isFalse()) + commonCodeEntity.deleted.isFalse().or(commonCodeEntity.deleted.isNull()), + child.deleted.isFalse().or(child.deleted.isNull()) + ) .orderBy(child.order.asc()) .fetchOne()); } @@ -58,7 +64,11 @@ public class CommonCodeRepositoryImpl implements CommonCodeRepositoryCustom { .selectFrom(commonCodeEntity) .leftJoin(commonCodeEntity.children, child) .fetchJoin() - .where(commonCodeEntity.parent.isNull(), commonCodeEntity.deleted.isFalse()) + .where( + commonCodeEntity.parent.isNull(), + commonCodeEntity.deleted.isFalse().or(commonCodeEntity.deleted.isNull()), + child.deleted.isFalse().or(child.deleted.isNull()) + ) .orderBy(commonCodeEntity.order.asc(), child.order.asc()) .fetch(); } @@ -90,7 +100,10 @@ public class CommonCodeRepositoryImpl implements CommonCodeRepositoryCustom { .select(child.name) .from(child) .join(child.parent, parent) - .where(parent.code.eq(parentCodeCd).and(child.code.eq(childCodeCd))) + .where( + parent.code.eq(parentCodeCd).and(child.code.eq(childCodeCd)), + child.deleted.isFalse().or(child.deleted.isNull()) + ) .fetchFirst(); // 단일 결과만 return Optional.ofNullable(result); @@ -120,7 +133,7 @@ public class CommonCodeRepositoryImpl implements CommonCodeRepositoryCustom { private List findAllByIds(Set ids) { return queryFactory .selectFrom(commonCodeEntity) - .where(commonCodeEntity.id.in(ids), commonCodeEntity.deleted.isFalse()) + .where(commonCodeEntity.id.in(ids), commonCodeEntity.deleted.isFalse().or(commonCodeEntity.deleted.isNull())) .fetch(); } }