feat: 들여쓰기
This commit is contained in:
21
build.gradle
21
build.gradle
@@ -60,30 +60,13 @@ bootJar {
|
|||||||
archiveFileName = 'ROOT.jar'
|
archiveFileName = 'ROOT.jar'
|
||||||
}
|
}
|
||||||
|
|
||||||
// Spotless configuration for code formatting
|
// Spotless configuration for code formatting (2-space indent)
|
||||||
//spotless {
|
|
||||||
// java {
|
|
||||||
// target 'src/**/*.java'
|
|
||||||
// googleJavaFormat('1.19.2').aosp().reflowLongStrings()
|
|
||||||
// indentWithSpaces(2)
|
|
||||||
// trimTrailingWhitespace()
|
|
||||||
// endWithNewline()
|
|
||||||
// importOrder()
|
|
||||||
// removeUnusedImports()
|
|
||||||
// formatAnnotations()
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
|
|
||||||
|
|
||||||
spotless {
|
spotless {
|
||||||
java {
|
java {
|
||||||
target 'src/**/*.java'
|
target 'src/**/*.java'
|
||||||
indentWithSpaces(2)
|
googleJavaFormat('1.19.2') // Default Google Style = 2 spaces (NO .aosp()!)
|
||||||
trimTrailingWhitespace()
|
trimTrailingWhitespace()
|
||||||
endWithNewline()
|
endWithNewline()
|
||||||
importOrder()
|
|
||||||
removeUnusedImports()
|
|
||||||
formatAnnotations()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
|
|||||||
@SpringBootApplication
|
@SpringBootApplication
|
||||||
public class KamcoBackApplication {
|
public class KamcoBackApplication {
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
SpringApplication.run(KamcoBackApplication.class, args);
|
SpringApplication.run(KamcoBackApplication.class, args);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,14 +12,14 @@ import org.springframework.web.bind.annotation.RestController;
|
|||||||
@RequestMapping("/api/hello")
|
@RequestMapping("/api/hello")
|
||||||
public class HelloApiController {
|
public class HelloApiController {
|
||||||
|
|
||||||
private final HelloService helloService;
|
private final HelloService helloService;
|
||||||
|
|
||||||
@GetMapping
|
@GetMapping
|
||||||
public HelloDto.Res hello(HelloDto.Req req) {
|
public HelloDto.Res hello(HelloDto.Req req) {
|
||||||
req.valid();
|
req.valid();
|
||||||
|
|
||||||
Res res = helloService.sayHello(req);
|
Res res = helloService.sayHello(req);
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,29 +8,29 @@ import lombok.Setter;
|
|||||||
|
|
||||||
public class HelloDto {
|
public class HelloDto {
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
@Setter
|
@Setter
|
||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
public static class Req {
|
public static class Req {
|
||||||
private String id;
|
private String id;
|
||||||
|
|
||||||
public void valid() {
|
public void valid() {
|
||||||
if (id == null) {
|
if (id == null) {
|
||||||
throw new IllegalArgumentException(id);
|
throw new IllegalArgumentException(id);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
public static class Res {
|
public static class Res {
|
||||||
private String id;
|
private String id;
|
||||||
private String name;
|
private String name;
|
||||||
|
|
||||||
@Builder
|
@Builder
|
||||||
public Res(String id, String name) {
|
public Res(String id, String name) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,26 +13,26 @@ import org.springframework.data.domain.Page;
|
|||||||
*/
|
*/
|
||||||
public interface BaseCoreService<T, ID, S> {
|
public interface BaseCoreService<T, ID, S> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ID로 엔티티를 삭제합니다.
|
* ID로 엔티티를 삭제합니다.
|
||||||
*
|
*
|
||||||
* @param id 삭제할 엔티티의 ID
|
* @param id 삭제할 엔티티의 ID
|
||||||
*/
|
*/
|
||||||
void remove(ID id);
|
void remove(ID id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ID로 단건 조회합니다.
|
* ID로 단건 조회합니다.
|
||||||
*
|
*
|
||||||
* @param id 조회할 엔티티의 ID
|
* @param id 조회할 엔티티의 ID
|
||||||
* @return 조회된 엔티티
|
* @return 조회된 엔티티
|
||||||
*/
|
*/
|
||||||
T getOneById(ID id);
|
T getOneById(ID id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 검색 조건과 페이징으로 조회합니다.
|
* 검색 조건과 페이징으로 조회합니다.
|
||||||
*
|
*
|
||||||
* @param searchReq 검색 조건
|
* @param searchReq 검색 조건
|
||||||
* @return 페이징 처리된 검색 결과
|
* @return 페이징 처리된 검색 결과
|
||||||
*/
|
*/
|
||||||
Page<T> search(S searchReq);
|
Page<T> search(S searchReq);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,9 +9,9 @@ import org.springframework.stereotype.Service;
|
|||||||
@Service
|
@Service
|
||||||
public class HelloService {
|
public class HelloService {
|
||||||
|
|
||||||
public HelloDto.Res sayHello(HelloDto.Req req) {
|
public HelloDto.Res sayHello(HelloDto.Req req) {
|
||||||
log.info("hello");
|
log.info("hello");
|
||||||
String name = UUID.randomUUID().toString();
|
String name = UUID.randomUUID().toString();
|
||||||
return HelloDto.Res.builder().id(req.getId()).name(name).build();
|
return HelloDto.Res.builder().id(req.getId()).name(name).build();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,26 +11,26 @@ import org.springframework.util.StringUtils;
|
|||||||
|
|
||||||
public class GeometryDeserializer<T extends Geometry> extends StdDeserializer<T> {
|
public class GeometryDeserializer<T extends Geometry> extends StdDeserializer<T> {
|
||||||
|
|
||||||
public GeometryDeserializer(Class<T> targetType) {
|
public GeometryDeserializer(Class<T> targetType) {
|
||||||
super(targetType);
|
super(targetType);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: test code
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
@Override
|
||||||
|
public T deserialize(JsonParser jsonParser, DeserializationContext deserializationContext)
|
||||||
|
throws IOException, JacksonException {
|
||||||
|
String json = jsonParser.readValueAsTree().toString();
|
||||||
|
|
||||||
|
if (!StringUtils.hasText(json)) {
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: test code
|
try {
|
||||||
@SuppressWarnings("unchecked")
|
GeoJsonReader reader = new GeoJsonReader();
|
||||||
@Override
|
return (T) reader.read(json);
|
||||||
public T deserialize(JsonParser jsonParser, DeserializationContext deserializationContext)
|
} catch (Exception e) {
|
||||||
throws IOException, JacksonException {
|
throw new IllegalArgumentException("Failed to deserialize GeoJSON into Geometry", e);
|
||||||
String json = jsonParser.readValueAsTree().toString();
|
|
||||||
|
|
||||||
if (!StringUtils.hasText(json)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
GeoJsonReader reader = new GeoJsonReader();
|
|
||||||
return (T) reader.read(json);
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new IllegalArgumentException("Failed to deserialize GeoJSON into Geometry", e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,22 +10,22 @@ import org.locationtech.jts.io.geojson.GeoJsonWriter;
|
|||||||
|
|
||||||
public class GeometrySerializer<T extends Geometry> extends StdSerializer<T> {
|
public class GeometrySerializer<T extends Geometry> extends StdSerializer<T> {
|
||||||
|
|
||||||
// TODO: test code
|
// TODO: test code
|
||||||
public GeometrySerializer(Class<T> targetType) {
|
public GeometrySerializer(Class<T> targetType) {
|
||||||
super(targetType);
|
super(targetType);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void serialize(
|
public void serialize(
|
||||||
T geometry, JsonGenerator jsonGenerator, SerializerProvider serializerProvider)
|
T geometry, JsonGenerator jsonGenerator, SerializerProvider serializerProvider)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
if (Objects.nonNull(geometry)) {
|
if (Objects.nonNull(geometry)) {
|
||||||
// default: 8자리 강제로 반올림시킴. 16자리로 늘려줌
|
// default: 8자리 강제로 반올림시킴. 16자리로 늘려줌
|
||||||
GeoJsonWriter writer = new GeoJsonWriter(16);
|
GeoJsonWriter writer = new GeoJsonWriter(16);
|
||||||
String json = writer.write(geometry);
|
String json = writer.write(geometry);
|
||||||
jsonGenerator.writeRawValue(json);
|
jsonGenerator.writeRawValue(json);
|
||||||
} else {
|
} else {
|
||||||
jsonGenerator.writeNull();
|
jsonGenerator.writeNull();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,49 +14,47 @@ import org.springframework.stereotype.Component;
|
|||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class StartupLogger {
|
public class StartupLogger {
|
||||||
|
|
||||||
private final Environment environment;
|
private final Environment environment;
|
||||||
private final DataSource dataSource;
|
private final DataSource dataSource;
|
||||||
|
|
||||||
@EventListener(ApplicationReadyEvent.class)
|
@EventListener(ApplicationReadyEvent.class)
|
||||||
public void logStartupInfo() {
|
public void logStartupInfo() {
|
||||||
String[] activeProfiles = environment.getActiveProfiles();
|
String[] activeProfiles = environment.getActiveProfiles();
|
||||||
String profileInfo =
|
String profileInfo = activeProfiles.length > 0 ? String.join(", ", activeProfiles) : "default";
|
||||||
activeProfiles.length > 0 ? String.join(", ", activeProfiles) : "default";
|
|
||||||
|
|
||||||
// Database connection information
|
// Database connection information
|
||||||
String dbUrl = environment.getProperty("spring.datasource.url");
|
String dbUrl = environment.getProperty("spring.datasource.url");
|
||||||
String dbUsername = environment.getProperty("spring.datasource.username");
|
String dbUsername = environment.getProperty("spring.datasource.username");
|
||||||
String dbDriver = environment.getProperty("spring.datasource.driver-class-name");
|
String dbDriver = environment.getProperty("spring.datasource.driver-class-name");
|
||||||
|
|
||||||
// HikariCP pool settings
|
// HikariCP pool settings
|
||||||
String poolInfo = "";
|
String poolInfo = "";
|
||||||
if (dataSource instanceof HikariDataSource hikariDs) {
|
if (dataSource instanceof HikariDataSource hikariDs) {
|
||||||
poolInfo =
|
poolInfo =
|
||||||
String.format(
|
String.format(
|
||||||
"""
|
"""
|
||||||
│ Pool Size : min=%d, max=%d
|
│ Pool Size : min=%d, max=%d
|
||||||
│ Connection Timeout: %dms
|
│ Connection Timeout: %dms
|
||||||
│ Idle Timeout : %dms
|
│ Idle Timeout : %dms
|
||||||
│ Max Lifetime : %dms""",
|
│ Max Lifetime : %dms""",
|
||||||
hikariDs.getMinimumIdle(),
|
hikariDs.getMinimumIdle(),
|
||||||
hikariDs.getMaximumPoolSize(),
|
hikariDs.getMaximumPoolSize(),
|
||||||
hikariDs.getConnectionTimeout(),
|
hikariDs.getConnectionTimeout(),
|
||||||
hikariDs.getIdleTimeout(),
|
hikariDs.getIdleTimeout(),
|
||||||
hikariDs.getMaxLifetime());
|
hikariDs.getMaxLifetime());
|
||||||
}
|
}
|
||||||
|
|
||||||
// JPA/Hibernate settings
|
// JPA/Hibernate settings
|
||||||
String showSql = environment.getProperty("spring.jpa.show-sql", "false");
|
String showSql = environment.getProperty("spring.jpa.show-sql", "false");
|
||||||
String ddlAuto = environment.getProperty("spring.jpa.hibernate.ddl-auto", "none");
|
String ddlAuto = environment.getProperty("spring.jpa.hibernate.ddl-auto", "none");
|
||||||
String batchSize =
|
String batchSize =
|
||||||
environment.getProperty("spring.jpa.properties.hibernate.jdbc.batch_size", "N/A");
|
environment.getProperty("spring.jpa.properties.hibernate.jdbc.batch_size", "N/A");
|
||||||
String batchFetchSize =
|
String batchFetchSize =
|
||||||
environment.getProperty(
|
environment.getProperty("spring.jpa.properties.hibernate.default_batch_fetch_size", "N/A");
|
||||||
"spring.jpa.properties.hibernate.default_batch_fetch_size", "N/A");
|
|
||||||
|
|
||||||
String startupMessage =
|
String startupMessage =
|
||||||
String.format(
|
String.format(
|
||||||
"""
|
"""
|
||||||
|
|
||||||
╔════════════════════════════════════════════════════════════════════════════════╗
|
╔════════════════════════════════════════════════════════════════════════════════╗
|
||||||
║ 🚀 APPLICATION STARTUP INFORMATION ║
|
║ 🚀 APPLICATION STARTUP INFORMATION ║
|
||||||
@@ -83,16 +81,16 @@ public class StartupLogger {
|
|||||||
│ Fetch Batch Size : %s
|
│ Fetch Batch Size : %s
|
||||||
╚════════════════════════════════════════════════════════════════════════════════╝
|
╚════════════════════════════════════════════════════════════════════════════════╝
|
||||||
""",
|
""",
|
||||||
profileInfo,
|
profileInfo,
|
||||||
dbUrl != null ? dbUrl : "N/A",
|
dbUrl != null ? dbUrl : "N/A",
|
||||||
dbUsername != null ? dbUsername : "N/A",
|
dbUsername != null ? dbUsername : "N/A",
|
||||||
dbDriver != null ? dbDriver : "PostgreSQL JDBC Driver (auto-detected)",
|
dbDriver != null ? dbDriver : "PostgreSQL JDBC Driver (auto-detected)",
|
||||||
poolInfo,
|
poolInfo,
|
||||||
showSql,
|
showSql,
|
||||||
ddlAuto,
|
ddlAuto,
|
||||||
batchSize,
|
batchSize,
|
||||||
batchFetchSize);
|
batchFetchSize);
|
||||||
|
|
||||||
log.info(startupMessage);
|
log.info(startupMessage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,18 +14,18 @@ import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
|
|||||||
@Configuration
|
@Configuration
|
||||||
public class WebConfig {
|
public class WebConfig {
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public ObjectMapper objectMapper() {
|
public ObjectMapper objectMapper() {
|
||||||
SimpleModule module = new SimpleModule();
|
SimpleModule module = new SimpleModule();
|
||||||
module.addSerializer(Geometry.class, new GeometrySerializer<>(Geometry.class));
|
module.addSerializer(Geometry.class, new GeometrySerializer<>(Geometry.class));
|
||||||
module.addDeserializer(Geometry.class, new GeometryDeserializer<>(Geometry.class));
|
module.addDeserializer(Geometry.class, new GeometryDeserializer<>(Geometry.class));
|
||||||
|
|
||||||
module.addSerializer(Polygon.class, new GeometrySerializer<>(Polygon.class));
|
module.addSerializer(Polygon.class, new GeometrySerializer<>(Polygon.class));
|
||||||
module.addDeserializer(Polygon.class, new GeometryDeserializer<>(Polygon.class));
|
module.addDeserializer(Polygon.class, new GeometryDeserializer<>(Polygon.class));
|
||||||
|
|
||||||
module.addSerializer(Point.class, new GeometrySerializer<>(Point.class));
|
module.addSerializer(Point.class, new GeometrySerializer<>(Point.class));
|
||||||
module.addDeserializer(Point.class, new GeometryDeserializer<>(Point.class));
|
module.addDeserializer(Point.class, new GeometryDeserializer<>(Point.class));
|
||||||
|
|
||||||
return Jackson2ObjectMapperBuilder.json().modulesToInstall(module).build();
|
return Jackson2ObjectMapperBuilder.json().modulesToInstall(module).build();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,111 +10,111 @@ import lombok.ToString;
|
|||||||
@ToString
|
@ToString
|
||||||
public class ApiResponseDto<T> {
|
public class ApiResponseDto<T> {
|
||||||
|
|
||||||
private T data;
|
private T data;
|
||||||
|
|
||||||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||||
private Error error;
|
private Error error;
|
||||||
|
|
||||||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||||
private T errorData;
|
private T errorData;
|
||||||
|
|
||||||
public ApiResponseDto(T data) {
|
public ApiResponseDto(T data) {
|
||||||
this.data = data;
|
this.data = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ApiResponseDto(ApiResponseCode code) {
|
||||||
|
this.error = new Error(code.getId(), code.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
public ApiResponseDto(ApiResponseCode code, String message) {
|
||||||
|
this.error = new Error(code.getId(), message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ApiResponseDto(ApiResponseCode code, String message, T errorData) {
|
||||||
|
this.error = new Error(code.getId(), message);
|
||||||
|
this.errorData = errorData;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> ApiResponseDto<T> createOK(T data) {
|
||||||
|
return new ApiResponseDto<>(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ApiResponseDto<String> createException(ApiResponseCode code) {
|
||||||
|
return new ApiResponseDto<>(code);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ApiResponseDto<String> createException(ApiResponseCode code, String message) {
|
||||||
|
return new ApiResponseDto<>(code, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> ApiResponseDto<T> createException(
|
||||||
|
ApiResponseCode code, String message, T data) {
|
||||||
|
return new ApiResponseDto<>(code, message, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
public static class Error {
|
||||||
|
|
||||||
|
private final String code;
|
||||||
|
private final String message;
|
||||||
|
|
||||||
|
public Error(String code, String message) {
|
||||||
|
this.code = code;
|
||||||
|
this.message = message;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public enum ApiResponseCode implements EnumType {
|
||||||
|
|
||||||
|
// @formatter:off
|
||||||
|
OK("요청이 성공하였습니다."),
|
||||||
|
BAD_REQUEST("요청 파라미터가 잘못되었습니다."),
|
||||||
|
ALREADY_EXIST_MALL("이미 등록된 쇼핑센터입니다."),
|
||||||
|
NOT_FOUND_MAP("지도를 찾을 수 없습니다."),
|
||||||
|
UNAUTHORIZED("권한이 없습니다."),
|
||||||
|
CONFLICT("이미 등록된 컨텐츠입니다."),
|
||||||
|
NOT_FOUND("Resource를 찾을 수 없습니다."),
|
||||||
|
NOT_FOUND_DATA("데이터를 찾을 수 없습니다."),
|
||||||
|
NOT_FOUND_WEATHER_DATA("날씨 데이터를 찾을 수 없습니다."),
|
||||||
|
FAIL_SEND_MESSAGE("메시지를 전송하지 못했습니다."),
|
||||||
|
TOO_MANY_CONNECTED_MACHINES("연결된 기기가 너무 많습니다."),
|
||||||
|
UNAUTHENTICATED("인증에 실패하였습니다."),
|
||||||
|
INVALID_TOKEN("잘못된 토큰입니다."),
|
||||||
|
EXPIRED_TOKEN("만료된 토큰입니다."),
|
||||||
|
INTERNAL_SERVER_ERROR("서버에 문제가 발생 하였습니다."),
|
||||||
|
FORBIDDEN("권한을 확인해주세요."),
|
||||||
|
INVALID_PASSWORD("잘못된 비밀번호 입니다."),
|
||||||
|
NOT_FOUND_CAR_IN("입차정보가 없습니다."),
|
||||||
|
WRONG_STATUS("잘못된 상태입니다."),
|
||||||
|
FAIL_VERIFICATION("인증에 실패하였습니다."),
|
||||||
|
INVALID_EMAIL("잘못된 형식의 이메일입니다."),
|
||||||
|
REQUIRED_EMAIL("이메일은 필수 항목입니다."),
|
||||||
|
WRONG_PASSWORD("잘못된 패스워드입니다.."),
|
||||||
|
DUPLICATE_EMAIL("이미 가입된 이메일입니다."),
|
||||||
|
DUPLICATE_DATA("이미 등록되여 있습니다."),
|
||||||
|
DATA_INTEGRITY_ERROR("요청을 처리할수 없습니다."),
|
||||||
|
FOREIGN_KEY_ERROR("참조 중인 데이터가 있어 삭제할 수 없습니다."),
|
||||||
|
DUPLICATE_EMPLOYEEID("이미 가입된 사번입니다."),
|
||||||
|
NOT_FOUND_USER_FOR_EMAIL("이메일로 유저를 찾을 수 없습니다."),
|
||||||
|
NOT_FOUND_USER("사용자를 찾을 수 없습니다."),
|
||||||
|
INVALID_EMAIL_TOKEN(
|
||||||
|
"You can only reset your password within 24 hours from when the email was sent.\n"
|
||||||
|
+ "To reset your password again, please submit a new request through \"Forgot"
|
||||||
|
+ " Password.\""),
|
||||||
|
;
|
||||||
|
// @formatter:on
|
||||||
|
private final String message;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getId() {
|
||||||
|
return name();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ApiResponseDto(ApiResponseCode code) {
|
@Override
|
||||||
this.error = new Error(code.getId(), code.getMessage());
|
public String getText() {
|
||||||
}
|
return message;
|
||||||
|
|
||||||
public ApiResponseDto(ApiResponseCode code, String message) {
|
|
||||||
this.error = new Error(code.getId(), message);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ApiResponseDto(ApiResponseCode code, String message, T errorData) {
|
|
||||||
this.error = new Error(code.getId(), message);
|
|
||||||
this.errorData = errorData;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static <T> ApiResponseDto<T> createOK(T data) {
|
|
||||||
return new ApiResponseDto<>(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static ApiResponseDto<String> createException(ApiResponseCode code) {
|
|
||||||
return new ApiResponseDto<>(code);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static ApiResponseDto<String> createException(ApiResponseCode code, String message) {
|
|
||||||
return new ApiResponseDto<>(code, message);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static <T> ApiResponseDto<T> createException(
|
|
||||||
ApiResponseCode code, String message, T data) {
|
|
||||||
return new ApiResponseDto<>(code, message, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
public static class Error {
|
|
||||||
|
|
||||||
private final String code;
|
|
||||||
private final String message;
|
|
||||||
|
|
||||||
public Error(String code, String message) {
|
|
||||||
this.code = code;
|
|
||||||
this.message = message;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
@RequiredArgsConstructor
|
|
||||||
public enum ApiResponseCode implements EnumType {
|
|
||||||
|
|
||||||
// @formatter:off
|
|
||||||
OK("요청이 성공하였습니다."),
|
|
||||||
BAD_REQUEST("요청 파라미터가 잘못되었습니다."),
|
|
||||||
ALREADY_EXIST_MALL("이미 등록된 쇼핑센터입니다."),
|
|
||||||
NOT_FOUND_MAP("지도를 찾을 수 없습니다."),
|
|
||||||
UNAUTHORIZED("권한이 없습니다."),
|
|
||||||
CONFLICT("이미 등록된 컨텐츠입니다."),
|
|
||||||
NOT_FOUND("Resource를 찾을 수 없습니다."),
|
|
||||||
NOT_FOUND_DATA("데이터를 찾을 수 없습니다."),
|
|
||||||
NOT_FOUND_WEATHER_DATA("날씨 데이터를 찾을 수 없습니다."),
|
|
||||||
FAIL_SEND_MESSAGE("메시지를 전송하지 못했습니다."),
|
|
||||||
TOO_MANY_CONNECTED_MACHINES("연결된 기기가 너무 많습니다."),
|
|
||||||
UNAUTHENTICATED("인증에 실패하였습니다."),
|
|
||||||
INVALID_TOKEN("잘못된 토큰입니다."),
|
|
||||||
EXPIRED_TOKEN("만료된 토큰입니다."),
|
|
||||||
INTERNAL_SERVER_ERROR("서버에 문제가 발생 하였습니다."),
|
|
||||||
FORBIDDEN("권한을 확인해주세요."),
|
|
||||||
INVALID_PASSWORD("잘못된 비밀번호 입니다."),
|
|
||||||
NOT_FOUND_CAR_IN("입차정보가 없습니다."),
|
|
||||||
WRONG_STATUS("잘못된 상태입니다."),
|
|
||||||
FAIL_VERIFICATION("인증에 실패하였습니다."),
|
|
||||||
INVALID_EMAIL("잘못된 형식의 이메일입니다."),
|
|
||||||
REQUIRED_EMAIL("이메일은 필수 항목입니다."),
|
|
||||||
WRONG_PASSWORD("잘못된 패스워드입니다.."),
|
|
||||||
DUPLICATE_EMAIL("이미 가입된 이메일입니다."),
|
|
||||||
DUPLICATE_DATA("이미 등록되여 있습니다."),
|
|
||||||
DATA_INTEGRITY_ERROR("요청을 처리할수 없습니다."),
|
|
||||||
FOREIGN_KEY_ERROR("참조 중인 데이터가 있어 삭제할 수 없습니다."),
|
|
||||||
DUPLICATE_EMPLOYEEID("이미 가입된 사번입니다."),
|
|
||||||
NOT_FOUND_USER_FOR_EMAIL("이메일로 유저를 찾을 수 없습니다."),
|
|
||||||
NOT_FOUND_USER("사용자를 찾을 수 없습니다."),
|
|
||||||
INVALID_EMAIL_TOKEN(
|
|
||||||
"You can only reset your password within 24 hours from when the email was sent.\n"
|
|
||||||
+ "To reset your password again, please submit a new request through \"Forgot"
|
|
||||||
+ " Password.\""),
|
|
||||||
;
|
|
||||||
// @formatter:on
|
|
||||||
private final String message;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getId() {
|
|
||||||
return name();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getText() {
|
|
||||||
return message;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ package com.kamco.cd.kamcoback.config.enums;
|
|||||||
|
|
||||||
public interface EnumType {
|
public interface EnumType {
|
||||||
|
|
||||||
String getId();
|
String getId();
|
||||||
|
|
||||||
String getText();
|
String getText();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,22 +13,22 @@ import org.springframework.data.annotation.LastModifiedDate;
|
|||||||
@MappedSuperclass
|
@MappedSuperclass
|
||||||
public class CommonDateEntity {
|
public class CommonDateEntity {
|
||||||
|
|
||||||
@CreatedDate
|
@CreatedDate
|
||||||
@Column(name = "created_date", updatable = false, nullable = false)
|
@Column(name = "created_date", updatable = false, nullable = false)
|
||||||
private ZonedDateTime createdDate;
|
private ZonedDateTime createdDate;
|
||||||
|
|
||||||
@LastModifiedDate
|
@LastModifiedDate
|
||||||
@Column(name = "modified_date", nullable = false)
|
@Column(name = "modified_date", nullable = false)
|
||||||
private ZonedDateTime modifiedDate;
|
private ZonedDateTime modifiedDate;
|
||||||
|
|
||||||
@PrePersist
|
@PrePersist
|
||||||
protected void onPersist() {
|
protected void onPersist() {
|
||||||
this.createdDate = ZonedDateTime.now();
|
this.createdDate = ZonedDateTime.now();
|
||||||
this.modifiedDate = ZonedDateTime.now();
|
this.modifiedDate = ZonedDateTime.now();
|
||||||
}
|
}
|
||||||
|
|
||||||
@PreUpdate
|
@PreUpdate
|
||||||
protected void onUpdate() {
|
protected void onUpdate() {
|
||||||
this.modifiedDate = ZonedDateTime.now();
|
this.modifiedDate = ZonedDateTime.now();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,10 +10,10 @@ import org.springframework.context.annotation.Configuration;
|
|||||||
@Configuration
|
@Configuration
|
||||||
public class QueryDslConfig {
|
public class QueryDslConfig {
|
||||||
|
|
||||||
private final EntityManager entityManager;
|
private final EntityManager entityManager;
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public JPAQueryFactory jpaQueryFactory() {
|
public JPAQueryFactory jpaQueryFactory() {
|
||||||
return new JPAQueryFactory(entityManager);
|
return new JPAQueryFactory(entityManager);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,67 +16,59 @@ import org.springframework.transaction.annotation.Transactional;
|
|||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
@Transactional(readOnly = true)
|
@Transactional(readOnly = true)
|
||||||
public class AnimalCoreService
|
public class AnimalCoreService
|
||||||
implements BaseCoreService<AnimalDto.Basic, Long, AnimalDto.SearchReq> {
|
implements BaseCoreService<AnimalDto.Basic, Long, AnimalDto.SearchReq> {
|
||||||
|
|
||||||
private final AnimalRepository animalRepository;
|
private final AnimalRepository animalRepository;
|
||||||
private final ZooRepository zooRepository;
|
private final ZooRepository zooRepository;
|
||||||
|
|
||||||
@Transactional(readOnly = true)
|
@Transactional(readOnly = true)
|
||||||
public AnimalDto.Basic getDataByUuid(String uuid) {
|
public AnimalDto.Basic getDataByUuid(String uuid) {
|
||||||
AnimalEntity getZoo =
|
AnimalEntity getZoo =
|
||||||
animalRepository
|
animalRepository
|
||||||
.getAnimalByUuid(uuid)
|
.getAnimalByUuid(uuid)
|
||||||
.orElseThrow(
|
.orElseThrow(() -> new EntityNotFoundException("Zoo not found with uuid: " + uuid));
|
||||||
() ->
|
return getZoo.toDto();
|
||||||
new EntityNotFoundException(
|
}
|
||||||
"Zoo not found with uuid: " + uuid));
|
|
||||||
return getZoo.toDto();
|
// AddReq를 받는 추가 메서드
|
||||||
|
@Transactional
|
||||||
|
public AnimalDto.Basic create(AnimalDto.AddReq req) {
|
||||||
|
ZooEntity zoo = null;
|
||||||
|
if (req.getZooId() != null) {
|
||||||
|
zoo =
|
||||||
|
zooRepository
|
||||||
|
.getZooByUid(req.getZooId())
|
||||||
|
.orElseThrow(
|
||||||
|
() -> new EntityNotFoundException(" not found with id: " + req.getZooId()));
|
||||||
}
|
}
|
||||||
|
AnimalEntity entity = new AnimalEntity(req.getCategory(), req.getSpecies(), req.getName(), zoo);
|
||||||
|
AnimalEntity saved = animalRepository.save(entity);
|
||||||
|
return saved.toDto();
|
||||||
|
}
|
||||||
|
|
||||||
// AddReq를 받는 추가 메서드
|
@Override
|
||||||
@Transactional
|
@Transactional
|
||||||
public AnimalDto.Basic create(AnimalDto.AddReq req) {
|
public void remove(Long id) {
|
||||||
ZooEntity zoo = null;
|
AnimalEntity getAnimal =
|
||||||
if (req.getZooId() != null) {
|
animalRepository
|
||||||
zoo =
|
.getAnimalByUid(id)
|
||||||
zooRepository
|
.orElseThrow(() -> new EntityNotFoundException("getAnimal not found with id: " + id));
|
||||||
.getZooByUid(req.getZooId())
|
getAnimal.deleted();
|
||||||
.orElseThrow(
|
}
|
||||||
() ->
|
|
||||||
new EntityNotFoundException(
|
|
||||||
"Zoo not found with id: " + req.getZooId()));
|
|
||||||
}
|
|
||||||
AnimalEntity entity =
|
|
||||||
new AnimalEntity(req.getCategory(), req.getSpecies(), req.getName(), zoo);
|
|
||||||
AnimalEntity saved = animalRepository.save(entity);
|
|
||||||
return saved.toDto();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional
|
public AnimalDto.Basic getOneById(Long id) {
|
||||||
public void remove(Long id) {
|
AnimalEntity getAnimal =
|
||||||
AnimalEntity getZoo =
|
animalRepository
|
||||||
animalRepository
|
.getAnimalByUid(id)
|
||||||
.getAnimalByUid(id)
|
.orElseThrow(() -> new EntityNotFoundException("Zoo not found with id: " + id));
|
||||||
.orElseThrow(
|
return getAnimal.toDto();
|
||||||
() -> new EntityNotFoundException("Zoo not found with id: " + id));
|
}
|
||||||
getZoo.deleted();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AnimalDto.Basic getOneById(Long id) {
|
public Page<AnimalDto.Basic> search(AnimalDto.SearchReq searchReq) {
|
||||||
AnimalEntity getZoo =
|
|
||||||
animalRepository
|
|
||||||
.getAnimalByUid(id)
|
|
||||||
.orElseThrow(
|
|
||||||
() -> new EntityNotFoundException("Zoo not found with id: " + id));
|
|
||||||
return getZoo.toDto();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
Page<AnimalEntity> animalEntities = animalRepository.listAnimal(searchReq);
|
||||||
public Page<AnimalDto.Basic> search(AnimalDto.SearchReq searchReq) {
|
return animalEntities.map(AnimalEntity::toDto);
|
||||||
|
}
|
||||||
Page<AnimalEntity> zooEntities = animalRepository.listAnimal(searchReq);
|
|
||||||
return zooEntities.map(AnimalEntity::toDto);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,66 +15,61 @@ import org.springframework.transaction.annotation.Transactional;
|
|||||||
@Transactional(readOnly = true)
|
@Transactional(readOnly = true)
|
||||||
public class ZooCoreService implements BaseCoreService<ZooDto.Detail, Long, ZooDto.SearchReq> {
|
public class ZooCoreService implements BaseCoreService<ZooDto.Detail, Long, ZooDto.SearchReq> {
|
||||||
|
|
||||||
private final ZooRepository zooRepository;
|
private final ZooRepository zooRepository;
|
||||||
|
|
||||||
@Transactional(readOnly = true)
|
@Transactional(readOnly = true)
|
||||||
public ZooDto.Detail getDataByUuid(String uuid) {
|
public ZooDto.Detail getDataByUuid(String uuid) {
|
||||||
ZooEntity zoo =
|
ZooEntity zoo =
|
||||||
zooRepository
|
zooRepository
|
||||||
.getZooByUuid(uuid)
|
.getZooByUuid(uuid)
|
||||||
.orElseThrow(
|
.orElseThrow(() -> new EntityNotFoundException("Zoo not found with uuid: " + uuid));
|
||||||
() ->
|
return toDetailDto(zoo);
|
||||||
new EntityNotFoundException(
|
}
|
||||||
"Zoo not found with uuid: " + uuid));
|
|
||||||
return toDetailDto(zoo);
|
|
||||||
}
|
|
||||||
|
|
||||||
// AddReq를 받는 추가 메서드
|
// AddReq를 받는 추가 메서드
|
||||||
@Transactional
|
@Transactional
|
||||||
public ZooDto.Detail create(ZooDto.AddReq req) {
|
public ZooDto.Detail create(ZooDto.AddReq req) {
|
||||||
ZooEntity entity = new ZooEntity(req.getName(), req.getLocation(), req.getDescription());
|
ZooEntity entity = new ZooEntity(req.getName(), req.getLocation(), req.getDescription());
|
||||||
ZooEntity saved = zooRepository.save(entity);
|
ZooEntity saved = zooRepository.save(entity);
|
||||||
return toDetailDto(saved);
|
return toDetailDto(saved);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional
|
@Transactional
|
||||||
public void remove(Long id) {
|
public void remove(Long id) {
|
||||||
ZooEntity zoo =
|
ZooEntity zoo =
|
||||||
zooRepository
|
zooRepository
|
||||||
.getZooByUid(id)
|
.getZooByUid(id)
|
||||||
.orElseThrow(
|
.orElseThrow(() -> new EntityNotFoundException("Zoo not found with id: " + id));
|
||||||
() -> new EntityNotFoundException("Zoo not found with id: " + id));
|
zoo.deleted();
|
||||||
zoo.deleted();
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ZooDto.Detail getOneById(Long id) {
|
public ZooDto.Detail getOneById(Long id) {
|
||||||
ZooEntity zoo =
|
ZooEntity zoo =
|
||||||
zooRepository
|
zooRepository
|
||||||
.getZooByUid(id)
|
.getZooByUid(id)
|
||||||
.orElseThrow(
|
.orElseThrow(() -> new EntityNotFoundException("Zoo not found with id: " + id));
|
||||||
() -> new EntityNotFoundException("Zoo not found with id: " + id));
|
return toDetailDto(zoo);
|
||||||
return toDetailDto(zoo);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Page<ZooDto.Detail> search(ZooDto.SearchReq searchReq) {
|
public Page<ZooDto.Detail> search(ZooDto.SearchReq searchReq) {
|
||||||
Page<ZooEntity> zooEntities = zooRepository.listZoo(searchReq);
|
Page<ZooEntity> zooEntities = zooRepository.listZoo(searchReq);
|
||||||
return zooEntities.map(this::toDetailDto);
|
return zooEntities.map(this::toDetailDto);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Entity -> Detail DTO 변환 (동물 개수 포함)
|
// Entity -> Detail DTO 변환 (동물 개수 포함)
|
||||||
private ZooDto.Detail toDetailDto(ZooEntity zoo) {
|
private ZooDto.Detail toDetailDto(ZooEntity zoo) {
|
||||||
Long activeAnimalCount = zooRepository.countActiveAnimals(zoo.getUid());
|
Long activeAnimalCount = zooRepository.countActiveAnimals(zoo.getUid());
|
||||||
return new ZooDto.Detail(
|
return new ZooDto.Detail(
|
||||||
zoo.getUid(),
|
zoo.getUid(),
|
||||||
zoo.getUuid().toString(),
|
zoo.getUuid().toString(),
|
||||||
zoo.getName(),
|
zoo.getName(),
|
||||||
zoo.getLocation(),
|
zoo.getLocation(),
|
||||||
zoo.getDescription(),
|
zoo.getDescription(),
|
||||||
zoo.getCreatedDate(),
|
zoo.getCreatedDate(),
|
||||||
zoo.getModifiedDate(),
|
zoo.getModifiedDate(),
|
||||||
activeAnimalCount);
|
activeAnimalCount);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,48 +28,48 @@ import lombok.NoArgsConstructor;
|
|||||||
@Table(name = "tb_animal")
|
@Table(name = "tb_animal")
|
||||||
public class AnimalEntity extends CommonDateEntity {
|
public class AnimalEntity extends CommonDateEntity {
|
||||||
|
|
||||||
@Id
|
@Id
|
||||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||||
private Long uid;
|
private Long uid;
|
||||||
|
|
||||||
@Column(unique = true)
|
@Column(unique = true)
|
||||||
private UUID uuid;
|
private UUID uuid;
|
||||||
|
|
||||||
@Enumerated(EnumType.STRING)
|
@Enumerated(EnumType.STRING)
|
||||||
private Category category;
|
private Category category;
|
||||||
|
|
||||||
@Enumerated(EnumType.STRING)
|
@Enumerated(EnumType.STRING)
|
||||||
private Species species;
|
private Species species;
|
||||||
|
|
||||||
private String name;
|
private String name;
|
||||||
private Boolean isDeleted;
|
private Boolean isDeleted;
|
||||||
|
|
||||||
@ManyToOne(fetch = FetchType.LAZY)
|
@ManyToOne(fetch = FetchType.LAZY)
|
||||||
@JoinColumn(name = "zoo_id")
|
@JoinColumn(name = "zoo_id")
|
||||||
private ZooEntity zoo;
|
private ZooEntity zoo;
|
||||||
|
|
||||||
// Construct
|
// Construct
|
||||||
public AnimalEntity(Category category, Species species, String name, ZooEntity zoo) {
|
public AnimalEntity(Category category, Species species, String name, ZooEntity zoo) {
|
||||||
this.uuid = UUID.randomUUID();
|
this.uuid = UUID.randomUUID();
|
||||||
this.category = category;
|
this.category = category;
|
||||||
this.species = species;
|
this.species = species;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.isDeleted = false;
|
this.isDeleted = false;
|
||||||
this.zoo = zoo;
|
this.zoo = zoo;
|
||||||
}
|
}
|
||||||
|
|
||||||
public AnimalDto.Basic toDto() {
|
public AnimalDto.Basic toDto() {
|
||||||
return new AnimalDto.Basic(
|
return new AnimalDto.Basic(
|
||||||
this.uid,
|
this.uid,
|
||||||
this.uuid.toString(),
|
this.uuid.toString(),
|
||||||
this.name,
|
this.name,
|
||||||
this.category,
|
this.category,
|
||||||
this.species,
|
this.species,
|
||||||
super.getCreatedDate(),
|
super.getCreatedDate(),
|
||||||
super.getModifiedDate());
|
super.getModifiedDate());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void deleted() {
|
public void deleted() {
|
||||||
this.isDeleted = true;
|
this.isDeleted = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,44 +23,44 @@ import lombok.NoArgsConstructor;
|
|||||||
@Table(name = "tb_zoo")
|
@Table(name = "tb_zoo")
|
||||||
public class ZooEntity extends CommonDateEntity {
|
public class ZooEntity extends CommonDateEntity {
|
||||||
|
|
||||||
@Id
|
@Id
|
||||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||||
private Long uid;
|
private Long uid;
|
||||||
|
|
||||||
@Column(unique = true, nullable = false)
|
@Column(unique = true, nullable = false)
|
||||||
private UUID uuid;
|
private UUID uuid;
|
||||||
|
|
||||||
@Column(nullable = false, length = 200)
|
@Column(nullable = false, length = 200)
|
||||||
private String name;
|
private String name;
|
||||||
|
|
||||||
@Column(length = 300)
|
@Column(length = 300)
|
||||||
private String location;
|
private String location;
|
||||||
|
|
||||||
@Column(columnDefinition = "TEXT")
|
@Column(columnDefinition = "TEXT")
|
||||||
private String description;
|
private String description;
|
||||||
|
|
||||||
@Column(nullable = false)
|
@Column(nullable = false)
|
||||||
private Boolean isDeleted;
|
private Boolean isDeleted;
|
||||||
|
|
||||||
@OneToMany(mappedBy = "zoo", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
|
@OneToMany(mappedBy = "zoo", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
|
||||||
private List<AnimalEntity> animals = new ArrayList<>();
|
private List<AnimalEntity> animals = new ArrayList<>();
|
||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
public ZooEntity(String name, String location, String description) {
|
public ZooEntity(String name, String location, String description) {
|
||||||
this.uuid = UUID.randomUUID();
|
this.uuid = UUID.randomUUID();
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.location = location;
|
this.location = location;
|
||||||
this.description = description;
|
this.description = description;
|
||||||
this.isDeleted = false;
|
this.isDeleted = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 논리 삭제
|
// 논리 삭제
|
||||||
public void deleted() {
|
public void deleted() {
|
||||||
this.isDeleted = true;
|
this.isDeleted = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 현재 활성 동물 개수 조회 (삭제되지 않은 동물만)
|
// 현재 활성 동물 개수 조회 (삭제되지 않은 동물만)
|
||||||
public long getActiveAnimalCount() {
|
public long getActiveAnimalCount() {
|
||||||
return animals.stream().filter(animal -> !animal.getIsDeleted()).count();
|
return animals.stream().filter(animal -> !animal.getIsDeleted()).count();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,4 +4,4 @@ import com.kamco.cd.kamcoback.postgres.entity.AnimalEntity;
|
|||||||
import org.springframework.data.jpa.repository.JpaRepository;
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
|
|
||||||
public interface AnimalRepository
|
public interface AnimalRepository
|
||||||
extends JpaRepository<AnimalEntity, Long>, AnimalRepositoryCustom {}
|
extends JpaRepository<AnimalEntity, Long>, AnimalRepositoryCustom {}
|
||||||
|
|||||||
@@ -7,9 +7,9 @@ import org.springframework.data.domain.Page;
|
|||||||
|
|
||||||
public interface AnimalRepositoryCustom {
|
public interface AnimalRepositoryCustom {
|
||||||
|
|
||||||
Optional<AnimalEntity> getAnimalByUid(Long uid);
|
Optional<AnimalEntity> getAnimalByUid(Long uid);
|
||||||
|
|
||||||
Optional<AnimalEntity> getAnimalByUuid(String uuid);
|
Optional<AnimalEntity> getAnimalByUuid(String uuid);
|
||||||
|
|
||||||
Page<AnimalEntity> listAnimal(AnimalDto.SearchReq req);
|
Page<AnimalEntity> listAnimal(AnimalDto.SearchReq req);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,84 +16,81 @@ import org.springframework.data.domain.Pageable;
|
|||||||
import org.springframework.data.jpa.repository.support.QuerydslRepositorySupport;
|
import org.springframework.data.jpa.repository.support.QuerydslRepositorySupport;
|
||||||
|
|
||||||
public class AnimalRepositoryImpl extends QuerydslRepositorySupport
|
public class AnimalRepositoryImpl extends QuerydslRepositorySupport
|
||||||
implements AnimalRepositoryCustom {
|
implements AnimalRepositoryCustom {
|
||||||
|
|
||||||
private final JPAQueryFactory queryFactory;
|
private final JPAQueryFactory queryFactory;
|
||||||
|
|
||||||
public AnimalRepositoryImpl(JPAQueryFactory queryFactory) {
|
public AnimalRepositoryImpl(JPAQueryFactory queryFactory) {
|
||||||
super(AnimalEntity.class);
|
super(AnimalEntity.class);
|
||||||
this.queryFactory = queryFactory;
|
this.queryFactory = queryFactory;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Optional<AnimalEntity> getAnimalByUid(Long uid) {
|
||||||
|
QAnimalEntity animal = QAnimalEntity.animalEntity;
|
||||||
|
|
||||||
|
return Optional.ofNullable(
|
||||||
|
queryFactory.selectFrom(animal).where(animal.uid.eq(uid)).fetchFirst());
|
||||||
|
}
|
||||||
|
|
||||||
|
public Optional<AnimalEntity> getAnimalByUuid(String uuid) {
|
||||||
|
QAnimalEntity animal = QAnimalEntity.animalEntity;
|
||||||
|
|
||||||
|
return Optional.ofNullable(
|
||||||
|
queryFactory.selectFrom(animal).where(animal.uuid.eq(UUID.fromString(uuid))).fetchFirst());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Page<AnimalEntity> listAnimal(AnimalDto.SearchReq req) {
|
||||||
|
QAnimalEntity animal = QAnimalEntity.animalEntity;
|
||||||
|
|
||||||
|
Pageable pageable = req.toPageable();
|
||||||
|
|
||||||
|
List<AnimalEntity> content =
|
||||||
|
queryFactory
|
||||||
|
.selectFrom(animal)
|
||||||
|
.where(
|
||||||
|
animal.isDeleted.eq(false),
|
||||||
|
eqCategory(animal, req.getCategory()),
|
||||||
|
eqSpecies(animal, req.getSpecies()),
|
||||||
|
likeName(animal, req.getName()))
|
||||||
|
.offset(pageable.getOffset())
|
||||||
|
.limit(pageable.getPageSize())
|
||||||
|
.orderBy(animal.createdDate.desc())
|
||||||
|
.fetch();
|
||||||
|
|
||||||
|
// count 쿼리
|
||||||
|
Long total =
|
||||||
|
queryFactory
|
||||||
|
.select(animal.count())
|
||||||
|
.from(animal)
|
||||||
|
.where(
|
||||||
|
animal.isDeleted.eq(false),
|
||||||
|
eqCategory(animal, req.getCategory()),
|
||||||
|
eqSpecies(animal, req.getSpecies()),
|
||||||
|
likeName(animal, req.getName()))
|
||||||
|
.fetchOne();
|
||||||
|
|
||||||
|
return new PageImpl<>(content, pageable, total);
|
||||||
|
}
|
||||||
|
|
||||||
|
private BooleanExpression likeName(QAnimalEntity animal, String nameStr) {
|
||||||
|
if (nameStr == null || nameStr.isEmpty()) {
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
return animal.name.containsIgnoreCase(nameStr.trim());
|
||||||
|
}
|
||||||
|
|
||||||
public Optional<AnimalEntity> getAnimalByUid(Long uid) {
|
private BooleanExpression eqCategory(QAnimalEntity animal, Category category) {
|
||||||
QAnimalEntity animal = QAnimalEntity.animalEntity;
|
if (category == null) {
|
||||||
|
return null;
|
||||||
return Optional.ofNullable(
|
|
||||||
queryFactory.selectFrom(animal).where(animal.uid.eq(uid)).fetchFirst());
|
|
||||||
}
|
}
|
||||||
|
return animal.category.eq(category);
|
||||||
|
}
|
||||||
|
|
||||||
public Optional<AnimalEntity> getAnimalByUuid(String uuid) {
|
private BooleanExpression eqSpecies(QAnimalEntity animal, Species species) {
|
||||||
QAnimalEntity animal = QAnimalEntity.animalEntity;
|
if (species == null) {
|
||||||
|
return null;
|
||||||
return Optional.ofNullable(
|
|
||||||
queryFactory
|
|
||||||
.selectFrom(animal)
|
|
||||||
.where(animal.uuid.eq(UUID.fromString(uuid)))
|
|
||||||
.fetchFirst());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Page<AnimalEntity> listAnimal(AnimalDto.SearchReq req) {
|
|
||||||
QAnimalEntity animal = QAnimalEntity.animalEntity;
|
|
||||||
|
|
||||||
Pageable pageable = req.toPageable();
|
|
||||||
|
|
||||||
List<AnimalEntity> content =
|
|
||||||
queryFactory
|
|
||||||
.selectFrom(animal)
|
|
||||||
.where(
|
|
||||||
animal.isDeleted.eq(false),
|
|
||||||
eqCategory(animal, req.getCategory()),
|
|
||||||
eqSpecies(animal, req.getSpecies()),
|
|
||||||
likeName(animal, req.getName()))
|
|
||||||
.offset(pageable.getOffset())
|
|
||||||
.limit(pageable.getPageSize())
|
|
||||||
.orderBy(animal.createdDate.desc())
|
|
||||||
.fetch();
|
|
||||||
|
|
||||||
// count 쿼리
|
|
||||||
Long total =
|
|
||||||
queryFactory
|
|
||||||
.select(animal.count())
|
|
||||||
.from(animal)
|
|
||||||
.where(
|
|
||||||
animal.isDeleted.eq(false),
|
|
||||||
eqCategory(animal, req.getCategory()),
|
|
||||||
eqSpecies(animal, req.getSpecies()),
|
|
||||||
likeName(animal, req.getName()))
|
|
||||||
.fetchOne();
|
|
||||||
|
|
||||||
return new PageImpl<>(content, pageable, total);
|
|
||||||
}
|
|
||||||
|
|
||||||
private BooleanExpression likeName(QAnimalEntity animal, String nameStr) {
|
|
||||||
if (nameStr == null || nameStr.isEmpty()) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return animal.name.containsIgnoreCase(nameStr.trim());
|
|
||||||
}
|
|
||||||
|
|
||||||
private BooleanExpression eqCategory(QAnimalEntity animal, Category category) {
|
|
||||||
if (category == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return animal.category.eq(category);
|
|
||||||
}
|
|
||||||
|
|
||||||
private BooleanExpression eqSpecies(QAnimalEntity animal, Species species) {
|
|
||||||
if (species == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return animal.species.eq(species);
|
|
||||||
}
|
}
|
||||||
|
return animal.species.eq(species);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,11 +7,11 @@ import org.springframework.data.domain.Page;
|
|||||||
|
|
||||||
public interface ZooRepositoryCustom {
|
public interface ZooRepositoryCustom {
|
||||||
|
|
||||||
Page<ZooEntity> listZoo(ZooDto.SearchReq searchReq);
|
Page<ZooEntity> listZoo(ZooDto.SearchReq searchReq);
|
||||||
|
|
||||||
Optional<ZooEntity> getZooByUuid(String uuid);
|
Optional<ZooEntity> getZooByUuid(String uuid);
|
||||||
|
|
||||||
Optional<ZooEntity> getZooByUid(Long uid);
|
Optional<ZooEntity> getZooByUid(Long uid);
|
||||||
|
|
||||||
Long countActiveAnimals(Long zooId);
|
Long countActiveAnimals(Long zooId);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,68 +20,66 @@ import org.springframework.stereotype.Repository;
|
|||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class ZooRepositoryImpl implements ZooRepositoryCustom {
|
public class ZooRepositoryImpl implements ZooRepositoryCustom {
|
||||||
|
|
||||||
private final JPAQueryFactory queryFactory;
|
private final JPAQueryFactory queryFactory;
|
||||||
private final QZooEntity qZoo = QZooEntity.zooEntity;
|
private final QZooEntity qZoo = QZooEntity.zooEntity;
|
||||||
private final QAnimalEntity qAnimal = QAnimalEntity.animalEntity;
|
private final QAnimalEntity qAnimal = QAnimalEntity.animalEntity;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Page<ZooEntity> listZoo(ZooDto.SearchReq searchReq) {
|
public Page<ZooEntity> listZoo(ZooDto.SearchReq searchReq) {
|
||||||
Pageable pageable = searchReq.toPageable();
|
Pageable pageable = searchReq.toPageable();
|
||||||
|
|
||||||
JPAQuery<ZooEntity> query =
|
JPAQuery<ZooEntity> query =
|
||||||
queryFactory
|
queryFactory
|
||||||
.selectFrom(qZoo)
|
.selectFrom(qZoo)
|
||||||
.where(
|
.where(
|
||||||
qZoo.isDeleted.eq(false),
|
qZoo.isDeleted.eq(false),
|
||||||
nameContains(searchReq.getName()),
|
nameContains(searchReq.getName()),
|
||||||
locationContains(searchReq.getLocation()));
|
locationContains(searchReq.getLocation()));
|
||||||
|
|
||||||
long total = query.fetchCount();
|
long total = query.fetchCount();
|
||||||
|
|
||||||
List<ZooEntity> content =
|
List<ZooEntity> content =
|
||||||
query.offset(pageable.getOffset())
|
query
|
||||||
.limit(pageable.getPageSize())
|
.offset(pageable.getOffset())
|
||||||
.orderBy(qZoo.createdDate.desc())
|
.limit(pageable.getPageSize())
|
||||||
.fetch();
|
.orderBy(qZoo.createdDate.desc())
|
||||||
|
.fetch();
|
||||||
|
|
||||||
return new PageImpl<>(content, pageable, total);
|
return new PageImpl<>(content, pageable, total);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Optional<ZooEntity> getZooByUuid(String uuid) {
|
public Optional<ZooEntity> getZooByUuid(String uuid) {
|
||||||
return Optional.ofNullable(
|
return Optional.ofNullable(
|
||||||
queryFactory
|
queryFactory
|
||||||
.selectFrom(qZoo)
|
.selectFrom(qZoo)
|
||||||
.where(qZoo.uuid.eq(UUID.fromString(uuid)), qZoo.isDeleted.eq(false))
|
.where(qZoo.uuid.eq(UUID.fromString(uuid)), qZoo.isDeleted.eq(false))
|
||||||
.fetchOne());
|
.fetchOne());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Optional<ZooEntity> getZooByUid(Long uid) {
|
public Optional<ZooEntity> getZooByUid(Long uid) {
|
||||||
return Optional.ofNullable(
|
return Optional.ofNullable(
|
||||||
queryFactory
|
queryFactory.selectFrom(qZoo).where(qZoo.uid.eq(uid), qZoo.isDeleted.eq(false)).fetchOne());
|
||||||
.selectFrom(qZoo)
|
}
|
||||||
.where(qZoo.uid.eq(uid), qZoo.isDeleted.eq(false))
|
|
||||||
.fetchOne());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Long countActiveAnimals(Long zooId) {
|
public Long countActiveAnimals(Long zooId) {
|
||||||
Long count =
|
Long count =
|
||||||
queryFactory
|
queryFactory
|
||||||
.select(qAnimal.count())
|
.select(qAnimal.count())
|
||||||
.from(qAnimal)
|
.from(qAnimal)
|
||||||
.where(qAnimal.zoo.uid.eq(zooId), qAnimal.isDeleted.eq(false))
|
.where(qAnimal.zoo.uid.eq(zooId), qAnimal.isDeleted.eq(false))
|
||||||
.fetchOne();
|
.fetchOne();
|
||||||
|
|
||||||
return count != null ? count : 0L;
|
return count != null ? count : 0L;
|
||||||
}
|
}
|
||||||
|
|
||||||
private BooleanExpression nameContains(String name) {
|
private BooleanExpression nameContains(String name) {
|
||||||
return name != null && !name.isEmpty() ? qZoo.name.contains(name) : null;
|
return name != null && !name.isEmpty() ? qZoo.name.contains(name) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private BooleanExpression locationContains(String location) {
|
private BooleanExpression locationContains(String location) {
|
||||||
return location != null && !location.isEmpty() ? qZoo.location.contains(location) : null;
|
return location != null && !location.isEmpty() ? qZoo.location.contains(location) : null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,68 +15,68 @@ import org.springframework.web.bind.annotation.*;
|
|||||||
@RequestMapping({"/api/animals", "/v1/api/animals"})
|
@RequestMapping({"/api/animals", "/v1/api/animals"})
|
||||||
public class AnimalApiController {
|
public class AnimalApiController {
|
||||||
|
|
||||||
private final AnimalService animalService;
|
private final AnimalService animalService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 동물 생성
|
* 동물 생성
|
||||||
*
|
*
|
||||||
* @param req 동물 생성 요청
|
* @param req 동물 생성 요청
|
||||||
* @return 생성된 동물 정보
|
* @return 생성된 동물 정보
|
||||||
*/
|
*/
|
||||||
@PostMapping
|
@PostMapping
|
||||||
public ResponseEntity<AnimalDto.Basic> createAnimal(@RequestBody AnimalDto.AddReq req) {
|
public ResponseEntity<AnimalDto.Basic> createAnimal(@RequestBody AnimalDto.AddReq req) {
|
||||||
AnimalDto.Basic created = animalService.createAnimal(req);
|
AnimalDto.Basic created = animalService.createAnimal(req);
|
||||||
return ResponseEntity.status(HttpStatus.CREATED).body(created);
|
return ResponseEntity.status(HttpStatus.CREATED).body(created);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* UUID로 동물 조회
|
* UUID로 동물 조회
|
||||||
*
|
*
|
||||||
* @param uuid 동물 UUID
|
* @param uuid 동물 UUID
|
||||||
* @return 동물 정보
|
* @return 동물 정보
|
||||||
*/
|
*/
|
||||||
@GetMapping("/{uuid}")
|
@GetMapping("/{uuid}")
|
||||||
public ResponseEntity<AnimalDto.Basic> getAnimal(@PathVariable String uuid) {
|
public ResponseEntity<AnimalDto.Basic> getAnimal(@PathVariable String uuid) {
|
||||||
Long id = animalService.getAnimalByUuid(uuid);
|
Long id = animalService.getAnimalByUuid(uuid);
|
||||||
AnimalDto.Basic animal = animalService.getAnimal(id);
|
AnimalDto.Basic animal = animalService.getAnimal(id);
|
||||||
return ResponseEntity.ok(animal);
|
return ResponseEntity.ok(animal);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* UUID로 동물 삭제 (논리 삭제)
|
* UUID로 동물 삭제 (논리 삭제)
|
||||||
*
|
*
|
||||||
* @param uuid 동물 UUID
|
* @param uuid 동물 UUID
|
||||||
* @return 삭제 성공 메시지
|
* @return 삭제 성공 메시지
|
||||||
*/
|
*/
|
||||||
@DeleteMapping("/{uuid}")
|
@DeleteMapping("/{uuid}")
|
||||||
public ResponseEntity<Void> deleteAnimal(@PathVariable String uuid) {
|
public ResponseEntity<Void> deleteAnimal(@PathVariable String uuid) {
|
||||||
Long id = animalService.getAnimalByUuid(uuid);
|
Long id = animalService.getAnimalByUuid(uuid);
|
||||||
animalService.deleteZoo(id);
|
animalService.deleteZoo(id);
|
||||||
return ResponseEntity.noContent().build();
|
return ResponseEntity.noContent().build();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 동물 검색 (페이징)
|
* 동물 검색 (페이징)
|
||||||
*
|
*
|
||||||
* @param name 동물 이름 (선택)
|
* @param name 동물 이름 (선택)
|
||||||
* @param category 서식지 타입 (선택)
|
* @param category 서식지 타입 (선택)
|
||||||
* @param species 동물종 (선택) 개, 고양이등.
|
* @param species 동물종 (선택) 개, 고양이등.
|
||||||
* @param page 페이지 번호 (기본값: 0)
|
* @param page 페이지 번호 (기본값: 0)
|
||||||
* @param size 페이지 크기 (기본값: 20)
|
* @param size 페이지 크기 (기본값: 20)
|
||||||
* @param sort 정렬 조건 (예: "name,asc")
|
* @param sort 정렬 조건 (예: "name,asc")
|
||||||
* @return 페이징 처리된 동물 목록
|
* @return 페이징 처리된 동물 목록
|
||||||
*/
|
*/
|
||||||
@GetMapping
|
@GetMapping
|
||||||
public ResponseEntity<Page<AnimalDto.Basic>> searchAnimals(
|
public ResponseEntity<Page<AnimalDto.Basic>> searchAnimals(
|
||||||
@RequestParam(required = false) String name,
|
@RequestParam(required = false) String name,
|
||||||
@RequestParam(required = false) Category category,
|
@RequestParam(required = false) Category category,
|
||||||
@RequestParam(required = false) Species species,
|
@RequestParam(required = false) Species species,
|
||||||
@RequestParam(defaultValue = "0") int page,
|
@RequestParam(defaultValue = "0") int page,
|
||||||
@RequestParam(defaultValue = "20") int size,
|
@RequestParam(defaultValue = "20") int size,
|
||||||
@RequestParam(required = false) String sort) {
|
@RequestParam(required = false) String sort) {
|
||||||
AnimalDto.SearchReq searchReq =
|
AnimalDto.SearchReq searchReq =
|
||||||
new AnimalDto.SearchReq(name, category, species, page, size, sort);
|
new AnimalDto.SearchReq(name, category, species, page, size, sort);
|
||||||
Page<AnimalDto.Basic> animals = animalService.search(searchReq);
|
Page<AnimalDto.Basic> animals = animalService.search(searchReq);
|
||||||
return ResponseEntity.ok(animals);
|
return ResponseEntity.ok(animals);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -56,20 +56,20 @@ public class ZooApiController {
|
|||||||
/**
|
/**
|
||||||
* 동물원 검색 (페이징)
|
* 동물원 검색 (페이징)
|
||||||
*
|
*
|
||||||
* @param name 동물원 이름 (선택)
|
* @param name 동물원 이름 (선택)
|
||||||
* @param location 위치 (선택)
|
* @param location 위치 (선택)
|
||||||
* @param page 페이지 번호 (기본값: 0)
|
* @param page 페이지 번호 (기본값: 0)
|
||||||
* @param size 페이지 크기 (기본값: 20)
|
* @param size 페이지 크기 (기본값: 20)
|
||||||
* @param sort 정렬 조건 (예: "name,asc")
|
* @param sort 정렬 조건 (예: "name,asc")
|
||||||
* @return 페이징 처리된 동물원 목록 (각 동물원의 현재 동물 개수 포함)
|
* @return 페이징 처리된 동물원 목록 (각 동물원의 현재 동물 개수 포함)
|
||||||
*/
|
*/
|
||||||
@GetMapping
|
@GetMapping
|
||||||
public ResponseEntity<Page<ZooDto.Detail>> searchZoos(
|
public ResponseEntity<Page<ZooDto.Detail>> searchZoos(
|
||||||
@RequestParam(required = false) String name,
|
@RequestParam(required = false) String name,
|
||||||
@RequestParam(required = false) String location,
|
@RequestParam(required = false) String location,
|
||||||
@RequestParam(defaultValue = "0") int page,
|
@RequestParam(defaultValue = "0") int page,
|
||||||
@RequestParam(defaultValue = "20") int size,
|
@RequestParam(defaultValue = "20") int size,
|
||||||
@RequestParam(required = false) String sort) {
|
@RequestParam(required = false) String sort) {
|
||||||
ZooDto.SearchReq searchReq = new ZooDto.SearchReq(name, location, page, size, sort);
|
ZooDto.SearchReq searchReq = new ZooDto.SearchReq(name, location, page, size, sort);
|
||||||
Page<ZooDto.Detail> zoos = zooService.search(searchReq);
|
Page<ZooDto.Detail> zoos = zooService.search(searchReq);
|
||||||
return ResponseEntity.ok(zoos);
|
return ResponseEntity.ok(zoos);
|
||||||
|
|||||||
@@ -29,33 +29,32 @@ public class AnimalDto {
|
|||||||
@Getter
|
@Getter
|
||||||
public static class Basic {
|
public static class Basic {
|
||||||
|
|
||||||
@JsonIgnore
|
@JsonIgnore private Long id;
|
||||||
private Long id;
|
|
||||||
private String uuid;
|
private String uuid;
|
||||||
private Category category;
|
private Category category;
|
||||||
private Species species;
|
private Species species;
|
||||||
private String name;
|
private String name;
|
||||||
|
|
||||||
@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")
|
||||||
private ZonedDateTime createdDate;
|
private ZonedDateTime createdDate;
|
||||||
|
|
||||||
@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")
|
||||||
private ZonedDateTime modifiedDate;
|
private ZonedDateTime modifiedDate;
|
||||||
|
|
||||||
public Basic(
|
public Basic(
|
||||||
Long id,
|
Long id,
|
||||||
String uuid,
|
String uuid,
|
||||||
String name,
|
String name,
|
||||||
Category category,
|
Category category,
|
||||||
Species species,
|
Species species,
|
||||||
ZonedDateTime createdDate,
|
ZonedDateTime createdDate,
|
||||||
ZonedDateTime modifiedDate) {
|
ZonedDateTime modifiedDate) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.uuid = uuid;
|
this.uuid = uuid;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
@@ -70,16 +69,16 @@ public class AnimalDto {
|
|||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
public enum Category implements EnumType {
|
public enum Category implements EnumType {
|
||||||
// @formatter:off
|
// @formatter:off
|
||||||
MAMMALS("100", "포유류"), // 땅에 사는 동물
|
MAMMALS("100", "포유류"), // 땅에 사는 동물
|
||||||
BIRDS("200", "조류"), // 하늘을 나는 동물
|
BIRDS("200", "조류"), // 하늘을 나는 동물
|
||||||
FISH("300", "어류"),
|
FISH("300", "어류"),
|
||||||
AMPHIBIANS("400", "양서류"),
|
AMPHIBIANS("400", "양서류"),
|
||||||
REPTILES("500", "파충류"),
|
REPTILES("500", "파충류"),
|
||||||
INSECTS("500", "곤충"),
|
INSECTS("500", "곤충"),
|
||||||
INVERTEBRATES("500", "무척추동물"),
|
INVERTEBRATES("500", "무척추동물"),
|
||||||
;
|
;
|
||||||
// @formatter:on
|
// @formatter:on
|
||||||
private final String id;
|
private final String id;
|
||||||
private final String text;
|
private final String text;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -87,15 +86,15 @@ public class AnimalDto {
|
|||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
public enum Species implements EnumType {
|
public enum Species implements EnumType {
|
||||||
// @formatter:off
|
// @formatter:off
|
||||||
DOG("101", "개"),
|
DOG("101", "개"),
|
||||||
CAT("102", "강아지"),
|
CAT("102", "강아지"),
|
||||||
DOVE("201", "비둘기"),
|
DOVE("201", "비둘기"),
|
||||||
EAGLE("202", "독수리"),
|
EAGLE("202", "독수리"),
|
||||||
SALMON("301", "연어"),
|
SALMON("301", "연어"),
|
||||||
TUNA("302", "참치"),
|
TUNA("302", "참치"),
|
||||||
;
|
;
|
||||||
// @formatter:on
|
// @formatter:on
|
||||||
private final String id;
|
private final String id;
|
||||||
private final String text;
|
private final String text;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -120,9 +119,7 @@ public class AnimalDto {
|
|||||||
String[] sortParams = sort.split(",");
|
String[] sortParams = sort.split(",");
|
||||||
String property = sortParams[0];
|
String property = sortParams[0];
|
||||||
Sort.Direction direction =
|
Sort.Direction direction =
|
||||||
sortParams.length > 1
|
sortParams.length > 1 ? Sort.Direction.fromString(sortParams[1]) : Sort.Direction.ASC;
|
||||||
? Sort.Direction.fromString(sortParams[1])
|
|
||||||
: Sort.Direction.ASC;
|
|
||||||
return PageRequest.of(page, size, Sort.by(direction, property));
|
return PageRequest.of(page, size, Sort.by(direction, property));
|
||||||
}
|
}
|
||||||
return PageRequest.of(page, size);
|
return PageRequest.of(page, size);
|
||||||
|
|||||||
@@ -27,33 +27,32 @@ public class ZooDto {
|
|||||||
@Getter
|
@Getter
|
||||||
public static class Basic {
|
public static class Basic {
|
||||||
|
|
||||||
@JsonIgnore
|
@JsonIgnore private Long id;
|
||||||
private Long id;
|
|
||||||
private String uuid;
|
private String uuid;
|
||||||
private String name;
|
private String name;
|
||||||
private String location;
|
private String location;
|
||||||
private String description;
|
private String description;
|
||||||
|
|
||||||
@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")
|
||||||
private ZonedDateTime createdDate;
|
private ZonedDateTime createdDate;
|
||||||
|
|
||||||
@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")
|
||||||
private ZonedDateTime modifiedDate;
|
private ZonedDateTime modifiedDate;
|
||||||
|
|
||||||
public Basic(
|
public Basic(
|
||||||
Long id,
|
Long id,
|
||||||
String uuid,
|
String uuid,
|
||||||
String name,
|
String name,
|
||||||
String location,
|
String location,
|
||||||
String description,
|
String description,
|
||||||
ZonedDateTime createdDate,
|
ZonedDateTime createdDate,
|
||||||
ZonedDateTime modifiedDate) {
|
ZonedDateTime modifiedDate) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.uuid = uuid;
|
this.uuid = uuid;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
@@ -70,14 +69,14 @@ public class ZooDto {
|
|||||||
private Long activeAnimalCount;
|
private Long activeAnimalCount;
|
||||||
|
|
||||||
public Detail(
|
public Detail(
|
||||||
Long id,
|
Long id,
|
||||||
String uuid,
|
String uuid,
|
||||||
String name,
|
String name,
|
||||||
String location,
|
String location,
|
||||||
String description,
|
String description,
|
||||||
ZonedDateTime createdDate,
|
ZonedDateTime createdDate,
|
||||||
ZonedDateTime modifiedDate,
|
ZonedDateTime modifiedDate,
|
||||||
Long activeAnimalCount) {
|
Long activeAnimalCount) {
|
||||||
super(id, uuid, name, location, description, createdDate, modifiedDate);
|
super(id, uuid, name, location, description, createdDate, modifiedDate);
|
||||||
this.activeAnimalCount = activeAnimalCount;
|
this.activeAnimalCount = activeAnimalCount;
|
||||||
}
|
}
|
||||||
@@ -103,9 +102,7 @@ public class ZooDto {
|
|||||||
String[] sortParams = sort.split(",");
|
String[] sortParams = sort.split(",");
|
||||||
String property = sortParams[0];
|
String property = sortParams[0];
|
||||||
Sort.Direction direction =
|
Sort.Direction direction =
|
||||||
sortParams.length > 1
|
sortParams.length > 1 ? Sort.Direction.fromString(sortParams[1]) : Sort.Direction.ASC;
|
||||||
? Sort.Direction.fromString(sortParams[1])
|
|
||||||
: Sort.Direction.ASC;
|
|
||||||
return PageRequest.of(page, size, Sort.by(direction, property));
|
return PageRequest.of(page, size, Sort.by(direction, property));
|
||||||
}
|
}
|
||||||
return PageRequest.of(page, size);
|
return PageRequest.of(page, size);
|
||||||
|
|||||||
@@ -11,51 +11,52 @@ import org.springframework.transaction.annotation.Transactional;
|
|||||||
@Service
|
@Service
|
||||||
@Transactional(readOnly = true)
|
@Transactional(readOnly = true)
|
||||||
public class ZooService {
|
public class ZooService {
|
||||||
private final ZooCoreService zooCoreService;
|
|
||||||
|
|
||||||
// 동물원의 UUID로 id조회
|
private final ZooCoreService zooCoreService;
|
||||||
public Long getZooByUuid(String uuid) {
|
|
||||||
return zooCoreService.getDataByUuid(uuid).getId();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
// 동물원의 UUID로 id조회
|
||||||
* 동물원 생성
|
public Long getZooByUuid(String uuid) {
|
||||||
*
|
return zooCoreService.getDataByUuid(uuid).getId();
|
||||||
* @param req 동물원 생성 요청
|
}
|
||||||
* @return 생성된 동물원 정보 (동물 개수 포함)
|
|
||||||
*/
|
|
||||||
@Transactional
|
|
||||||
public ZooDto.Detail createZoo(ZooDto.AddReq req) {
|
|
||||||
return zooCoreService.create(req);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 동물원 삭제 (논리 삭제)
|
* 동물원 생성
|
||||||
*
|
*
|
||||||
* @param id 동물원 ID
|
* @param req 동물원 생성 요청
|
||||||
*/
|
* @return 생성된 동물원 정보 (동물 개수 포함)
|
||||||
@Transactional
|
*/
|
||||||
public void deleteZoo(Long id) {
|
@Transactional
|
||||||
zooCoreService.remove(id);
|
public ZooDto.Detail createZoo(ZooDto.AddReq req) {
|
||||||
}
|
return zooCoreService.create(req);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 동물원 단건 조회
|
* 동물원 삭제 (논리 삭제)
|
||||||
*
|
*
|
||||||
* @param id 동물원 ID
|
* @param id 동물원 ID
|
||||||
* @return 동물원 정보 (동물 개수 포함)
|
*/
|
||||||
*/
|
@Transactional
|
||||||
public ZooDto.Detail getZoo(Long id) {
|
public void deleteZoo(Long id) {
|
||||||
return zooCoreService.getOneById(id);
|
zooCoreService.remove(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 동물원 검색 (페이징)
|
* 동물원 단건 조회
|
||||||
*
|
*
|
||||||
* @param searchReq 검색 조건
|
* @param id 동물원 ID
|
||||||
* @return 페이징 처리된 동물원 목록 (각 동물원의 동물 개수 포함)
|
* @return 동물원 정보 (동물 개수 포함)
|
||||||
*/
|
*/
|
||||||
public Page<ZooDto.Detail> search(ZooDto.SearchReq searchReq) {
|
public ZooDto.Detail getZoo(Long id) {
|
||||||
return zooCoreService.search(searchReq);
|
return zooCoreService.getOneById(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 동물원 검색 (페이징)
|
||||||
|
*
|
||||||
|
* @param searchReq 검색 조건
|
||||||
|
* @return 페이징 처리된 동물원 목록 (각 동물원의 동물 개수 포함)
|
||||||
|
*/
|
||||||
|
public Page<ZooDto.Detail> search(ZooDto.SearchReq searchReq) {
|
||||||
|
return zooCoreService.search(searchReq);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,6 @@ import org.springframework.boot.test.context.SpringBootTest;
|
|||||||
@SpringBootTest
|
@SpringBootTest
|
||||||
class KamcoBackApplicationTests {
|
class KamcoBackApplicationTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void contextLoads() {}
|
void contextLoads() {}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user