-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
12 changed files
with
413 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
74 changes: 74 additions & 0 deletions
74
src/main/java/com/testcar/car/domains/car/CarController.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
package com.testcar.car.domains.car; | ||
|
||
|
||
import com.testcar.car.common.annotation.RoleAllowed; | ||
import com.testcar.car.common.response.PageResponse; | ||
import com.testcar.car.domains.car.model.CarResponse; | ||
import com.testcar.car.domains.car.model.RegisterCarRequest; | ||
import com.testcar.car.domains.car.model.vo.CarFilterCondition; | ||
import com.testcar.car.domains.member.Role; | ||
import io.swagger.v3.oas.annotations.Operation; | ||
import jakarta.validation.Valid; | ||
import lombok.RequiredArgsConstructor; | ||
import org.springdoc.core.annotations.ParameterObject; | ||
import org.springframework.data.domain.Page; | ||
import org.springframework.data.domain.Pageable; | ||
import org.springframework.web.bind.annotation.DeleteMapping; | ||
import org.springframework.web.bind.annotation.GetMapping; | ||
import org.springframework.web.bind.annotation.ModelAttribute; | ||
import org.springframework.web.bind.annotation.PatchMapping; | ||
import org.springframework.web.bind.annotation.PathVariable; | ||
import org.springframework.web.bind.annotation.PostMapping; | ||
import org.springframework.web.bind.annotation.RequestBody; | ||
import org.springframework.web.bind.annotation.RequestMapping; | ||
import org.springframework.web.bind.annotation.RestController; | ||
|
||
@RestController | ||
@RequestMapping("/cars") | ||
@RequiredArgsConstructor | ||
public class CarController { | ||
private final CarService carService; | ||
|
||
@GetMapping | ||
@RoleAllowed(role = Role.USER) | ||
@Operation(summary = "[차량 관리] 차량 조회 필터", description = "조건에 맞는 모든 차량을 페이지네이션으로 조회합니다.") | ||
public PageResponse<CarResponse> getMembersByCondition( | ||
@ParameterObject @ModelAttribute CarFilterCondition condition, | ||
@ParameterObject Pageable pageable) { | ||
final Page<Car> cars = carService.findAllPageByCondition(condition, pageable); | ||
return PageResponse.from(cars.map(CarResponse::from)); | ||
} | ||
|
||
@GetMapping("/{carId}") | ||
@RoleAllowed(role = Role.USER) | ||
@Operation(summary = "[차량 관리] 사용자 상세 정보", description = "차량 상세 정보를 가져옵니다.") | ||
public CarResponse getMemberById(@PathVariable Long carId) { | ||
final Car car = carService.findById(carId); | ||
return CarResponse.from(car); | ||
} | ||
|
||
@PostMapping("/register") | ||
@RoleAllowed(role = Role.ADMIN) | ||
@Operation(summary = "[차량 관리] 차량 등록", description = "(관리자) 새로운 차량을 등록합니다.") | ||
public CarResponse register(@Valid @RequestBody RegisterCarRequest request) { | ||
final Car car = carService.register(request); | ||
return CarResponse.from(car); | ||
} | ||
|
||
@PatchMapping("/{carId}") | ||
@RoleAllowed(role = Role.ADMIN) | ||
@Operation(summary = "[차량 관리] 차량 정보 수정", description = "(관리자) 차량 정보를 수정합니다.") | ||
public CarResponse update( | ||
@PathVariable Long carId, @Valid @RequestBody RegisterCarRequest request) { | ||
final Car car = carService.updateById(carId, request); | ||
return CarResponse.from(car); | ||
} | ||
|
||
@DeleteMapping("/{carId}") | ||
@RoleAllowed(role = Role.ADMIN) | ||
@Operation(summary = "[차량 관리] 차량 삭제", description = "(관리자) 차량을 삭제합니다.") | ||
public CarResponse withdraw(@PathVariable Long carId) { | ||
final Car car = carService.deleteById(carId); | ||
return CarResponse.from(car); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
package com.testcar.car.domains.car; | ||
|
||
|
||
import com.testcar.car.common.exception.BadRequestException; | ||
import com.testcar.car.common.exception.NotFoundException; | ||
import com.testcar.car.domains.car.exception.ErrorCode; | ||
import com.testcar.car.domains.car.model.RegisterCarRequest; | ||
import com.testcar.car.domains.car.model.vo.CarFilterCondition; | ||
import com.testcar.car.domains.car.repository.CarRepository; | ||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.data.domain.Page; | ||
import org.springframework.data.domain.Pageable; | ||
import org.springframework.stereotype.Service; | ||
import org.springframework.transaction.annotation.Transactional; | ||
|
||
@Service | ||
@Transactional | ||
@RequiredArgsConstructor | ||
public class CarService { | ||
private final CarRepository carRepository; | ||
|
||
/** 차량을 id로 조회합니다. */ | ||
public Car findById(Long id) { | ||
return carRepository | ||
.findByIdAndDeletedFalse(id) | ||
.orElseThrow(() -> new NotFoundException(ErrorCode.CAR_NOT_FOUND)); | ||
} | ||
|
||
/** 차량을 조건에 맞게 조회합니다. */ | ||
public Page<Car> findAllPageByCondition(CarFilterCondition condition, Pageable pageable) { | ||
return carRepository.findAllPageByCondition(condition, pageable); | ||
} | ||
|
||
/** 새로운 차량을 등록합니다. */ | ||
public Car register(RegisterCarRequest request) { | ||
final Car car = createEntity(request); | ||
return carRepository.save(car); | ||
} | ||
|
||
/** 차량 정보를 업데이트 합니다. */ | ||
public Car updateById(Long carId, RegisterCarRequest request) { | ||
final Car car = this.findById(carId); | ||
final Car updateMember = createEntity(request); | ||
car.update(updateMember); | ||
return carRepository.save(car); | ||
} | ||
|
||
/** 차량을 삭제 처리 합니다. (soft delete) */ | ||
public Car deleteById(Long carId) { | ||
final Car car = this.findById(carId); | ||
car.delete(); | ||
return carRepository.save(car); | ||
} | ||
|
||
/** 영속되지 않은 차량 엔티티를 생성합니다. */ | ||
private Car createEntity(RegisterCarRequest request) { | ||
validateNameNotDuplicated(request.getName()); | ||
return Car.builder() | ||
.name(request.getName()) | ||
.type(request.getType()) | ||
.displacement(request.getDisplacement()) | ||
.build(); | ||
} | ||
|
||
/** 차량명 중복을 검사합니다. */ | ||
private void validateNameNotDuplicated(String name) { | ||
if (carRepository.existsByNameAndDeletedFalse(name)) { | ||
throw new BadRequestException(ErrorCode.DUPLICATED_CAR_NAME); | ||
} | ||
} | ||
} |
16 changes: 16 additions & 0 deletions
16
src/main/java/com/testcar/car/domains/car/exception/ErrorCode.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
package com.testcar.car.domains.car.exception; | ||
|
||
|
||
import com.testcar.car.common.exception.BaseErrorCode; | ||
import lombok.Getter; | ||
import lombok.RequiredArgsConstructor; | ||
|
||
@Getter | ||
@RequiredArgsConstructor | ||
public enum ErrorCode implements BaseErrorCode { | ||
CAR_NOT_FOUND("CAR001", "해당 차량을 찾을 수 없습니다."), | ||
DUPLICATED_CAR_NAME("CAR002", "중복된 차량명입니다."), | ||
; | ||
private final String code; | ||
private final String message; | ||
} |
40 changes: 40 additions & 0 deletions
40
src/main/java/com/testcar/car/domains/car/model/CarResponse.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
package com.testcar.car.domains.car.model; | ||
|
||
|
||
import com.testcar.car.common.annotation.DateTimeFormat; | ||
import com.testcar.car.domains.car.Car; | ||
import com.testcar.car.domains.car.Type; | ||
import io.swagger.v3.oas.annotations.media.Schema; | ||
import java.time.LocalDateTime; | ||
import lombok.Builder; | ||
import lombok.Getter; | ||
|
||
@Getter | ||
@Builder | ||
public class CarResponse { | ||
@Schema(description = "차량 ID", example = "1") | ||
private Long id; | ||
|
||
@Schema(description = "차량명", example = "아반떼") | ||
private String name; | ||
|
||
@Schema(description = "차종", example = "SEDAN", implementation = Type.class) | ||
private Type type; | ||
|
||
@Schema(description = "배기량", example = "1.6") | ||
private Double displacement; | ||
|
||
@DateTimeFormat | ||
@Schema(description = "등록일시", example = "2021-01-01 12:33:22") | ||
private LocalDateTime createdAt; | ||
|
||
public static CarResponse from(Car car) { | ||
return CarResponse.builder() | ||
.id(car.getId()) | ||
.name(car.getName()) | ||
.type(car.getType()) | ||
.displacement(car.getDisplacement()) | ||
.createdAt(car.getCreatedAt()) | ||
.build(); | ||
} | ||
} |
27 changes: 27 additions & 0 deletions
27
src/main/java/com/testcar/car/domains/car/model/RegisterCarRequest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
package com.testcar.car.domains.car.model; | ||
|
||
|
||
import com.testcar.car.domains.car.Type; | ||
import io.swagger.v3.oas.annotations.media.Schema; | ||
import jakarta.validation.constraints.NotBlank; | ||
import jakarta.validation.constraints.NotNull; | ||
import jakarta.validation.constraints.Positive; | ||
import lombok.Getter; | ||
import org.hibernate.validator.constraints.Length; | ||
|
||
@Getter | ||
public class RegisterCarRequest { | ||
@NotBlank | ||
@Length(max = 20) | ||
@Schema(description = "차량명", example = "아반떼") | ||
private String name; | ||
|
||
@NotNull | ||
@Schema(description = "차종", example = "SEDAN", implementation = Type.class) | ||
private Type type; | ||
|
||
@NotNull | ||
@Positive | ||
@Schema(description = "배기량", example = "1.6") | ||
private Double displacement; | ||
} |
27 changes: 27 additions & 0 deletions
27
src/main/java/com/testcar/car/domains/car/model/vo/CarFilterCondition.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
package com.testcar.car.domains.car.model.vo; | ||
|
||
|
||
import com.testcar.car.common.annotation.DateTimeFormat; | ||
import com.testcar.car.domains.car.Type; | ||
import io.swagger.v3.oas.annotations.media.Schema; | ||
import java.time.LocalDateTime; | ||
import lombok.Getter; | ||
import lombok.Setter; | ||
|
||
@Getter | ||
@Setter | ||
public class CarFilterCondition { | ||
@Schema(description = "차량명", example = "null") | ||
private String name; | ||
|
||
@Schema(description = "차종", example = "null", implementation = Type.class) | ||
private Type type; | ||
|
||
@DateTimeFormat | ||
@Schema(description = "등록일자 시작일", example = "null") | ||
private LocalDateTime startDate; | ||
|
||
@DateTimeFormat | ||
@Schema(description = "등록일자 종료일", example = "null") | ||
private LocalDateTime endDate; | ||
} |
14 changes: 14 additions & 0 deletions
14
src/main/java/com/testcar/car/domains/car/repository/CarCustomRepository.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
package com.testcar.car.domains.car.repository; | ||
|
||
|
||
import com.testcar.car.domains.car.Car; | ||
import com.testcar.car.domains.car.model.vo.CarFilterCondition; | ||
import java.util.Optional; | ||
import org.springframework.data.domain.Page; | ||
import org.springframework.data.domain.Pageable; | ||
|
||
public interface CarCustomRepository { | ||
Optional<Car> findById(Long id); | ||
|
||
Page<Car> findAllPageByCondition(CarFilterCondition condition, Pageable pageable); | ||
} |
Oops, something went wrong.