Skip to content

Commit 8b5cb0d

Browse files
Merge pull request #54 from prgrms-web-devcourse-final-project/feat/#42
[Concerts] 공연 목록 조회, 공연 상세 조회, 공연 예매처 조회 추가
2 parents a6c19c0 + ac02b40 commit 8b5cb0d

11 files changed

Lines changed: 382 additions & 5 deletions

File tree

src/main/java/com/back/web7_9_codecrete_be/domain/concerts/controller/ConcertController.java

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,35 @@
22

33
import com.back.web7_9_codecrete_be.domain.concerts.dto.KopisApiDto.concert.ConcertListResponse;
44
import com.back.web7_9_codecrete_be.domain.concerts.dto.KopisApiDto.concertPlace.ConcertPlaceListResponse;
5+
import com.back.web7_9_codecrete_be.domain.concerts.dto.concert.ConcertDetailResponse;
6+
import com.back.web7_9_codecrete_be.domain.concerts.dto.concert.ConcertItem;
7+
import com.back.web7_9_codecrete_be.domain.concerts.dto.ticketOffice.TicketOfficeElement;
8+
import com.back.web7_9_codecrete_be.domain.concerts.entity.TicketOffice;
59
import com.back.web7_9_codecrete_be.domain.concerts.service.ConcertService;
610
import com.back.web7_9_codecrete_be.domain.concerts.service.KopisApiService;
11+
import com.back.web7_9_codecrete_be.global.rsData.RsData;
12+
import io.swagger.v3.oas.annotations.Operation;
13+
import io.swagger.v3.oas.annotations.media.Schema;
14+
import io.swagger.v3.oas.annotations.tags.Tag;
715
import lombok.RequiredArgsConstructor;
16+
import org.springdoc.core.converters.models.PageableAsQueryParam;
17+
import org.springframework.data.domain.Page;
18+
import org.springframework.data.domain.PageRequest;
19+
import org.springframework.data.domain.Pageable;
20+
import org.springframework.data.domain.Sort;
821
import org.springframework.stereotype.Controller;
922
import org.springframework.web.bind.annotation.GetMapping;
1023
import org.springframework.web.bind.annotation.RequestMapping;
24+
import org.springframework.web.bind.annotation.RequestParam;
1125
import org.springframework.web.bind.annotation.RestController;
1226

