Skip to content

Commit

Permalink
Merge pull request #54 from KUSITMS-30th-TEAM-A/feature/#46/jamsil-cu…
Browse files Browse the repository at this point in the history
…lture

[feat] 야구 문화 API 구현 및 테스트코드를 작성한다.
  • Loading branch information
juuuunny authored Nov 7, 2024
2 parents d1bb474 + 190d04d commit ddbcbbe
Show file tree
Hide file tree
Showing 30 changed files with 1,095 additions and 21 deletions.
10 changes: 10 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,20 @@ dependencies {
// MacOS Silicon 라이브러리 누락 문제
runtimeOnly 'io.netty:netty-resolver-dns-native-macos:4.1.104.Final:osx-aarch_64'


// Querydsl 추가
implementation 'com.querydsl:querydsl-jpa:5.0.0:jakarta'
annotationProcessor "com.querydsl:querydsl-apt:5.0.0:jakarta"
annotationProcessor "jakarta.annotation:jakarta.annotation-api"
annotationProcessor "jakarta.persistence:jakarta.persistence-api"

// S3
implementation 'org.springframework.cloud:spring-cloud-starter-aws:2.2.6.RELEASE'

}

def querydslDir = "src/main/generated"

ext {
snippetsDir = file('build/generated-snippets')
}
Expand Down
1 change: 1 addition & 0 deletions src/main/java/kusitms/backend/auth/jwt/JWTFilter.java
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ protected boolean shouldNotFilter(HttpServletRequest request) {
|| path.equals("/api/v1/token/re-issue")
|| path.equals("/api/v1/test/docs") || path.startsWith(("/swagger-ui")) || path.startsWith("/v3/api-docs")
|| path.startsWith("/api/v1/results") || path.startsWith("/api/v1/stadium")
|| path.startsWith("/api/v1/culture")
|| path.startsWith("/api/v1/chatbot")
;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package kusitms.backend.culture.application;

import kusitms.backend.culture.domain.enums.Boundary;
import kusitms.backend.culture.domain.repository.EntertainmentRepository;
import kusitms.backend.culture.dto.response.GetEntertainmentsResponseDto;
import kusitms.backend.culture.status.FoodErrorStatus;
import kusitms.backend.global.exception.CustomException;
import kusitms.backend.stadium.domain.entity.Stadium;
import kusitms.backend.stadium.domain.repository.StadiumRepository;
import kusitms.backend.stadium.status.StadiumErrorStatus;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

@Service
@RequiredArgsConstructor
public class EntertainmentService {

private final EntertainmentRepository entertainmentRepository;
private final StadiumRepository stadiumRepository;

@Transactional(readOnly = true)
public GetEntertainmentsResponseDto getSuitableEntertainments(String stadiumName, String boundary) {
Stadium stadium = stadiumRepository.findByName(stadiumName)
.orElseThrow(() -> new CustomException(StadiumErrorStatus._NOT_FOUND_STADIUM));

if (!Boundary.isExists(boundary)) {
throw new CustomException(FoodErrorStatus._BAD_REQUEST_BOUNDARY);
}

Boundary existBoundary = Boundary.of(boundary);

List<GetEntertainmentsResponseDto.EntertainmentDto> entertainments = entertainmentRepository.findAllByStadiumAndBoundary(stadium, existBoundary)
.stream()
.map(GetEntertainmentsResponseDto.EntertainmentDto::from)
.toList();
return GetEntertainmentsResponseDto.of(entertainments);

}
}
40 changes: 40 additions & 0 deletions src/main/java/kusitms/backend/culture/application/FoodService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package kusitms.backend.culture.application;

import kusitms.backend.culture.domain.enums.Boundary;
import kusitms.backend.culture.domain.enums.Course;
import kusitms.backend.culture.domain.repository.FoodRepository;
import kusitms.backend.culture.dto.response.GetFoodsResponseDto;
import kusitms.backend.global.exception.CustomException;
import kusitms.backend.stadium.domain.entity.Stadium;
import kusitms.backend.stadium.domain.repository.StadiumRepository;
import kusitms.backend.stadium.status.StadiumErrorStatus;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

@Service
@RequiredArgsConstructor
public class FoodService {

private final FoodRepository foodRepository;
private final StadiumRepository stadiumRepository;

@Transactional(readOnly = true)
public GetFoodsResponseDto getSuitableFoods(String stadiumName, String boundary, String course) {
Stadium stadium = stadiumRepository.findByName(stadiumName)
.orElseThrow(() -> new CustomException(StadiumErrorStatus._NOT_FOUND_STADIUM));
Boundary existBoundary = Boundary.of(boundary);
Course existCourse = null;
if ("내부".equals(boundary)) {
existCourse = Course.of(course);
}

List<GetFoodsResponseDto.FoodDto> foods = foodRepository.findFoodsByConditions(stadium, existBoundary, existCourse)
.stream()
.map(GetFoodsResponseDto.FoodDto::from)
.toList();
return GetFoodsResponseDto.of(foods);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package kusitms.backend.culture.domain.entity;

import jakarta.persistence.*;
import kusitms.backend.culture.domain.enums.Boundary;
import kusitms.backend.global.domain.BaseTimeEntity;
import kusitms.backend.result.domain.converter.StringListConverter;
import kusitms.backend.stadium.domain.entity.Stadium;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;

import java.util.List;

@Entity
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class Entertainment extends BaseTimeEntity {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "entertainment_id", nullable = false)
private Long id;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "stadium_id", nullable = false)
private Stadium stadium;

@Column(nullable = false)
private String imgUrl;

@Enumerated(EnumType.STRING)
private Boundary boundary;

@Column(nullable = false)
private String name;

@Lob
@Convert(converter = StringListConverter.class)
private List<String> explanations;

@Lob
@Convert(converter = StringListConverter.class)
private List<String> tips;
}
54 changes: 54 additions & 0 deletions src/main/java/kusitms/backend/culture/domain/entity/Food.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package kusitms.backend.culture.domain.entity;

import jakarta.persistence.*;
import kusitms.backend.culture.domain.enums.Boundary;
import kusitms.backend.culture.domain.enums.Course;
import kusitms.backend.global.domain.BaseTimeEntity;
import kusitms.backend.result.domain.converter.StringListConverter;
import kusitms.backend.stadium.domain.entity.Stadium;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;

import java.util.List;

@Entity
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class Food extends BaseTimeEntity {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "food_id", nullable = false)
private Long id;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "stadium_id", nullable = false)
private Stadium stadium;

