Skip to content

Commit

Permalink
Merge pull request #417 from softeerbootcamp-2nd/dev
Browse files Browse the repository at this point in the history
MAIN MERGE
  • Loading branch information
tank3a authored Aug 23, 2023
2 parents aa8233e + f8ef000 commit 7f05470
Show file tree
Hide file tree
Showing 48 changed files with 997 additions and 1,105 deletions.
2 changes: 2 additions & 0 deletions backend/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ dependencies {
testImplementation group: 'com.h2database', name: 'h2', version: '2.2.220'
implementation 'org.springdoc:springdoc-openapi-ui:1.6.9'
implementation group: 'com.googlecode.json-simple', name: 'json-simple', version: '1.1.1'
implementation 'org.springframework.boot:spring-boot-starter-data-redis'
implementation 'org.springframework.boot:spring-boot-starter-cache'

}

Expand Down
2 changes: 2 additions & 0 deletions backend/src/main/java/autoever2/cartag/CartagApplication.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;

@SpringBootApplication
@EnableCaching
public class CartagApplication {
public static void main(String[] args) {
SpringApplication.run(CartagApplication.class, args);
Expand Down
52 changes: 52 additions & 0 deletions backend/src/main/java/autoever2/cartag/RedisConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package autoever2.cartag;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;

import java.time.Duration;

@EnableCaching
@Configuration
@PropertySource("classpath:application.yml")
public class RedisConfig {

@Value("${spring.redis.host}") // application.properties 에서 불러옴
private String host;

@Value("${spring.redis.port}") // application.properties 에서 불러옴
private int port;

@Value("${spring.redis.password}")
private String password;

@Bean
public RedisConnectionFactory redisConnectionFactory() {
RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration();
redisStandaloneConfiguration.setHostName(host);
redisStandaloneConfiguration.setPort(port);
redisStandaloneConfiguration.setPassword(password);
return new LettuceConnectionFactory(redisStandaloneConfiguration);
}

@Bean
public CacheManager cacheManager(RedisConnectionFactory connectionFactory) {
RedisCacheManager.RedisCacheManagerBuilder builder = RedisCacheManager.RedisCacheManagerBuilder.fromConnectionFactory(redisConnectionFactory());
RedisCacheConfiguration configuration = RedisCacheConfiguration.defaultCacheConfig()
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer()))
.entryTtl(Duration.ofHours(12)); // TTL 12시간으로 지정
builder.cacheDefaults(configuration);

return builder.build();
}
}
48 changes: 48 additions & 0 deletions backend/src/main/java/autoever2/cartag/cars/CarController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package autoever2.cartag.cars;

import autoever2.cartag.cars.dto.CarDefaultDto;
import autoever2.cartag.cars.dto.CarVo;
import autoever2.cartag.cars.dto.CarTypeDto;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;

@RestController
@RequestMapping("api/cars")
@RequiredArgsConstructor
@Tag(name = "차량 관련 API", description = "차종 및 차량 트림, 차량의 기본 정보를 제공합니다.")
public class CarController {

private final CarService service;


@Operation(summary = "차종에 속한 모든 트림을 조회하는 API", description = "차종 ID를 통해 르블랑, 익스클루시브 등 차종에 속한 모든 트림을 반환하는 API입니다.")
@ApiResponse(responseCode = "200", content = @Content(schema = @Schema(implementation = CarVo.class)))
@GetMapping("/types")
public List<CarVo> carTrimInfo(@Parameter(description = "차종 ID") @RequestParam("cartype") int carType) {
return service.getCarDtoByCarType(carType);
}

@Operation(summary = "차종 리스트를 조회하는 API", description = "팰리세이드, 베뉴 등 차종 리스트 및 이미지를 반환하는 API입니다.")
@ApiResponse(responseCode = "200", content = @Content(schema = @Schema(implementation = CarTypeDto.class)))
@GetMapping("/list")
public List<CarTypeDto> getCarTypeList() {
return service.getAllCarTypes();
}

@Operation(summary = "트림의 기본 정보를 조회하는 API", description = "트림의 기본 옵션, 기본 모델타입을 반환하는 API입니다.")
@ApiResponse(responseCode = "200", content = @Content(schema = @Schema(implementation = CarDefaultDto.class)))
@GetMapping("/infos/defaults")
public CarDefaultDto carDefaultDto(@Parameter(description = "트림 ID") @RequestParam("carid") int carId) {
return service.getCarDefaultDtoByCarId(carId);
}
}
98 changes: 98 additions & 0 deletions backend/src/main/java/autoever2/cartag/cars/CarRepository.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
package autoever2.cartag.cars;