27+
import java.util.List;
28+
1329
@RestController
1430
@RequestMapping("api/v1/concerts/")
1531
@Controller
1632
@RequiredArgsConstructor
33+
@Tag(name = "Concerts", description = "공연에 대한 정보를 제공하는 API 입니다.")
1734
public class ConcertController {
1835
private final ConcertService concertService;
1936
private final KopisApiService kopisApiService;
@@ -33,4 +50,46 @@ public ConcertPlaceListResponse setConcertPlace() throws InterruptedException {
3350
return kopisApiService.setConcertPlace();
3451
}
3552

53+
@Operation(summary = "공연목록", description = "공연 전체 목록을 조회합니다. 시작일자를 기준으로 오름차순 조회합니다.")
54+
@GetMapping("list")
55+
public RsData<List<ConcertItem>> getList (
56+
@RequestParam
57+
@Schema(description = "page입니다. 일단은 ?page={page} 로 넘기시면 됩니다.", example = "1")
58+
int page
59+
) {
60+
Pageable pageable = PageRequest.of(page, 10, Sort.by("startDate").ascending());
61+
return RsData.success(concertService.getConcertsList(pageable));
62+
}
63+
64+
@Operation(summary = "다가오는 공연 목록", description = "오늘을 기준으로 다가오는 공연 목록을 조회합니다.")
65+
@GetMapping("upComingList")
66+
public RsData<List<ConcertItem>> getUpComingList (
67+
@RequestParam
68+
@Schema(description = "page입니다. 일단은 ?page={page} 로 넘기시면 됩니다.", example = "1")
69+
int page
70+
) {
71+
Pageable pageable = PageRequest.of(page, 10);
72+
return RsData.success(concertService.getUpcomingConcertsList(pageable));
73+
}
74+
75+
@Operation(summary = "공연 상세 조회", description = "공연에 대한 상세 목록을 조회합니다.")
76+
@GetMapping("concertDetail")
77+
public ConcertDetailResponse getConcertDetail(
78+
@RequestParam
79+
@Schema(description = "조회 기준이 되는 concertId입니다. ?concertId={concertId} 로 값을 넘기시면 됩니다.")
80+
long concertId
81+
) {
82+
return concertService.getConcertDetail(concertId);
83+
}
84+
85+
@Operation(summary = "공연 예매처 조회", description = "공연에 대한 예매처들을 조회합니다.")
86+
@GetMapping("ticketOffices")
87+
public RsData<List<TicketOfficeElement>> getTicketOffices (
88+
@RequestParam
89+
@Schema(description = "조회 기준이 되는 concertId입니다. ?concertId={concertId} 로 값을 넘기시면 됩니다.")
90+
long concertId
91+
){
92+
return RsData.success(concertService.getTicketOfficesList(concertId));
93+
}
94+
3695
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
package com.back.web7_9_codecrete_be.domain.concerts.dto.concert;
2+
3+
import io.swagger.v3.oas.annotations.media.Schema;
4+
import lombok.AllArgsConstructor;
5+
import lombok.Getter;
6+
import lombok.RequiredArgsConstructor;
7+
8+
import java.time.LocalDate;
9+
10+
@Getter
11+
public class ConcertDetailResponse {
12+
13+
@Schema(description = "콘서트 Id입니다.")
14+
private Long concertId;
15+
16+
@Schema(description = "콘서트 이름입니다.")
17+
private String name;
18+
19+
@Schema(description = "콘서트에 대한 설명입니다.")
20+
private String description;
21+
22+
@Schema(description = "콘서트 장소 이름입니다.")
23+
private String placeName;
24+
25+
@Schema(description = "콘서트 시작 날짜입니다.",format = "yyyy-MM-dd")
26+
private LocalDate startDate;
27+
28+
@Schema(description = "콘서트 종료 날짜입니다.",format = "yyyy-MM-dd")
29+
private LocalDate endDate;
30+
31+
@Schema(description = "콘서트 포스터URL입니다. 썸네일로 사용해주세요.")
32+
private String posterUrl;
33+
34+
@Schema(description = "콘서트 티켓 최고가입니다.")
35+
private int maxPrice;
36+
37+
@Schema(description = "콘서트 티켓 최저가입니다.")
38+
private int minPrice;
39+
40+
@Schema(description = "콘서트 조회수입니다.")
41+
private int viewCount;
42+
43+
@Schema(description = "콘서트 좋아요수입니다.")
44+
private int likeCount;
45+
46+
}
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
package com.back.web7_9_codecrete_be.domain.concerts.dto.concert;
2+
3+
import com.back.web7_9_codecrete_be.domain.concerts.entity.Concert;
4+
import io.swagger.v3.oas.annotations.media.Schema;
5+
import lombok.Getter;
6+
import lombok.Setter;
7+
8+
import java.time.LocalDate;
9+
10+
@Getter
11+
@Setter
12+
public class ConcertItem {
13+
14+
@Schema(description = "콘서트 Id입니다.")
15+
private long id;
16+
17+
@Schema(description = "콘서트 이름입니다.")
18+
private String name;
19+
20+
@Schema(description = "콘서트 장소 이름입니다.")
21+
private String placeName;
22+
23+
@Schema(description = "콘서트 시작 날짜입니다.",format = "yyyy-MM-dd")
24+
private LocalDate startDate ;
25+
26+
@Schema(description = "콘서트 종료 날짜입니다.",format = "yyyy-MM-dd")
27+
private LocalDate endDate ;
28+
29+
@Schema(description = "콘서트 포스터URL입니다. 썸네일로 사용해주세요.")
30+
private String posterUrl;
31+
32+
@Schema(description = "콘서트 티켓 최고가입니다.")
33+
private int maxPrice;
34+
35+
@Schema(description = "콘서트 티켓 최저가입니다.")
36+
private int minPrice;
37+
38+
@Schema(description = "콘서트 조회수입니다.")
39+
private int viewCount;
40+
41+
@Schema(description = "콘서트 좋아요수입니다.")
42+
private int likeCount;
43+
44+
public ConcertItem(Concert concert) {
45+
this.id = concert.getConcertId();
46+
this.name = concert.getName();
47+
this.placeName = concert.getConcertPlace().getPlaceName();
48+
this.startDate = concert.getStartDate();
49+
this.endDate =concert.getEndDate();
50+
this.posterUrl = concert.getPosterUrl();
51+
this.maxPrice = concert.getMaxPrice();
52+
this.minPrice = concert.getMinPrice();
53+
this.viewCount = concert.getViewCount();
54+
this.likeCount = concert.getLikeCount();
55+
}
56+
57+
public ConcertItem(long id, String name, String placeName, LocalDate startDate, LocalDate endDate, String posterUrl, int maxPrice, int minPrice, int viewCount, int likeCount) {
58+
this.id = id;
59+
this.name = name;
60+
this.placeName = placeName;
61+
this.startDate = startDate;
62+
this.endDate = endDate;
63+
this.posterUrl = posterUrl;
64+
this.maxPrice = maxPrice;
65+
this.minPrice = minPrice;
66+
this.viewCount = viewCount;
67+
this.likeCount = likeCount;
68+
}
69+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package com.back.web7_9_codecrete_be.domain.concerts.dto.ticketOffice;
2+
3+
import com.back.web7_9_codecrete_be.domain.concerts.entity.TicketOffice;
4+
import io.swagger.v3.oas.annotations.media.Schema;
5+
import lombok.Getter;
6+
7+
@Getter
8+
public class TicketOfficeElement {
9+
10+
@Schema(description = "예매처 이름입니다.")
11+
String ticketOfficeName;
12+
13+
@Schema(description = "예매처 주소입니다.")
14+
String ticketOfficeUrl;
15+
16+
public TicketOfficeElement(TicketOffice ticketOffice) {
17+
this.ticketOfficeName = ticketOffice.getTicketOfficeName();
18+
this.ticketOfficeUrl = ticketOffice.getTicketOfficeUrl();
19+
}
20+
}

src/main/java/com/back/web7_9_codecrete_be/domain/concerts/entity/Concert.java

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import lombok.Getter;
55
import lombok.RequiredArgsConstructor;
66

7+
import java.time.LocalDate;
78
import java.time.LocalDateTime;
89

910
@Entity
@@ -25,6 +26,12 @@ public class Concert {
2526
@Column(nullable = false,columnDefinition = "TEXT")
2627
private String content;
2728

29+
@Column(name = "start_date",nullable = false)
30+
private LocalDate startDate;
31+
32+
@Column(name = "end_date",nullable = false)
33+
private LocalDate endDate;
34+
2835
@Column(name = "ticket_time", nullable = false)
2936
private String ticketTime;
3037

@@ -43,18 +50,36 @@ public class Concert {
4350
@Column(name = "api_concert_id", nullable = false)
4451
private String apiConcertId;
4552

46-
public Concert(ConcertPlace concertPlace, String name, String content, String ticketTime, int maxPrice, int minPrice, String apiConcertId) {
53+
@Column(name = "poster_url",nullable = false,columnDefinition = "TEXT")
54+
private String posterUrl;
55+
56+
private int viewCount;
57+
58+
private int likeCount;
59+
60+
61+
62+
public Concert(ConcertPlace concertPlace, String name, String content, LocalDate startDate, LocalDate endDate, String ticketTime, int maxPrice, int minPrice, String posterUrl,String apiConcertId) {
4763
this.concertPlace = concertPlace;
4864
this.name = name;
4965
this.content = content;
5066
this.ticketTime = ticketTime;
67+
this.startDate = startDate;
68+
this.endDate = endDate;
5169
this.createdDate = LocalDateTime.now();
5270
this.modifiedDate = LocalDateTime.now();
5371
this.maxPrice = maxPrice;
5472
this.minPrice = minPrice;
73+
this.posterUrl = posterUrl;
74+
this.likeCount = 0;
75+
this.viewCount = 0;
5576
this.apiConcertId = apiConcertId;
5677
}
5778

79+
public Concert(Long concertId) {
80+
this.concertId = concertId;
81+
}
82+
5883
public Concert update(ConcertPlace concertPlace, String content, String ticketTime, int maxPrice, int minPrice){
5984
this.concertPlace = concertPlace;
6085
this.content = content;

src/main/java/com/back/web7_9_codecrete_be/domain/concerts/entity/TicketOffice.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,21 @@
11
package com.back.web7_9_codecrete_be.domain.concerts.entity;
22

33
import jakarta.persistence.*;
4+
import lombok.AllArgsConstructor;
5+
import lombok.Getter;
6+
import lombok.NoArgsConstructor;
7+
import lombok.Setter;
48

59
@Entity
10+
@NoArgsConstructor
11+
@AllArgsConstructor
12+
@Getter
613
public class TicketOffice {
714
@Id
815
@GeneratedValue(strategy = GenerationType.IDENTITY)
916
private Long id;
1017

11-
@ManyToOne
18+
@ManyToOne(fetch = FetchType.LAZY)
1219
Concert concert;
1320

1421
//예매처 명
@@ -23,4 +30,5 @@ public TicketOffice(Concert concert, String ticketOfficeName, String ticketOffic
2330
this.ticketOfficeName = ticketOfficeName;
2431
this.ticketOfficeUrl = ticketOfficeUrl;
2532
}
33+
2634
}
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,89 @@
11
package com.back.web7_9_codecrete_be.domain.concerts.repository;
22

3+
import com.back.web7_9_codecrete_be.domain.concerts.dto.concert.ConcertDetailResponse;
4+
import com.back.web7_9_codecrete_be.domain.concerts.dto.concert.ConcertItem;
35
import com.back.web7_9_codecrete_be.domain.concerts.entity.Concert;
6+
import com.back.web7_9_codecrete_be.domain.concerts.entity.ConcertPlace;
7+
import com.back.web7_9_codecrete_be.domain.concerts.entity.ConcertTime;
8+
import org.springframework.data.domain.Page;
9+
import org.springframework.data.domain.Pageable;
410
import org.springframework.data.jpa.repository.JpaRepository;
11+
import org.springframework.data.jpa.repository.Query;
12+
import org.springframework.data.repository.query.Param;
513
import org.springframework.stereotype.Repository;
614

15+
import java.time.LocalDate;
16+
import java.util.List;
17+
718
@Repository
819
public interface ConcertRepository extends JpaRepository<Concert, Long> {
920
Concert getConcertByApiConcertId(String apiConcertId);
21+
22+
@Query("""
23+
SELECT
24+
new com.back.web7_9_codecrete_be.domain.concerts.dto.concert.ConcertItem(
25+
c.concertId as id,
26+
c.name as name,
27+
c.concertPlace.placeName as placeName,
28+
c.startDate as startDate,
29+
c.endDate as endDate,
30+
c.posterUrl as posterUrl,
31+
c.maxPrice as maxPrice,
32+
c.minPrice as minPrice,
33+
c.viewCount as viewCount,
34+
c.likeCount as likeCount
35+
)
36+
FROM
37+
Concert c
38+
""")
39+
List<ConcertItem> getConcertItems(Pageable pageable);
40+
41+
@Query("""
42+
SELECT
43+
new com.back.web7_9_codecrete_be.domain.concerts.dto.concert.ConcertItem(
44+
c.concertId as id,
45+
c.name as name,
46+
c.concertPlace.placeName as placeName,
47+
c.startDate as startDate,
48+
c.endDate as endDate,
49+
c.posterUrl as posterUrl,
50+
c.maxPrice as maxPrice,
51+
c.minPrice as minPrice,
52+
c.viewCount as viewCount,
53+
c.likeCount as likeCount
54+
)
55+
FROM
56+
Concert c
57+
WHERE
58+
c.startDate >= :fromDate
59+
ORDER BY
60+
c.startDate
61+
asc
62+
""")
63+
List<ConcertItem> getUpComingConcertItems(
64+
Pageable pageable,
65+
@Param("fromDate") LocalDate fromDate
66+
);
67+
68+
@Query("""
69+
SELECT
70+
new com.back.web7_9_codecrete_be.domain.concerts.dto.concert.ConcertDetailResponse(
71+
c.concertId as concertId,
72+
c.name as name,
73+
c.content as description,
74+
c.concertPlace.placeName as placeName,
75+
c.startDate as startDate,
76+
c.endDate as endDate,
77+
c.posterUrl as posterUrl,
78+
c.maxPrice as maxPrice,
79+
c.minPrice as minPrice,
80+
c.viewCount as viewCount,
81+
c.likeCount as likeCount
82+
)
83+
FROM
84+
Concert c
85+
WHERE
86+
c.concertId = :concertId
87+
""")
88+
ConcertDetailResponse getConcertDetailById(@Param("concertId")long concertId);
1089
}

0 commit comments

Comments
 (0)