Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[fix] CORS 에러 해결 설정 추가 #33

Merged
merged 2 commits into from
Jan 27, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions src/main/java/muit/backend/config/WebConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package muit.backend.config;


import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("http://localhost:5173")
.allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS", "HEAD", "PATCH")
.allowedHeaders("*")
.allowCredentials(true)
.maxAge(3600);
}
}
36 changes: 36 additions & 0 deletions src/main/java/muit/backend/controller/ManageReservController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package muit.backend.controller;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import muit.backend.apiPayLoad.ApiResponse;
import muit.backend.dto.manageReservDTO.ManageReservResponseDTO;
import muit.backend.service.ManageReservService;
import org.springdoc.core.annotations.ParameterObject;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
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.Set;

@Tag(name = "어드민이 공연 예약 관리")
@RestController
@RequiredArgsConstructor
@RequestMapping("/admin/amateur-reservations")
public class ManageReservController {

private final ManageReservService manageReservService;

@Operation(summary = "전체 공연 예약 조회")
@GetMapping
public ApiResponse<Page<ManageReservResponseDTO.ManageReservResultListDTO>> getAllReservations(@ParameterObject Pageable pageable,
@RequestParam(required = false) String keyword,
@RequestParam(required = false) Set<String> selectedFields) {
Page<ManageReservResponseDTO.ManageReservResultListDTO> reservations = manageReservService.getAllReservations(pageable, keyword, selectedFields);
return ApiResponse.onSuccess(reservations);
}

}
53 changes: 53 additions & 0 deletions src/main/java/muit/backend/converter/ManageReservConverter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package muit.backend.converter;

import muit.backend.domain.entity.amateur.AmateurShow;
import muit.backend.domain.entity.member.MemberTicket;
import muit.backend.domain.entity.member.Reservation;
import muit.backend.dto.manageReservDTO.ManageReservResponseDTO;

import java.util.Set;