import autoever2.cartag.cars.dto.CarInfoDto;
import autoever2.cartag.cars.dto.CarTypeDto;
import autoever2.cartag.cars.dto.TrimInfoDto;
import org.springframework.dao.support.DataAccessUtils;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.jdbc.core.namedparam.SqlParameterSource;
import org.springframework.stereotype.Repository;

import javax.sql.DataSource;
import java.util.List;
import java.util.Optional;

@Repository
public class CarRepository {

private final NamedParameterJdbcTemplate template;

public CarRepository(DataSource dataSource) {
template = new NamedParameterJdbcTemplate(dataSource);
}

public List<CarInfoDto> findCarByCarType(int carType) {
String sql = "select car_id, trim, car_default_price, outer_image, inner_image, wheel_image, car_description " +
"from Car " +
"where car_type_id = :carType";

SqlParameterSource param = new MapSqlParameterSource()
.addValue("carType", carType);

return template.query(sql, param, carRowMapper());
}

public Optional<Long> findCarBoughtCountByCarId(int carId) {
String sql = "select bought_count " +
"from Car " +
"where car_id = :carId";

SqlParameterSource param = new MapSqlParameterSource()
.addValue("carId", carId);

return Optional.ofNullable(DataAccessUtils.singleResult(template.query(sql, param, longMapper())));
}

public List<CarTypeDto> findAllCarType() {
String sql = "select car_type_id, car_type_name, car_type_image " +
"from CarType";

return template.query(sql, carTypeDtoRowMapper());
}

public Optional<TrimInfoDto> findTrimInfoByCarId(int carId){
String sql = "select car_id, trim, car_default_price " +
"from Car " +
"where car_id = :carId";

SqlParameterSource param = new MapSqlParameterSource()
.addValue("carId", carId);

return Optional.ofNullable(DataAccessUtils.singleResult(template.query(sql, param, trimInfoRowMapper())));
}

public Optional<Integer> findCarPriceByCarId(int carId) {
String sql = "select car_default_price " +
"from Car " +
"where car_id = :carId";

SqlParameterSource param = new MapSqlParameterSource()
.addValue("carId", carId);

return Optional.ofNullable(DataAccessUtils.singleResult(template.query(sql, param, intMapper())));
}

private RowMapper<CarTypeDto> carTypeDtoRowMapper() {
return BeanPropertyRowMapper.newInstance(CarTypeDto.class);
}

private RowMapper<CarInfoDto> carRowMapper() {
return BeanPropertyRowMapper.newInstance(CarInfoDto.class);
}

private RowMapper<Long> longMapper() {
return (rs, rowNum) -> rs.getLong("bought_count");
}

private RowMapper<Integer> intMapper() {
return (rs, rowNum) -> rs.getInt("car_default_price");
}

private RowMapper<TrimInfoDto> trimInfoRowMapper() {
return BeanPropertyRowMapper.newInstance(TrimInfoDto.class);
}

}
58 changes: 58 additions & 0 deletions backend/src/main/java/autoever2/cartag/cars/CarService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package autoever2.cartag.cars;

import autoever2.cartag.cars.dto.*;
import autoever2.cartag.domain.color.InnerColorDto;
import autoever2.cartag.domain.color.OuterColorDto;
import autoever2.cartag.domain.model.ModelDefaultDto;
import autoever2.cartag.exception.EmptyDataException;
import autoever2.cartag.exception.ErrorCode;
import autoever2.cartag.repository.ColorRepository;
import autoever2.cartag.repository.ModelRepository;
import autoever2.cartag.repository.OptionRepository;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

import static autoever2.cartag.parser.ImageUrlParser.changeUrl;