@Column(nullable = false)
private String imgUrl;

@Enumerated(EnumType.STRING)
private Boundary boundary;

@Enumerated(EnumType.STRING)
private Course course;

@Column(nullable = false)
private String name;

@Column(nullable = false)
private String location;

@Lob
@Convert(converter = StringListConverter.class)
private List<String> menu;

@Column(nullable = false)
private String price;

@Column(nullable = false)
private String tip;

}
30 changes: 30 additions & 0 deletions src/main/java/kusitms/backend/culture/domain/enums/Boundary.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package kusitms.backend.culture.domain.enums;

import lombok.Getter;
import lombok.RequiredArgsConstructor;

import java.util.Arrays;

@Getter
@RequiredArgsConstructor
public enum Boundary {

INTERIOR("내부"),
EXTERIOR("외부");

private final String name;

public static boolean isExists(String name) {
return Arrays.stream(Boundary.values())
.anyMatch(boundary -> boundary.getName().equals(name));
}

public static Boundary of(String name) {
for (Boundary boundary : Boundary.values()) {
if (boundary.getName().equals(name)) {
return boundary;
}
}
return null;
}
}
31 changes: 31 additions & 0 deletions src/main/java/kusitms/backend/culture/domain/enums/Course.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package kusitms.backend.culture.domain.enums;