public class ManageReservConverter {

// reservation에서 amateurshow 가져오기
private static AmateurShow getAmateurShowFromReservation(Reservation reservation) {
return reservation.getMemberTicketList().stream()
.findFirst() // 아무 티켓이나 봐도 같은 공연이니 첫 번째 것 사용
.map(memberTicket -> memberTicket.getAmateurTicket().getAmateurShow())
.orElse(null);
}

public static ManageReservResponseDTO.ManageReservResultListDTO toManageReservResultListDTO(Reservation reservation, Set<String> selectedFields, boolean isKeywordSearch) {

// 키워드 검색이거나 전체 조회인 경우 모든 필드 포함
if (isKeywordSearch || selectedFields == null || selectedFields.isEmpty()) {
AmateurShow amateurShow = getAmateurShowFromReservation(reservation);

return ManageReservResponseDTO.ManageReservResultListDTO.builder()
.reservationId(reservation.getId())
.memberName(reservation.getMember().getName())
.amateurShowName(amateurShow.getName())
.schedule(amateurShow.getSchedule())
.place(amateurShow.getPlace())
.quantity(reservation.getMemberTicketList().stream()
.findFirst()
.map(MemberTicket::getQuantity)
.orElse(null))
.reservationStatus(reservation.getStatus())
.build();
}

// selectedFields로 특정 필드만 선택한 경우
AmateurShow amateurShow = getAmateurShowFromReservation(reservation);
return ManageReservResponseDTO.ManageReservResultListDTO.builder()
.reservationId(reservation.getId()) // ID는 항상 포함
.amateurShowName(selectedFields.contains("amateurShowName") ?
(amateurShow != null ? amateurShow.getName() : null) : null)
.schedule(selectedFields.contains("schedule") ?
(amateurShow != null ? amateurShow.getSchedule() : null) : null)
.reservationStatus(selectedFields.contains("reservationStatus") ?
reservation.getStatus() : null)
.build();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package muit.backend.dto.manageReservDTO;

public class ManageReservRequestDTO {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package muit.backend.dto.manageReservDTO;

import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import muit.backend.domain.enums.ReservationStatus;

public class ManageReservResponseDTO {

@Getter
@Builder
@AllArgsConstructor
@NoArgsConstructor
@JsonInclude(JsonInclude.Include.NON_NULL) // null 값을 가진 필드는 JSON 응답에서 제외
public static class ManageReservResultListDTO { // 소극장 공연 관리 내역 전체 조회
private Long reservationId; // 소극장 예약 id
private String memberName; // 예약자(사용자)명
private String amateurShowName; // 소극장 공연명
private String schedule; // 소극장 공연 날짜/시간
private String place; // 소극장 공연 장소
private Integer quantity;
private ReservationStatus reservationStatus; // 예약 상태 (예약 중, 예약 완료, 사용 완료, 취소 중, 취소 완료)
}
}
23 changes: 23 additions & 0 deletions src/main/java/muit/backend/repository/ReservationRepository.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package muit.backend.repository;

import muit.backend.domain.entity.member.Reservation;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;

public interface ReservationRepository extends JpaRepository<Reservation, Long> {

// 검색어가 있을 때
@Query("SELECT r FROM Reservation r " +
"JOIN FETCH r.member m " +
"JOIN FETCH r.memberTicketList mt " +
"JOIN FETCH mt.amateurTicket at " +
"JOIN FETCH at.amateurShow ams " +
"WHERE m.name LIKE CONCAT('%', :keyword, '%') " +
"OR ams.name LIKE CONCAT('%', :keyword, '%') " +
"OR ams.place LIKE CONCAT('%', :keyword, '%') " +
"OR ams.schedule LIKE CONCAT('%', :keyword, '%')")
Page<Reservation> findByKeyword(Pageable pageable, @Param("keyword") String keyword);
}
14 changes: 14 additions & 0 deletions src/main/java/muit/backend/service/ManageReservService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package muit.backend.service;

import muit.backend.dto.manageReservDTO.ManageReservResponseDTO;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;

import java.util.Set;

@Service
public interface ManageReservService {

public Page<ManageReservResponseDTO.ManageReservResultListDTO> getAllReservations(Pageable pageable, String keyword, Set<String> selectedFields);
}
46 changes: 46 additions & 0 deletions src/main/java/muit/backend/service/ManageReservServiceImpl.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package muit.backend.service;

import lombok.RequiredArgsConstructor;
import muit.backend.converter.AmateurTicketConverter;
import muit.backend.converter.ManageReservConverter;
import muit.backend.domain.entity.amateur.AmateurShow;
import muit.backend.domain.entity.member.Reservation;
import muit.backend.dto.manageReservDTO.ManageReservResponseDTO;
import muit.backend.repository.ReservationRepository;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Set;

@Service
@RequiredArgsConstructor
@Transactional(readOnly = true)
public class ManageReservServiceImpl implements ManageReservService {

private final ReservationRepository reservationRepository;

@Override
public Page<ManageReservResponseDTO.ManageReservResultListDTO> getAllReservations(Pageable pageable, String keyword, Set<String> selectedFields) {

// 검색어가 있는지 확인
boolean isKeywordSearch = keyword != null && !keyword.trim().isEmpty(); // 그냥 빈 검색어도 없다고 침

Page<Reservation> reservations;

// 검색어가 있으면 해당 키워드로 검색
if (isKeywordSearch) {
reservations = reservationRepository.findByKeyword(pageable, keyword);
if(reservations.isEmpty()) {
return Page.empty(pageable);
}
} else { // 검색어가 없으면 모든 소극장 공연 정보 조회
reservations = reservationRepository.findAll(pageable);
}

return reservations.map(reservation ->
ManageReservConverter.toManageReservResultListDTO(reservation, selectedFields, isKeywordSearch)
);
}
}