@Service
@Slf4j
@RequiredArgsConstructor
public class CarService {

private final CarRepository carRepository;
private final OptionRepository optionRepository;
private final ColorRepository colorRepository;
private final ModelRepository modelRepository;

public List<CarTypeDto> getAllCarTypes() {
return carRepository.findAllCarType();
}

public List<CarVo> getCarDtoByCarType(int carType) {
List<CarInfoDto> carInfos = carRepository.findCarByCarType(carType);
if (carInfos.isEmpty()) {
throw new EmptyDataException(ErrorCode.DATA_NOT_EXISTS);
}

return carInfos.stream()
.map(carInfoDto -> CarVo.toVo(carInfoDto, optionRepository.findDefaultOptionByCarId(carInfoDto.getCarId())))
.collect(Collectors.toList());
}

public CarDefaultDto getCarDefaultDtoByCarId(int carId) {
List<OuterColorDto> outerColorList = colorRepository.findOuterColorCarByCarId(carId);
List<InnerColorDto> innerColorList = colorRepository.findInnerColorCarByCarId(carId);
List<ModelDefaultDto> modelList = modelRepository.findModelDefaultDtoByCarId(carId);
if (outerColorList.isEmpty() || innerColorList.isEmpty() || modelList.isEmpty()) {
throw new EmptyDataException(ErrorCode.DATA_NOT_EXISTS);
}
String outerImageUrl = changeUrl(outerColorList.get(0).getColorCarImage());

return CarDefaultDto.toDefault(outerColorList.get(0), innerColorList.get(0), modelList, outerImageUrl);
}

}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package autoever2.cartag.domain.car;
package autoever2.cartag.cars.dto;

import autoever2.cartag.domain.color.InnerColorDto;
import autoever2.cartag.domain.color.OuterColorDto;
Expand All @@ -11,50 +11,50 @@

@Getter
@Builder
@Schema(description = "차량 Default value를 반환하는 dto")
@Schema(description = "차량의 모델타입, 색상의 기본값을 반환")
public class CarDefaultDto {
@Schema(description = "powerTrain의 id")
@Schema(description = "기본 파워트레인 ID", example = "1")
private int powerTrainId;
@Schema(description = "기본 powerTrain의 이름", example = "디젤 2.2")
@Schema(description = "기본 파워트레인명", example = "디젤 2.2")
private String powerTrainName;
@Schema(description = "기본 powerTrain의 이미지 url")
@Schema(description = "기본 파워트레인 이미지 주소")
private String powerTrainImage;
@Schema(description = "기본 powerTrain의 가격")
@Schema(description = "기본 파워트레인 가격")
private Long powerTrainPrice;

@Schema(description = "bodyType의 id")
@Schema(description = "기본 바디타입 ID", example = "5")
private int bodyTypeId;
@Schema(description = "기본 bodyType의 이름", example = "7인승")
@Schema(description = "기본 바디타입명", example = "7인승")
private String bodyTypeName;
@Schema(description = "기본 bodyType의 이미지 url")
@Schema(description = "기본 바디타입 이미지 주소")
private String bodyTypeImage;
@Schema(description = "기본 bodyType의 가격")
@Schema(description = "기본 바디타입 가격")
private Long bodyTypePrice;

@Schema(description = "operation의 id")
@Schema(description = "기본 구동방식 ID", example = "3")
private int operationId;
@Schema(description = "기본 operation의 이름", example = "2WD")
@Schema(description = "기본 구동방식 이름", example = "2WD")
private String operationName;
@Schema(description = "기본 operation의 이미지 url")
@Schema(description = "기본 구동방식 이미지 주소")
private String operationImage;
@Schema(description = "기본 operation의 가격")
@Schema(description = "기본 구동방식 가격")
private Long operationPrice;

@Schema(description = "외장색상의 id")
@Schema(description = "기본 외장색상 ID", example = "3")
private int colorOuterId;
@Schema(description = "기본 외장색상 이미지 url")
@Schema(description = "기본 외장색상 이미지 주소")
private String colorOuterImage;
@Schema(description = "기본 외장색상이 적용된 차량 url")
@Schema(description = "기본 외장색상이 적용된 트림 이미지 주소")
private String colorCarOuterImage;
@Schema(description = "기본 외장색상 가격")
private Long colorOuterPrice;
@Schema(description = "기본 외장색상 이름")
private String colorOuterImageName;
@Schema(description = "내장색상의 id")
@Schema(description = "내장색상 ID", example = "1")
private int colorInnerId;
@Schema(description = "기본 내장색상 이미지 url")
@Schema(description = "기본 내장색상 이미지 주소")
private String colorInnerImage;
@Schema(description = "기본 내장색상이 적용된 차량 url")
@Schema(description = "기본 내장색상이 적용된 트림 이미지 주소")
private String colorCarInnerImage;
@Schema(description = "기본 내장색상 가격")
private Long colorInnerPrice;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package autoever2.cartag.domain.car;
package autoever2.cartag.cars.dto;

import lombok.Builder;
import lombok.Getter;
Expand All @@ -11,17 +11,11 @@
public class CarInfoDto {

private int carId;

private String trim;

private int carDefaultPrice;

private String outerImage;

private String innerImage;

private String wheelImage;

private String carDescription;

@Builder
Expand Down
Loading

0 comments on commit 7f05470

Please sign in to comment.