import lombok.Getter;
import lombok.RequiredArgsConstructor;

import java.util.Arrays;

@Getter
@RequiredArgsConstructor
public enum Course {

MEAL("식사"),
DESSERT("후식"),
TOTAL("전체");

private final String name;

public static boolean isExists(String name) {
return Arrays.stream(Course.values())
.anyMatch(course -> course.getName().equals(name));
}

public static Course of(String name) {
for (Course course : Course.values()) {
if (course.getName().equals(name)) {
return course;
}
}
return null;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package kusitms.backend.culture.domain.repository;

import kusitms.backend.culture.domain.entity.Entertainment;
import kusitms.backend.culture.domain.enums.Boundary;
import kusitms.backend.stadium.domain.entity.Stadium;
import org.springframework.data.jpa.repository.JpaRepository;

import java.util.List;

public interface EntertainmentRepository extends JpaRepository<Entertainment, Long> {
List<Entertainment> findAllByStadiumAndBoundary(Stadium stadium, Boundary boundary);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package kusitms.backend.culture.domain.repository;

import kusitms.backend.culture.domain.entity.Food;
import kusitms.backend.culture.domain.repository.custom.FoodRepositoryCustom;
import org.springframework.data.jpa.repository.JpaRepository;

public interface FoodRepository extends JpaRepository<Food, Long>, FoodRepositoryCustom {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package kusitms.backend.culture.domain.repository.custom;

import kusitms.backend.culture.domain.entity.Food;
import kusitms.backend.culture.domain.enums.Boundary;
import kusitms.backend.culture.domain.enums.Course;
import kusitms.backend.stadium.domain.entity.Stadium;

import java.util.List;

public interface FoodRepositoryCustom {
List<Food> findFoodsByConditions(Stadium stadium, Boundary boundary, Course course);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package kusitms.backend.culture.domain.repository.custom;

import com.querydsl.core.BooleanBuilder;
import com.querydsl.jpa.impl.JPAQueryFactory;
import kusitms.backend.culture.domain.entity.Food;
import kusitms.backend.culture.domain.enums.Boundary;
import kusitms.backend.culture.domain.enums.Course;
import kusitms.backend.stadium.domain.entity.Stadium;
import lombok.RequiredArgsConstructor;

import java.util.List;

import static kusitms.backend.culture.domain.entity.QFood.food;

@RequiredArgsConstructor
public class FoodRepositoryImpl implements FoodRepositoryCustom{

private final JPAQueryFactory jpaQueryFactory;


@Override
public List<Food> findFoodsByConditions(Stadium stadium, Boundary boundary, Course course) {

BooleanBuilder builder = new BooleanBuilder();
builder.and(food.stadium.eq(stadium));
builder.and(food.boundary.eq(boundary));
if (boundary == Boundary.INTERIOR) {
builder.and(food.course.eq(course));
}

return jpaQueryFactory
.selectFrom(food)
.distinct()
.where(builder)
.fetch();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package kusitms.backend.culture.dto.response;

import kusitms.backend.culture.domain.entity.Entertainment;
import kusitms.backend.culture.domain.enums.Boundary;

import java.util.List;

public record GetEntertainmentsResponseDto(
List<EntertainmentDto> entertainments
) {
public record EntertainmentDto(
String imgUrl,
Boundary boundary,
String name,
List<String> explanations,
List<String> tips
) {
public static EntertainmentDto from(Entertainment entertainment) {
return new EntertainmentDto(
entertainment.getImgUrl(),
entertainment.getBoundary(),
entertainment.getName(),
entertainment.getExplanations(),
entertainment.getTips()
);
}
}

public static GetEntertainmentsResponseDto of(List<EntertainmentDto> entertainments) {
return new GetEntertainmentsResponseDto(entertainments);
}
}
Loading

0 comments on commit ddbcbbe

Please sign in to comment.