From 34c4ac48dbab313a18b4ac700a87b8c4112cc96c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=A0=95=EC=9C=A4=ED=98=B8?= Date: Sun, 25 Jan 2026 19:31:38 +0900 Subject: [PATCH 1/6] =?UTF-8?q?fix:=20=EA=B4=80=EB=A6=AC=EC=9E=90=20?= =?UTF-8?q?=ED=8E=98=EC=9D=B4=EC=A7=80=20=ED=8E=98=EC=9D=B4=EC=A7=80?= =?UTF-8?q?=EB=B2=88=ED=98=B8=20=EC=9D=91=EB=8B=B5=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../AdminAmateurShowController.java | 7 +++--- .../controller/AdminApprovalController.java | 7 +++--- .../service/AdminAmateurShowService.java | 8 ++----- .../service/AdminApprovalService.java | 4 ++-- .../controller/AdminBoardController.java | 7 +++--- .../board/service/AdminBoardService.java | 15 +++++++------ .../admin/inquiry/AdminInquiryController.java | 13 +++-------- .../admin/inquiry/AdminInquiryService.java | 9 +++----- .../admin/member/AdminMemberController.java | 6 ++--- .../admin/member/AdminMemberService.java | 4 ++-- .../admin/ticket/AdminTicketController.java | 22 ++++++++++--------- .../admin/ticket/AdminTicketService.java | 12 +++++----- .../board/repository/BoardRepository.java | 5 +++-- 13 files changed, 56 insertions(+), 63 deletions(-) diff --git a/src/main/java/cc/backend/admin/amateurShow/controller/AdminAmateurShowController.java b/src/main/java/cc/backend/admin/amateurShow/controller/AdminAmateurShowController.java index 453323ed..0413a227 100644 --- a/src/main/java/cc/backend/admin/amateurShow/controller/AdminAmateurShowController.java +++ b/src/main/java/cc/backend/admin/amateurShow/controller/AdminAmateurShowController.java @@ -16,6 +16,7 @@ import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.tags.Tag; import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Page; import org.springframework.data.domain.Slice; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.*; @@ -44,7 +45,7 @@ public class AdminAmateurShowController { ) } ) - public ApiResponse> showList( + public ApiResponse> showList( @Parameter(description = "페이지 번호(0부터)", example = "0") @RequestParam(defaultValue = "0") int page, @@ -54,8 +55,8 @@ public ApiResponse> showList( @Parameter(description = "검색 키워드, 공연면", example = "실종") @RequestParam(required = false) String keyword ) { - Slice slice = adminAmateurShowService.getShowList(page, size, keyword); - return ApiResponse.onSuccess(SliceResponse.of(slice)); } + + return ApiResponse.onSuccess(adminAmateurShowService.getShowList(page, size, keyword)); } @GetMapping("/{showId}") @Operation( diff --git a/src/main/java/cc/backend/admin/amateurShow/controller/AdminApprovalController.java b/src/main/java/cc/backend/admin/amateurShow/controller/AdminApprovalController.java index e0516e1c..843069a9 100644 --- a/src/main/java/cc/backend/admin/amateurShow/controller/AdminApprovalController.java +++ b/src/main/java/cc/backend/admin/amateurShow/controller/AdminApprovalController.java @@ -13,6 +13,7 @@ import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.tags.Tag; import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Page; import org.springframework.data.domain.Slice; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.*; @@ -31,7 +32,7 @@ public class AdminApprovalController { summary = "소극장 공연 관리 - 등록 요청 관리", description = "등록 요청 관리 첫페이지, 리스트 조회입니다." ) - public ApiResponse> getApprovalList( + public ApiResponse> getApprovalList( @Parameter(description = "페이지 번호(0부터 시작)", example = "0") @RequestParam(defaultValue = "0") int page, @@ -41,8 +42,8 @@ public ApiResponse> getApprovalList( @Parameter(description = "검색 키워드, 공연 명으로 검색", example = "실종") @RequestParam(required = false) String keyword ){ - Slice slice = adminApprovalService.getApprovalList(page, size, keyword); - return ApiResponse.onSuccess(SliceResponse.of(slice)); + + return ApiResponse.onSuccess(adminApprovalService.getApprovalList(page, size, keyword)); } @PatchMapping("/{showId}/approve") diff --git a/src/main/java/cc/backend/admin/amateurShow/service/AdminAmateurShowService.java b/src/main/java/cc/backend/admin/amateurShow/service/AdminAmateurShowService.java index d8650ce0..4b0c4af6 100644 --- a/src/main/java/cc/backend/admin/amateurShow/service/AdminAmateurShowService.java +++ b/src/main/java/cc/backend/admin/amateurShow/service/AdminAmateurShowService.java @@ -32,7 +32,7 @@ public class AdminAmateurShowService { private final AmateurShowRepository amateurShowRepository; private final ApplicationEventPublisher eventPublisher; - public Slice getShowList(int page, int size, String keyword){ + public Page getShowList(int page, int size, String keyword){ Pageable pageable = PageRequest.of(page, size, Sort.by("id").ascending()); Page pageResult; @@ -42,11 +42,7 @@ public Slice getShowList(int page, int size, St pageResult = amateurShowRepository.findAll(pageable); } - List rows = pageResult.getContent().stream() - .map(this::toListDto) - .toList(); - - return new SliceImpl<>(rows, pageable, pageResult.hasNext()); + return pageResult.map(this::toListDto); } private AdminAmateurShowListResponseDTO toListDto(AmateurShow show){ diff --git a/src/main/java/cc/backend/admin/amateurShow/service/AdminApprovalService.java b/src/main/java/cc/backend/admin/amateurShow/service/AdminApprovalService.java index be3dfe4d..d11c3454 100644 --- a/src/main/java/cc/backend/admin/amateurShow/service/AdminApprovalService.java +++ b/src/main/java/cc/backend/admin/amateurShow/service/AdminApprovalService.java @@ -52,7 +52,7 @@ public AdminAmateurShowSummaryResponseDTO rejectShow(Long showId, AdminAmateurSh return AdminAmateurShowSummaryResponseDTO.from(show); } - public Slice getApprovalList(int page, int size, String keyword) { + public Page getApprovalList(int page, int size, String keyword) { Pageable pageable = PageRequest.of(page, size, Sort.by("id").ascending()); Page pageResult = @@ -64,7 +64,7 @@ public Slice getApprovalList(int page, int size, S .map(this::toApprovalDto) .toList(); - return new SliceImpl<>(content, pageable, pageResult.hasNext()); + return new PageImpl<>(content, pageable, pageResult.getTotalElements()); } private AdminApprovalListResponseDTO toApprovalDto(AmateurShow show) { diff --git a/src/main/java/cc/backend/admin/board/controller/AdminBoardController.java b/src/main/java/cc/backend/admin/board/controller/AdminBoardController.java index bcfff86f..152243a6 100644 --- a/src/main/java/cc/backend/admin/board/controller/AdminBoardController.java +++ b/src/main/java/cc/backend/admin/board/controller/AdminBoardController.java @@ -14,6 +14,7 @@ import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.tags.Tag; import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Page; import org.springframework.data.domain.Slice; import org.springframework.http.ResponseEntity; import org.springframework.security.access.prepost.PreAuthorize; @@ -83,7 +84,7 @@ public ResponseEntity deleteTarget( ) }) @GetMapping - public cc.backend.apiPayLoad.ApiResponse> getAllBoardsForAdmin( + public cc.backend.apiPayLoad.ApiResponse> getAllBoardsForAdmin( @Parameter(description = "페이지 번호 (0부터 시작)", example = "0") @RequestParam(defaultValue = "0") int page, @Parameter(description = "페이지 크기", example = "20") @@ -91,8 +92,8 @@ public cc.backend.apiPayLoad.ApiResponse> @Parameter(description = "검색 키워드, 게시글 제목", example = "예매 방법 꿀팁") @RequestParam(required = false) String keyword) { - Slice slice = adminBoardService.getAllBoardsForAdmin(page, size, keyword); - return cc.backend.apiPayLoad.ApiResponse.onSuccess(SliceResponse.of(slice)); +; + return cc.backend.apiPayLoad.ApiResponse.onSuccess(adminBoardService.getAllBoardsForAdmin(page, size, keyword)); } @Operation( diff --git a/src/main/java/cc/backend/admin/board/service/AdminBoardService.java b/src/main/java/cc/backend/admin/board/service/AdminBoardService.java index b67c0c56..930da047 100644 --- a/src/main/java/cc/backend/admin/board/service/AdminBoardService.java +++ b/src/main/java/cc/backend/admin/board/service/AdminBoardService.java @@ -16,10 +16,7 @@ import cc.backend.image.entity.Image; import cc.backend.image.repository.ImageRepository; import lombok.RequiredArgsConstructor; -import org.springframework.data.domain.PageRequest; -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.Slice; -import org.springframework.data.domain.Sort; +import org.springframework.data.domain.*; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -39,14 +36,18 @@ public class AdminBoardService { //게시글 목록 조회 @Transactional(readOnly = true) - public Slice getAllBoardsForAdmin(int page, int size, String keyword) { + public Page getAllBoardsForAdmin(int page, int size, String keyword) { // 관리자는 삭제된 게시글도 볼 수 있도록 @SQLDelete 우회 Pageable pageable = PageRequest.of(page, size, Sort.by("id").descending()); - Slice boards = (keyword != null && !keyword.isBlank()) + + Page boards = (keyword != null && !keyword.isBlank()) ? boardRepository.searchBoardsIncludingDeletedByTitle(keyword, pageable) : boardRepository.findAllBoardsIncludingDeleted(pageable); - return boards.map(AdminBoardListResponse::from); + List content = boards.getContent().stream() + .map(AdminBoardListResponse::from) + .toList(); + return new PageImpl<>(content, pageable, boards.getTotalElements()); } //게시글 상세조회 diff --git a/src/main/java/cc/backend/admin/inquiry/AdminInquiryController.java b/src/main/java/cc/backend/admin/inquiry/AdminInquiryController.java index 305d2198..83e2d24b 100644 --- a/src/main/java/cc/backend/admin/inquiry/AdminInquiryController.java +++ b/src/main/java/cc/backend/admin/inquiry/AdminInquiryController.java @@ -9,10 +9,7 @@ import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.tags.Tag; import lombok.RequiredArgsConstructor; -import org.springframework.data.domain.PageRequest; -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.Slice; -import org.springframework.data.domain.Sort; +import org.springframework.data.domain.*; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.*; @@ -42,7 +39,7 @@ public ApiResponse replyI @Operation(summary = "관리자 문의 리스트/검색 API", description = "관리자가 문의 리스트를 합니다. keyword로 제목/내용 검색을 합니다.") @GetMapping("") - public ApiResponse> getInquiryList( + public ApiResponse> getInquiryList( @Parameter(description = "검색 키워드(제목/내용)") @RequestParam(required = false) String keyword, @Parameter(description = "페이지 번호(0부터 시작)", example = "0") @@ -51,11 +48,7 @@ public ApiResponse slice = - adminInquiryService.getInquiryList(keyword, pageable); - - return ApiResponse.onSuccess(SliceResponse.of(slice)); + return ApiResponse.onSuccess(adminInquiryService.getInquiryList(keyword, pageable)); } } diff --git a/src/main/java/cc/backend/admin/inquiry/AdminInquiryService.java b/src/main/java/cc/backend/admin/inquiry/AdminInquiryService.java index b76c96d0..a5836e21 100644 --- a/src/main/java/cc/backend/admin/inquiry/AdminInquiryService.java +++ b/src/main/java/cc/backend/admin/inquiry/AdminInquiryService.java @@ -8,10 +8,7 @@ import cc.backend.inquiry.entity.Inquiry; import cc.backend.inquiry.repository.InquiryRepository; import lombok.RequiredArgsConstructor; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.Slice; -import org.springframework.data.domain.SliceImpl; +import org.springframework.data.domain.*; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.util.StringUtils; @@ -36,7 +33,7 @@ public AdminInquiryResponseDTO.AdminInquiryDetailResponseDTO replyInquiry(Long i return AdminInquiryResponseConverter.toInquiryDetailDTO(inquiry); } - public Slice getInquiryList(String keyword, + public Page getInquiryList(String keyword, Pageable pageable) { Page inquiryPage; if (StringUtils.hasText(keyword)) { @@ -50,6 +47,6 @@ public Slice getInquiryL List content = inquiryPage.getContent().stream() .map(AdminInquiryResponseConverter::toSummaryDTO) .toList(); - return new SliceImpl<>(content, pageable, inquiryPage.hasNext()); + return new PageImpl<>(content, pageable, inquiryPage.getTotalElements()); } } diff --git a/src/main/java/cc/backend/admin/member/AdminMemberController.java b/src/main/java/cc/backend/admin/member/AdminMemberController.java index d6e1a4e6..46886ce3 100644 --- a/src/main/java/cc/backend/admin/member/AdminMemberController.java +++ b/src/main/java/cc/backend/admin/member/AdminMemberController.java @@ -9,6 +9,7 @@ import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.tags.Tag; import lombok.*; +import org.springframework.data.domain.Page; import org.springframework.data.domain.Slice; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.core.parameters.P; @@ -24,7 +25,7 @@ public class AdminMemberController { @Operation(summary = "사용자 관리 리스트 조회", description = "모든 사용자를 id순으로 리스트로 조회합니다.") @GetMapping("/list") - public ApiResponse> getAllMember( + public ApiResponse> getAllMember( @Parameter(description = "페이지 번호(0부터 시작)", example = "0") @RequestParam(defaultValue = "0") int page, @@ -34,8 +35,7 @@ public ApiResponse> getAllMember( @Parameter(description = "검색할 사용자 아이디(username)", example = "jihee") @RequestParam(required = false) String keyword ) { - Slice slice = adminMemberService.getMemberList(page, size, keyword); - return ApiResponse.onSuccess(SliceResponse.of(slice)); + return ApiResponse.onSuccess(adminMemberService.getMemberList(page, size, keyword)); } @Operation(summary = "사용자 관리-상세", description = "모든 사용자를 id순으로 리스트로 조회합니다.") diff --git a/src/main/java/cc/backend/admin/member/AdminMemberService.java b/src/main/java/cc/backend/admin/member/AdminMemberService.java index 33bc854c..85fa3d49 100644 --- a/src/main/java/cc/backend/admin/member/AdminMemberService.java +++ b/src/main/java/cc/backend/admin/member/AdminMemberService.java @@ -22,7 +22,7 @@ public class AdminMemberService { private final MemberRepository memberRepository; - public Slice getMemberList(int page, int size, String keyword) { + public Page getMemberList(int page, int size, String keyword) { Pageable pageable = PageRequest.of(page, size, Sort.by("id").ascending()); Page pageResult; @@ -37,7 +37,7 @@ public Slice getMemberList(int page, int size, Strin .map(this::toDto) .toList(); - return new SliceImpl<>(content, pageable, pageResult.hasNext()); + return new PageImpl<>(content, pageable, pageResult.getTotalElements()); } private AdminMemberListResponseDTO toDto(Member m) { diff --git a/src/main/java/cc/backend/admin/ticket/AdminTicketController.java b/src/main/java/cc/backend/admin/ticket/AdminTicketController.java index 26d34702..185378b2 100644 --- a/src/main/java/cc/backend/admin/ticket/AdminTicketController.java +++ b/src/main/java/cc/backend/admin/ticket/AdminTicketController.java @@ -11,7 +11,7 @@ import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.tags.Tag; import lombok.*; -import org.springframework.data.domain.Slice; +import org.springframework.data.domain.Page; import org.springframework.web.bind.annotation.*; @RestController @@ -24,7 +24,7 @@ public class AdminTicketController { @GetMapping("/history") @Operation(summary = "관리자 소극장 티켓 관리 - 표") - public ApiResponse> getTicketHistory( + public ApiResponse> getTicketHistory( @Parameter(description = "페이지 번호(0부터)", example = "0") @RequestParam(defaultValue = "0") int page, @@ -34,8 +34,9 @@ public ApiResponse> getTicketHistory( @Parameter(description = "검색 키워드, 공연 명으로 검색", example = "실종") @RequestParam(required = false) String keyword ){ - Slice slice = adminTicketService.getTicketList(page, size, keyword); - return ApiResponse.onSuccess(SliceResponse.of(slice)); } + ; + return ApiResponse.onSuccess(adminTicketService.getTicketList(page, size, keyword)); + } @GetMapping("/{realTicketId}") @Operation(summary = "관리자 소극장 티켓 관리 상세조회") @@ -48,7 +49,7 @@ public ApiResponse getTicketDetail( @GetMapping("/reservation/history") @Operation(summary = "관리자 예약 내역 관리 - 표", description = "예매 내역을 리스트 형태로 조회합니다.") - public ApiResponse> getReservationHistory( + public ApiResponse> getReservationHistory( @Parameter(description = "페이지 번호(0부터)", example = "0") @RequestParam(defaultValue = "0") int page, @@ -58,8 +59,8 @@ public ApiResponse> getReservationHi @Parameter(description = "검색 키워드, 공연 명으로 검색", example = "실종") @RequestParam(required = false) String keyword ) { - Slice slice = adminTicketService.getReservationList(page, size, keyword); - return ApiResponse.onSuccess(SliceResponse.of(slice)); } + return ApiResponse.onSuccess(adminTicketService.getReservationList(page, size, keyword)); + } @GetMapping("/reservation/{realTicketId}") @Operation(summary = "관리자 예약 내역 관리 상세조회") @@ -72,7 +73,7 @@ public ApiResponse getReservationDetail( @GetMapping("/refund/history") @Operation(summary = "관리자 환불 내역 관리 - 표", description = "환불 내역을 리스트 형태로 조회합니다.") - public ApiResponse> getRefundHistory( + public ApiResponse> getRefundHistory( @Parameter(description = "페이지 번호(0부터)", example = "0") @RequestParam(defaultValue = "0") int page, @@ -82,8 +83,9 @@ public ApiResponse> getRefundHistory( @Parameter(description = "검색 키워드, 공연 명으로 검색", example = "실종") @RequestParam(required = false) String keyword ) { - Slice slice = adminTicketService.getRefundList(page, size, keyword); - return ApiResponse.onSuccess(SliceResponse.of(slice)); } + + return ApiResponse.onSuccess(adminTicketService.getRefundList(page, size, keyword)); + } @GetMapping("/refund/{realTicketId}") @Operation(summary = "관리자 환불 내역 관리 상세조회") diff --git a/src/main/java/cc/backend/admin/ticket/AdminTicketService.java b/src/main/java/cc/backend/admin/ticket/AdminTicketService.java index 5a4cefe1..af70ee86 100644 --- a/src/main/java/cc/backend/admin/ticket/AdminTicketService.java +++ b/src/main/java/cc/backend/admin/ticket/AdminTicketService.java @@ -24,7 +24,7 @@ public class AdminTicketService { private final RealTicketRepository realTicketRepository; // == 소극장 티켓 관리 == // - public Slice getTicketList(int page, int size, String keyword) { + public Page getTicketList(int page, int size, String keyword) { Sort sort = Sort.by( Sort.Order.desc("id") ); @@ -39,7 +39,7 @@ public Slice getTicketList(int page, int size, String k .map(this::toTicketDTO) .toList(); - return new SliceImpl<>(content, pageable, result.hasNext()); + return new PageImpl<>(content, pageable, result.getTotalElements()); } private TicketDetailResponseDTO toTicketDTO(RealTicket t) { @@ -64,7 +64,7 @@ public TicketDetailResponseDTO getTicketDetail(Long realTicketId) { } // == 예약 내역 관리 == // - public Slice getReservationList( + public Page getReservationList( int page, int size, String keyword ) { Sort sort = Sort.by( @@ -82,7 +82,7 @@ public Slice getReservationList( .map(this::toReservationDTO) .toList(); - return new SliceImpl<>(content, pageable, result.hasNext()); + return new PageImpl<>(content, pageable, result.getTotalElements()); } private ReservationDetailResponseDTO toReservationDTO(RealTicket t) { @@ -114,7 +114,7 @@ public ReservationDetailResponseDTO getReservationDetail(Long realTicketId) { .build(); } - public Slice getRefundList(int page, int size, String keyword) { + public Page getRefundList(int page, int size, String keyword) { Pageable pageable = PageRequest.of( page, size, @@ -132,7 +132,7 @@ public Slice getRefundList(int page, int size, String key .map(this::toRefundDTO) .toList(); - return new SliceImpl<>(content, pageable, result.hasNext()); + return new PageImpl<>(content, pageable, result.getTotalElements()); } private RefundListResponseDTO toRefundDTO(RealTicket t) { diff --git a/src/main/java/cc/backend/board/repository/BoardRepository.java b/src/main/java/cc/backend/board/repository/BoardRepository.java index 75c9720a..77a64cd1 100644 --- a/src/main/java/cc/backend/board/repository/BoardRepository.java +++ b/src/main/java/cc/backend/board/repository/BoardRepository.java @@ -2,6 +2,7 @@ import cc.backend.board.entity.Board; import cc.backend.board.entity.enums.BoardType; +import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Slice; import org.springframework.data.jpa.repository.JpaRepository; @@ -22,7 +23,7 @@ public interface BoardRepository extends JpaRepository { Optional findByIdIncludingDeleted(@Param("id") Long id); @Query(value = "SELECT * FROM board ORDER BY id DESC", nativeQuery = true) - Slice findAllBoardsIncludingDeleted(Pageable pageable); + Page findAllBoardsIncludingDeleted(Pageable pageable); //Full-context Search // 일반게시판: 제목 + 내용 @@ -76,7 +77,7 @@ Slice searchPromotionBoards( FROM Board b WHERE LOWER(b.title) LIKE LOWER(CONCAT('%', :keyword, '%')) """) - Slice searchBoardsIncludingDeletedByTitle(@Param("keyword") String keyword, Pageable pageable); + Page searchBoardsIncludingDeletedByTitle(@Param("keyword") String keyword, Pageable pageable); } From bdc2c6fa15ca9b1020626c577d70dbe7f6cc3c06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=A0=95=EC=9C=A4=ED=98=B8?= Date: Sun, 25 Jan 2026 19:31:55 +0900 Subject: [PATCH 2/6] =?UTF-8?q?fix:=20=EA=B4=80=EB=A6=AC=EC=9E=90=20?= =?UTF-8?q?=ED=8E=98=EC=9D=B4=EC=A7=80=20=ED=8E=98=EC=9D=B4=EC=A7=80?= =?UTF-8?q?=EB=B2=88=ED=98=B8=20=EC=9D=91=EB=8B=B5=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/cc/backend/admin/ticket/AdminTicketController.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/cc/backend/admin/ticket/AdminTicketController.java b/src/main/java/cc/backend/admin/ticket/AdminTicketController.java index 185378b2..56ac1112 100644 --- a/src/main/java/cc/backend/admin/ticket/AdminTicketController.java +++ b/src/main/java/cc/backend/admin/ticket/AdminTicketController.java @@ -5,8 +5,7 @@ import cc.backend.admin.ticket.dto.ReservationDetailResponseDTO; import cc.backend.admin.ticket.dto.TicketDetailResponseDTO; import cc.backend.apiPayLoad.ApiResponse; -import cc.backend.apiPayLoad.SliceResponse; -import com.google.protobuf.Api; + import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.tags.Tag; From 894d561111024020ac439e69d55bcad23e07a98f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=A0=95=EC=9C=A4=ED=98=B8?= Date: Sun, 25 Jan 2026 19:40:20 +0900 Subject: [PATCH 3/6] =?UTF-8?q?fix:=20=EC=98=A4=ED=83=80=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cc/backend/admin/board/controller/AdminBoardController.java | 1 - src/main/java/cc/backend/admin/ticket/AdminTicketController.java | 1 - 2 files changed, 2 deletions(-) diff --git a/src/main/java/cc/backend/admin/board/controller/AdminBoardController.java b/src/main/java/cc/backend/admin/board/controller/AdminBoardController.java index 152243a6..cddfce53 100644 --- a/src/main/java/cc/backend/admin/board/controller/AdminBoardController.java +++ b/src/main/java/cc/backend/admin/board/controller/AdminBoardController.java @@ -92,7 +92,6 @@ public cc.backend.apiPayLoad.ApiResponse> getAllBoa @Parameter(description = "검색 키워드, 게시글 제목", example = "예매 방법 꿀팁") @RequestParam(required = false) String keyword) { -; return cc.backend.apiPayLoad.ApiResponse.onSuccess(adminBoardService.getAllBoardsForAdmin(page, size, keyword)); } diff --git a/src/main/java/cc/backend/admin/ticket/AdminTicketController.java b/src/main/java/cc/backend/admin/ticket/AdminTicketController.java index 56ac1112..6f0b1918 100644 --- a/src/main/java/cc/backend/admin/ticket/AdminTicketController.java +++ b/src/main/java/cc/backend/admin/ticket/AdminTicketController.java @@ -33,7 +33,6 @@ public ApiResponse> getTicketHistory( @Parameter(description = "검색 키워드, 공연 명으로 검색", example = "실종") @RequestParam(required = false) String keyword ){ - ; return ApiResponse.onSuccess(adminTicketService.getTicketList(page, size, keyword)); } From 28a9515c842a582516fbe4214b768c20f3938fd8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=A0=95=EC=9C=A4=ED=98=B8?= Date: Mon, 26 Jan 2026 00:21:39 +0900 Subject: [PATCH 4/6] =?UTF-8?q?fix:=20Page=EC=98=A4=EB=B2=84=ED=97=A4?= =?UTF-8?q?=EB=93=9C=20=EC=A4=84=EC=9D=B8=20PageResponse=EB=A1=9C=20?= =?UTF-8?q?=EC=88=98=EC=A0=95=20=EB=B0=8F=20=EB=8C=80=EC=8B=9C=EB=B3=B4?= =?UTF-8?q?=EB=93=9C=20npe=20=EB=94=94=EB=B2=84=EA=B7=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../AdminAmateurShowController.java | 3 +- .../controller/AdminApprovalController.java | 3 +- .../service/AdminAmateurShowService.java | 17 ++-- .../service/AdminApprovalService.java | 9 +- .../controller/AdminBoardController.java | 3 +- .../board/service/AdminBoardService.java | 5 +- .../controller/DashboardController.java | 13 +-- .../dashboard/service/DashboardService.java | 21 ++--- .../admin/inquiry/AdminInquiryController.java | 3 +- .../admin/inquiry/AdminInquiryService.java | 14 ++-- .../admin/member/AdminMemberController.java | 3 +- .../admin/member/AdminMemberService.java | 9 +- .../controller/AdminPhotoAlbumController.java | 7 +- .../service/AdminPhotoAlbumService.java | 33 +++++--- .../admin/ticket/AdminTicketController.java | 7 +- .../admin/ticket/AdminTicketService.java | 29 +++---- .../ticket/dto/RefundListResponseDTO.java | 23 ++--- .../repository/AmateurShowRepository.java | 8 ++ .../cc/backend/apiPayLoad/PageResponse.java | 24 ++++++ .../cc/backend/apiPayLoad/SliceResponse.java | 16 +--- .../cc/backend/search/SearchController.java | 8 +- .../java/cc/backend/search/SearchService.java | 18 +++- .../search/dto/SearchShowResponseDTO.java | 84 ++++++++++++------- 23 files changed, 213 insertions(+), 147 deletions(-) create mode 100644 src/main/java/cc/backend/apiPayLoad/PageResponse.java diff --git a/src/main/java/cc/backend/admin/amateurShow/controller/AdminAmateurShowController.java b/src/main/java/cc/backend/admin/amateurShow/controller/AdminAmateurShowController.java index 0413a227..90093328 100644 --- a/src/main/java/cc/backend/admin/amateurShow/controller/AdminAmateurShowController.java +++ b/src/main/java/cc/backend/admin/amateurShow/controller/AdminAmateurShowController.java @@ -7,6 +7,7 @@ import cc.backend.admin.amateurShow.dto.AdminAmateurShowSummaryResponseDTO; import cc.backend.admin.amateurShow.service.AdminAmateurShowService; import cc.backend.apiPayLoad.ApiResponse; +import cc.backend.apiPayLoad.PageResponse; import cc.backend.apiPayLoad.SliceResponse; import com.google.protobuf.Api; import io.swagger.v3.oas.annotations.Operation; @@ -45,7 +46,7 @@ public class AdminAmateurShowController { ) } ) - public ApiResponse> showList( + public ApiResponse> showList( @Parameter(description = "페이지 번호(0부터)", example = "0") @RequestParam(defaultValue = "0") int page, diff --git a/src/main/java/cc/backend/admin/amateurShow/controller/AdminApprovalController.java b/src/main/java/cc/backend/admin/amateurShow/controller/AdminApprovalController.java index 843069a9..72d5dda6 100644 --- a/src/main/java/cc/backend/admin/amateurShow/controller/AdminApprovalController.java +++ b/src/main/java/cc/backend/admin/amateurShow/controller/AdminApprovalController.java @@ -6,6 +6,7 @@ import cc.backend.admin.amateurShow.service.AdminAmateurShowService; import cc.backend.admin.amateurShow.service.AdminApprovalService; import cc.backend.apiPayLoad.ApiResponse; +import cc.backend.apiPayLoad.PageResponse; import cc.backend.apiPayLoad.SliceResponse; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; @@ -32,7 +33,7 @@ public class AdminApprovalController { summary = "소극장 공연 관리 - 등록 요청 관리", description = "등록 요청 관리 첫페이지, 리스트 조회입니다." ) - public ApiResponse> getApprovalList( + public ApiResponse> getApprovalList( @Parameter(description = "페이지 번호(0부터 시작)", example = "0") @RequestParam(defaultValue = "0") int page, diff --git a/src/main/java/cc/backend/admin/amateurShow/service/AdminAmateurShowService.java b/src/main/java/cc/backend/admin/amateurShow/service/AdminAmateurShowService.java index 4b0c4af6..bfc19601 100644 --- a/src/main/java/cc/backend/admin/amateurShow/service/AdminAmateurShowService.java +++ b/src/main/java/cc/backend/admin/amateurShow/service/AdminAmateurShowService.java @@ -7,6 +7,7 @@ import cc.backend.amateurShow.entity.AmateurShow; import cc.backend.amateurShow.repository.AmateurShowRepository; import cc.backend.apiPayLoad.ApiResponse; +import cc.backend.apiPayLoad.PageResponse; import cc.backend.apiPayLoad.SliceResponse; import cc.backend.apiPayLoad.code.status.ErrorStatus; import cc.backend.apiPayLoad.exception.GeneralException; @@ -30,19 +31,17 @@ @Transactional(readOnly = true) public class AdminAmateurShowService { private final AmateurShowRepository amateurShowRepository; - private final ApplicationEventPublisher eventPublisher; - public Page getShowList(int page, int size, String keyword){ + public PageResponse getShowList(int page, int size, String keyword){ Pageable pageable = PageRequest.of(page, size, Sort.by("id").ascending()); - Page pageResult; - if (keyword != null && !keyword.isBlank()) { - pageResult = amateurShowRepository.findByNameContainingIgnoreCase(keyword, pageable); - } else { - pageResult = amateurShowRepository.findAll(pageable); - } + keyword = (keyword == null) ? "" : keyword.trim(); + Page pageResult = amateurShowRepository.findByNameContainingIgnoreCase(keyword, pageable); - return pageResult.map(this::toListDto); + + Page dtoPage = pageResult.map(this::toListDto); + + return PageResponse.of(dtoPage); } private AdminAmateurShowListResponseDTO toListDto(AmateurShow show){ diff --git a/src/main/java/cc/backend/admin/amateurShow/service/AdminApprovalService.java b/src/main/java/cc/backend/admin/amateurShow/service/AdminApprovalService.java index d11c3454..f06eea33 100644 --- a/src/main/java/cc/backend/admin/amateurShow/service/AdminApprovalService.java +++ b/src/main/java/cc/backend/admin/amateurShow/service/AdminApprovalService.java @@ -5,6 +5,7 @@ import cc.backend.admin.amateurShow.dto.AdminApprovalListResponseDTO; import cc.backend.amateurShow.entity.AmateurShow; import cc.backend.amateurShow.repository.AmateurShowRepository; +import cc.backend.apiPayLoad.PageResponse; import cc.backend.apiPayLoad.code.status.ErrorStatus; import cc.backend.apiPayLoad.exception.GeneralException; import cc.backend.event.entity.ApproveShowEvent; @@ -52,7 +53,7 @@ public AdminAmateurShowSummaryResponseDTO rejectShow(Long showId, AdminAmateurSh return AdminAmateurShowSummaryResponseDTO.from(show); } - public Page getApprovalList(int page, int size, String keyword) { + public PageResponse getApprovalList(int page, int size, String keyword) { Pageable pageable = PageRequest.of(page, size, Sort.by("id").ascending()); Page pageResult = @@ -60,11 +61,9 @@ public Page getApprovalList(int page, int size, St ? amateurShowRepository.findByNameContainingIgnoreCase(keyword, pageable) : amateurShowRepository.findAll(pageable); - List content = pageResult.getContent().stream() - .map(this::toApprovalDto) - .toList(); + Page dtoPage = pageResult.map(this::toApprovalDto); - return new PageImpl<>(content, pageable, pageResult.getTotalElements()); + return PageResponse.of(dtoPage); } private AdminApprovalListResponseDTO toApprovalDto(AmateurShow show) { diff --git a/src/main/java/cc/backend/admin/board/controller/AdminBoardController.java b/src/main/java/cc/backend/admin/board/controller/AdminBoardController.java index cddfce53..705efa0d 100644 --- a/src/main/java/cc/backend/admin/board/controller/AdminBoardController.java +++ b/src/main/java/cc/backend/admin/board/controller/AdminBoardController.java @@ -5,6 +5,7 @@ import cc.backend.admin.board.dto.response.AdminReportSummary; import cc.backend.admin.board.service.AdminBoardService; import cc.backend.admin.board.service.AdminReportService; +import cc.backend.apiPayLoad.PageResponse; import cc.backend.apiPayLoad.SliceResponse; import cc.backend.board.entity.enums.ReportTarget; import io.swagger.v3.oas.annotations.Operation; @@ -84,7 +85,7 @@ public ResponseEntity deleteTarget( ) }) @GetMapping - public cc.backend.apiPayLoad.ApiResponse> getAllBoardsForAdmin( + public cc.backend.apiPayLoad.ApiResponse> getAllBoardsForAdmin( @Parameter(description = "페이지 번호 (0부터 시작)", example = "0") @RequestParam(defaultValue = "0") int page, @Parameter(description = "페이지 크기", example = "20") diff --git a/src/main/java/cc/backend/admin/board/service/AdminBoardService.java b/src/main/java/cc/backend/admin/board/service/AdminBoardService.java index 930da047..10a33647 100644 --- a/src/main/java/cc/backend/admin/board/service/AdminBoardService.java +++ b/src/main/java/cc/backend/admin/board/service/AdminBoardService.java @@ -3,6 +3,7 @@ import cc.backend.admin.board.dto.response.AdminBoardDetailResponse; import cc.backend.admin.board.dto.response.AdminBoardDetailWithCommentsResponse; import cc.backend.admin.board.dto.response.AdminBoardListResponse; +import cc.backend.apiPayLoad.PageResponse; import cc.backend.apiPayLoad.code.status.ErrorStatus; import cc.backend.apiPayLoad.exception.GeneralException; import cc.backend.board.dto.response.CommentResponse; @@ -36,7 +37,7 @@ public class AdminBoardService { //게시글 목록 조회 @Transactional(readOnly = true) - public Page getAllBoardsForAdmin(int page, int size, String keyword) { + public PageResponse getAllBoardsForAdmin(int page, int size, String keyword) { // 관리자는 삭제된 게시글도 볼 수 있도록 @SQLDelete 우회 Pageable pageable = PageRequest.of(page, size, Sort.by("id").descending()); @@ -47,7 +48,7 @@ public Page getAllBoardsForAdmin(int page, int size, Str List content = boards.getContent().stream() .map(AdminBoardListResponse::from) .toList(); - return new PageImpl<>(content, pageable, boards.getTotalElements()); + return new PageResponse<>(content, boards.getNumber(), boards.getSize(), boards.getTotalElements(), boards.getTotalPages()); } //게시글 상세조회 diff --git a/src/main/java/cc/backend/admin/dashboard/controller/DashboardController.java b/src/main/java/cc/backend/admin/dashboard/controller/DashboardController.java index c016bace..84aa89a6 100644 --- a/src/main/java/cc/backend/admin/dashboard/controller/DashboardController.java +++ b/src/main/java/cc/backend/admin/dashboard/controller/DashboardController.java @@ -5,6 +5,7 @@ import cc.backend.admin.dashboard.dto.VisitResponseDTO; import cc.backend.admin.dashboard.service.DashboardService; import cc.backend.apiPayLoad.ApiResponse; +import cc.backend.apiPayLoad.PageResponse; import cc.backend.apiPayLoad.SliceResponse; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; @@ -41,27 +42,27 @@ public ApiResponse> getMonthlyVisits() @GetMapping("/approval") @Operation(summary = "등록 요청 - 간편보기", description = "대쉬보드에서 등록 요청 리스트를 조회합니다.") - public ApiResponse> getApprovalSummary( + public ApiResponse> getApprovalSummary( @Parameter(description = "페이지 번호(0부터 시작)", example = "0") @RequestParam(defaultValue = "0") int page, @Parameter(description = "페이지 크기", example = "10") @RequestParam(defaultValue = "10") int size ){ - Slice slice = dashBoardService.getApprovalList(page, size); - return ApiResponse.onSuccess(SliceResponse.of(slice)); + + return ApiResponse.onSuccess(dashBoardService.getApprovalList(page, size)); } @GetMapping("/reservation") @Operation(summary = "예약 현황 - 간편보기", description = "대쉬보드에서 예약 현황 리스트를 조회합니다.") - public ApiResponse> getReservationSummary( + public ApiResponse> getReservationSummary( @Parameter(description = "페이지 번호(0부터 시작)", example = "0") @RequestParam(defaultValue = "0") int page, @Parameter(description = "페이지 크기", example = "10") @RequestParam(defaultValue = "10") int size ){ - Slice slice = dashBoardService.getReservationList(page, size); - return ApiResponse.onSuccess(SliceResponse.of(slice)); } + return ApiResponse.onSuccess(dashBoardService.getReservationList(page, size) + ); } } diff --git a/src/main/java/cc/backend/admin/dashboard/service/DashboardService.java b/src/main/java/cc/backend/admin/dashboard/service/DashboardService.java index 8ecd7fa4..5a549730 100644 --- a/src/main/java/cc/backend/admin/dashboard/service/DashboardService.java +++ b/src/main/java/cc/backend/admin/dashboard/service/DashboardService.java @@ -7,6 +7,7 @@ import cc.backend.amateurShow.entity.AmateurShow; import cc.backend.amateurShow.repository.AmateurRoundsRepository; import cc.backend.amateurShow.repository.AmateurShowRepository; +import cc.backend.apiPayLoad.PageResponse; import com.google.analytics.data.v1beta.*; import lombok.RequiredArgsConstructor; import org.springframework.data.domain.*; @@ -81,21 +82,20 @@ public List getMonthlyVisits() { private static final DateTimeFormatter DT_FMT = DateTimeFormatter.ofPattern("yyyy-MM-dd / HH:mm"); - public Slice getApprovalList(int page, int size) { + public PageResponse getApprovalList(int page, int size) { Pageable pageable = PageRequest.of(page, size, Sort.by("id").ascending()); Page result = amateurShowRepository.findAll(pageable); - List content = result.getContent().stream() - .map(this::toSummaryDto) - .toList(); + Page dtoPage = result.map(this::toSummaryDto); - return new SliceImpl<>(content, pageable, result.hasNext()); + return PageResponse.of(dtoPage); } private ApprovalSummaryResponseDTO toSummaryDto(AmateurShow s) { String dateTime = s.getCreatedAt().format(DT_FMT); - int capacity = s.getTotalSoldTicket(); + int capacity = s.getTotalSoldTicket() != null ? s.getTotalSoldTicket() : 0; // null이면 0으로 처리 + return ApprovalSummaryResponseDTO.builder() .showId(s.getId()) @@ -105,7 +105,7 @@ private ApprovalSummaryResponseDTO toSummaryDto(AmateurShow s) { .build(); } - public Slice getReservationList(int page, int size) { + public PageResponse getReservationList(int page, int size) { Sort sort = Sort.by( Sort.Order.asc("performanceDateTime"), Sort.Order.asc("id") @@ -114,11 +114,8 @@ public Slice getReservationList(int page, int siz Page result = amateurRoundsRepository.findAll(pageable); - List content = result.getContent().stream() - .map(this::toDto) - .toList(); - - return new SliceImpl<>(content, pageable, result.hasNext()); + Page dtoPage = result.map(this::toDto); + return PageResponse.of(dtoPage); } private ReservationSummaryResponseDTO toDto(AmateurRounds r) { diff --git a/src/main/java/cc/backend/admin/inquiry/AdminInquiryController.java b/src/main/java/cc/backend/admin/inquiry/AdminInquiryController.java index 83e2d24b..01887136 100644 --- a/src/main/java/cc/backend/admin/inquiry/AdminInquiryController.java +++ b/src/main/java/cc/backend/admin/inquiry/AdminInquiryController.java @@ -3,6 +3,7 @@ import cc.backend.admin.inquiry.dto.AdminInquiryRequestDTO; import cc.backend.admin.inquiry.dto.AdminInquiryResponseDTO; import cc.backend.apiPayLoad.ApiResponse; +import cc.backend.apiPayLoad.PageResponse; import cc.backend.apiPayLoad.SliceResponse; import com.google.protobuf.Api; import io.swagger.v3.oas.annotations.Operation; @@ -39,7 +40,7 @@ public ApiResponse replyI @Operation(summary = "관리자 문의 리스트/검색 API", description = "관리자가 문의 리스트를 합니다. keyword로 제목/내용 검색을 합니다.") @GetMapping("") - public ApiResponse> getInquiryList( + public ApiResponse> getInquiryList( @Parameter(description = "검색 키워드(제목/내용)") @RequestParam(required = false) String keyword, @Parameter(description = "페이지 번호(0부터 시작)", example = "0") diff --git a/src/main/java/cc/backend/admin/inquiry/AdminInquiryService.java b/src/main/java/cc/backend/admin/inquiry/AdminInquiryService.java index a5836e21..47408f54 100644 --- a/src/main/java/cc/backend/admin/inquiry/AdminInquiryService.java +++ b/src/main/java/cc/backend/admin/inquiry/AdminInquiryService.java @@ -3,6 +3,7 @@ import cc.backend.admin.inquiry.converter.AdminInquiryResponseConverter; import cc.backend.admin.inquiry.dto.AdminInquiryRequestDTO; import cc.backend.admin.inquiry.dto.AdminInquiryResponseDTO; +import cc.backend.apiPayLoad.PageResponse; import cc.backend.apiPayLoad.code.status.ErrorStatus; import cc.backend.apiPayLoad.exception.GeneralException; import cc.backend.inquiry.entity.Inquiry; @@ -33,8 +34,8 @@ public AdminInquiryResponseDTO.AdminInquiryDetailResponseDTO replyInquiry(Long i return AdminInquiryResponseConverter.toInquiryDetailDTO(inquiry); } - public Page getInquiryList(String keyword, - Pageable pageable) { + public PageResponse getInquiryList(String keyword, + Pageable pageable) { Page inquiryPage; if (StringUtils.hasText(keyword)) { // 제목 or 내용 @@ -44,9 +45,10 @@ public Page getInquiryLi // 없으면 inquiryPage = inquiryRepository.findAll(pageable); } - List content = inquiryPage.getContent().stream() - .map(AdminInquiryResponseConverter::toSummaryDTO) - .toList(); - return new PageImpl<>(content, pageable, inquiryPage.getTotalElements()); + Page dtoPage = + inquiryPage.map(AdminInquiryResponseConverter::toSummaryDTO); + + // PageResponse.of 사용 + return PageResponse.of(dtoPage); } } diff --git a/src/main/java/cc/backend/admin/member/AdminMemberController.java b/src/main/java/cc/backend/admin/member/AdminMemberController.java index 46886ce3..46d084c8 100644 --- a/src/main/java/cc/backend/admin/member/AdminMemberController.java +++ b/src/main/java/cc/backend/admin/member/AdminMemberController.java @@ -4,6 +4,7 @@ import cc.backend.admin.member.dto.AdminMemberListResponseDTO; import cc.backend.admin.member.dto.UpdateMemberDetailRequestDTO; import cc.backend.apiPayLoad.ApiResponse; +import cc.backend.apiPayLoad.PageResponse; import cc.backend.apiPayLoad.SliceResponse; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; @@ -25,7 +26,7 @@ public class AdminMemberController { @Operation(summary = "사용자 관리 리스트 조회", description = "모든 사용자를 id순으로 리스트로 조회합니다.") @GetMapping("/list") - public ApiResponse> getAllMember( + public ApiResponse> getAllMember( @Parameter(description = "페이지 번호(0부터 시작)", example = "0") @RequestParam(defaultValue = "0") int page, diff --git a/src/main/java/cc/backend/admin/member/AdminMemberService.java b/src/main/java/cc/backend/admin/member/AdminMemberService.java index 85fa3d49..6de5f777 100644 --- a/src/main/java/cc/backend/admin/member/AdminMemberService.java +++ b/src/main/java/cc/backend/admin/member/AdminMemberService.java @@ -4,6 +4,7 @@ import cc.backend.admin.member.dto.AdminMemberListResponseDTO; import cc.backend.admin.member.dto.UpdateMemberDetailRequestDTO; import cc.backend.apiPayLoad.ApiResponse; +import cc.backend.apiPayLoad.PageResponse; import cc.backend.apiPayLoad.code.status.ErrorStatus; import cc.backend.apiPayLoad.exception.GeneralException; import cc.backend.member.entity.Member; @@ -22,7 +23,7 @@ public class AdminMemberService { private final MemberRepository memberRepository; - public Page getMemberList(int page, int size, String keyword) { + public PageResponse getMemberList(int page, int size, String keyword) { Pageable pageable = PageRequest.of(page, size, Sort.by("id").ascending()); Page pageResult; @@ -33,11 +34,9 @@ public Page getMemberList(int page, int size, String pageResult = memberRepository.findAll(pageable); } - List content = pageResult.getContent().stream() - .map(this::toDto) - .toList(); + Page dtoPage = pageResult.map(this::toDto); - return new PageImpl<>(content, pageable, pageResult.getTotalElements()); + return PageResponse.of(dtoPage); } private AdminMemberListResponseDTO toDto(Member m) { diff --git a/src/main/java/cc/backend/admin/photoAlbum/controller/AdminPhotoAlbumController.java b/src/main/java/cc/backend/admin/photoAlbum/controller/AdminPhotoAlbumController.java index 36fffd1a..92bcd43b 100644 --- a/src/main/java/cc/backend/admin/photoAlbum/controller/AdminPhotoAlbumController.java +++ b/src/main/java/cc/backend/admin/photoAlbum/controller/AdminPhotoAlbumController.java @@ -3,6 +3,7 @@ import cc.backend.admin.photoAlbum.dto.AdminPhotoAlbumResponseDTO; import cc.backend.admin.photoAlbum.service.AdminPhotoAlbumService; import cc.backend.apiPayLoad.ApiResponse; +import cc.backend.apiPayLoad.PageResponse; import cc.backend.apiPayLoad.SliceResponse; import cc.backend.board.entity.enums.BoardType; import cc.backend.member.entity.Member; @@ -32,7 +33,7 @@ public class AdminPhotoAlbumController { @GetMapping("") @Operation(summary = "관리자페이지 사진첩 전체 조회 API", description = "전체 사진첩 업로드 날짜 내림차순 정렬") - public ApiResponse> getAllPhotoAlbum( + public ApiResponse> getAllPhotoAlbum( @ParameterObject Pageable pageable){ return ApiResponse.onSuccess(adminPhotoAlbumService.getAllPhotoAlbum(pageable)); } @@ -51,10 +52,10 @@ public ApiResponse deletePhotoAlbum(@PathVariable Long photoAlbumId){ @GetMapping("/search") @Operation(summary = "관리자페이지 사진첩 검색 API", description = "사진첩 id, 공연 id, 공연제목, 사진첩 내용에 키워드를 포함하면 반환") - public ApiResponse> searchPhotoAlbum( + public ApiResponse> searchPhotoAlbum( @RequestParam String keyword, @ParameterObject Pageable pageable){ - return ApiResponse.onSuccess((adminPhotoAlbumService.searchPhotoAlbum(keyword, pageable))); + return ApiResponse.onSuccess(SliceResponse.of(adminPhotoAlbumService.searchPhotoAlbum(keyword, pageable))); } diff --git a/src/main/java/cc/backend/admin/photoAlbum/service/AdminPhotoAlbumService.java b/src/main/java/cc/backend/admin/photoAlbum/service/AdminPhotoAlbumService.java index d3e973bd..1dec76f8 100644 --- a/src/main/java/cc/backend/admin/photoAlbum/service/AdminPhotoAlbumService.java +++ b/src/main/java/cc/backend/admin/photoAlbum/service/AdminPhotoAlbumService.java @@ -1,6 +1,7 @@ package cc.backend.admin.photoAlbum.service; import cc.backend.admin.photoAlbum.dto.AdminPhotoAlbumResponseDTO; +import cc.backend.apiPayLoad.PageResponse; import cc.backend.apiPayLoad.SliceResponse; import cc.backend.apiPayLoad.code.status.ErrorStatus; import cc.backend.apiPayLoad.exception.GeneralException; @@ -31,7 +32,7 @@ public class AdminPhotoAlbumService { private final ImageService imageService; @Transactional(readOnly = true) - public Page getAllPhotoAlbum(Pageable pageable) { + public PageResponse getAllPhotoAlbum(Pageable pageable) { Pageable sortedPageable = PageRequest.of( pageable.getPageNumber(), pageable.getPageSize(), @@ -39,13 +40,23 @@ public Page getAllPhotoAlbum(Pag Page photoAlbums = photoAlbumRepository.findAll(sortedPageable); - return photoAlbums.map(photoAlbum -> AdminPhotoAlbumResponseDTO.SimplePhotoAlbumDTO.builder() - .id(photoAlbum.getId()) - .amateurShowName(photoAlbum.getAmateurShow().getName()) - .uploaderId(photoAlbum.getAmateurShow().getMember().getId()) - .uploaderName(photoAlbum.getAmateurShow().getMember().getName()) - .updatedAt(photoAlbum.getUpdatedAt()) - .build()); + List content = photoAlbums.getContent().stream() + .map(photoAlbum -> AdminPhotoAlbumResponseDTO.SimplePhotoAlbumDTO.builder() + .id(photoAlbum.getId()) + .amateurShowName(photoAlbum.getAmateurShow().getName()) + .uploaderId(photoAlbum.getAmateurShow().getMember().getId()) + .uploaderName(photoAlbum.getAmateurShow().getMember().getName()) + .updatedAt(photoAlbum.getUpdatedAt()) + .build()) + .toList(); + + return new PageResponse<>( + content, + photoAlbums.getNumber(), + photoAlbums.getSize(), + photoAlbums.getTotalElements(), + photoAlbums.getTotalPages() + ); } @Transactional(readOnly = true) @@ -92,12 +103,12 @@ public String deletePhotoAlbum(Long photoAlbumId) { } @Transactional(readOnly = true) - public Page searchPhotoAlbum(String keyword, Pageable pageable) { + public Slice searchPhotoAlbum(String keyword, Pageable pageable) { if (keyword == null || keyword.trim().isEmpty()) { - return Page.empty(pageable); + return new SliceImpl<>(List.of(), pageable, false); } - Page results = photoAlbumRepository.searchPhotoAlbumByKeyword(keyword, pageable); + Slice results = photoAlbumRepository.searchPhotoAlbumByKeyword(keyword, pageable); return results.map(p -> AdminPhotoAlbumResponseDTO.SimplePhotoAlbumDTO.builder() diff --git a/src/main/java/cc/backend/admin/ticket/AdminTicketController.java b/src/main/java/cc/backend/admin/ticket/AdminTicketController.java index 6f0b1918..446e955b 100644 --- a/src/main/java/cc/backend/admin/ticket/AdminTicketController.java +++ b/src/main/java/cc/backend/admin/ticket/AdminTicketController.java @@ -6,6 +6,7 @@ import cc.backend.admin.ticket.dto.TicketDetailResponseDTO; import cc.backend.apiPayLoad.ApiResponse; +import cc.backend.apiPayLoad.PageResponse; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.tags.Tag; @@ -23,7 +24,7 @@ public class AdminTicketController { @GetMapping("/history") @Operation(summary = "관리자 소극장 티켓 관리 - 표") - public ApiResponse> getTicketHistory( + public ApiResponse> getTicketHistory( @Parameter(description = "페이지 번호(0부터)", example = "0") @RequestParam(defaultValue = "0") int page, @@ -47,7 +48,7 @@ public ApiResponse getTicketDetail( @GetMapping("/reservation/history") @Operation(summary = "관리자 예약 내역 관리 - 표", description = "예매 내역을 리스트 형태로 조회합니다.") - public ApiResponse> getReservationHistory( + public ApiResponse> getReservationHistory( @Parameter(description = "페이지 번호(0부터)", example = "0") @RequestParam(defaultValue = "0") int page, @@ -71,7 +72,7 @@ public ApiResponse getReservationDetail( @GetMapping("/refund/history") @Operation(summary = "관리자 환불 내역 관리 - 표", description = "환불 내역을 리스트 형태로 조회합니다.") - public ApiResponse> getRefundHistory( + public ApiResponse> getRefundHistory( @Parameter(description = "페이지 번호(0부터)", example = "0") @RequestParam(defaultValue = "0") int page, diff --git a/src/main/java/cc/backend/admin/ticket/AdminTicketService.java b/src/main/java/cc/backend/admin/ticket/AdminTicketService.java index af70ee86..c497be09 100644 --- a/src/main/java/cc/backend/admin/ticket/AdminTicketService.java +++ b/src/main/java/cc/backend/admin/ticket/AdminTicketService.java @@ -4,6 +4,7 @@ import cc.backend.admin.ticket.dto.RefundListResponseDTO; import cc.backend.admin.ticket.dto.ReservationDetailResponseDTO; import cc.backend.admin.ticket.dto.TicketDetailResponseDTO; +import cc.backend.apiPayLoad.PageResponse; import cc.backend.apiPayLoad.code.status.ErrorStatus; import cc.backend.apiPayLoad.exception.GeneralException; import cc.backend.ticket.entity.RealTicket; @@ -24,7 +25,7 @@ public class AdminTicketService { private final RealTicketRepository realTicketRepository; // == 소극장 티켓 관리 == // - public Page getTicketList(int page, int size, String keyword) { + public PageResponse getTicketList(int page, int size, String keyword) { Sort sort = Sort.by( Sort.Order.desc("id") ); @@ -35,11 +36,9 @@ public Page getTicketList(int page, int size, String ke ? realTicketRepository.findByShowTitleContainingIgnoreCase(keyword, pageable) : realTicketRepository.findAll(pageable); - List content = result.getContent().stream() - .map(this::toTicketDTO) - .toList(); + Page dtoPage = result.map(this::toTicketDTO); - return new PageImpl<>(content, pageable, result.getTotalElements()); + return PageResponse.of(dtoPage); } private TicketDetailResponseDTO toTicketDTO(RealTicket t) { @@ -64,7 +63,7 @@ public TicketDetailResponseDTO getTicketDetail(Long realTicketId) { } // == 예약 내역 관리 == // - public Page getReservationList( + public PageResponse getReservationList( int page, int size, String keyword ) { Sort sort = Sort.by( @@ -78,11 +77,9 @@ public Page getReservationList( ? realTicketRepository.findByShowTitleContainingIgnoreCase(keyword, pageable) : realTicketRepository.findAll(pageable); - List content = result.getContent().stream() - .map(this::toReservationDTO) - .toList(); + Page dtoPage = result.map(this::toReservationDTO); - return new PageImpl<>(content, pageable, result.getTotalElements()); + return PageResponse.of(dtoPage); } private ReservationDetailResponseDTO toReservationDTO(RealTicket t) { @@ -114,7 +111,7 @@ public ReservationDetailResponseDTO getReservationDetail(Long realTicketId) { .build(); } - public Page getRefundList(int page, int size, String keyword) { + public PageResponse getRefundList(int page, int size, String keyword) { Pageable pageable = PageRequest.of( page, size, @@ -128,15 +125,13 @@ public Page getRefundList(int page, int size, String keyw ? realTicketRepository.findByReservationStatusAndShowTitleContainingIgnoreCase(refundStatus, keyword, pageable) : realTicketRepository.findByReservationStatus(refundStatus, pageable); - List content = result.getContent().stream() - .map(this::toRefundDTO) - .toList(); + Page dtoPage = result.map(this::toRefundDTO); - return new PageImpl<>(content, pageable, result.getTotalElements()); + return PageResponse.of(dtoPage); } - private RefundListResponseDTO toRefundDTO(RealTicket t) { - return RefundListResponseDTO.builder() + private RefundListResponseDTO.RefundListDTO toRefundDTO(RealTicket t) { + return RefundListResponseDTO.RefundListDTO.builder() .realTicketId(t.getId()) .username(t.getMember() != null ? t.getMember().getUsername() : null) .memberName(t.getMember() != null ? t.getMember().getName() : null) diff --git a/src/main/java/cc/backend/admin/ticket/dto/RefundListResponseDTO.java b/src/main/java/cc/backend/admin/ticket/dto/RefundListResponseDTO.java index 2d6d3830..40d95753 100644 --- a/src/main/java/cc/backend/admin/ticket/dto/RefundListResponseDTO.java +++ b/src/main/java/cc/backend/admin/ticket/dto/RefundListResponseDTO.java @@ -6,17 +6,20 @@ import lombok.NoArgsConstructor; import java.time.LocalDateTime; +import java.util.List; -@Builder -@AllArgsConstructor -@NoArgsConstructor -@Getter public class RefundListResponseDTO { - private Long realTicketId; - private String username; - private String memberName; - private String showTitle; - private LocalDateTime performanceDateTime; - private LocalDateTime canceledAt; + @Builder + @AllArgsConstructor + @NoArgsConstructor + @Getter + public static class RefundListDTO { + private Long realTicketId; + private String username; + private String memberName; + private String showTitle; + private LocalDateTime performanceDateTime; + private LocalDateTime canceledAt; + } } diff --git a/src/main/java/cc/backend/amateurShow/repository/AmateurShowRepository.java b/src/main/java/cc/backend/amateurShow/repository/AmateurShowRepository.java index 98f628ea..679b057b 100644 --- a/src/main/java/cc/backend/amateurShow/repository/AmateurShowRepository.java +++ b/src/main/java/cc/backend/amateurShow/repository/AmateurShowRepository.java @@ -45,6 +45,14 @@ Slice findByNameOrPerformer( Pageable pageable ); + @Query(""" + select count(s) + from AmateurShow s + where lower(s.name) like lower(concat('%', :kw, '%')) + or lower(s.performerName) like lower(concat('%', :kw, '%')) + """) + long countByNameOrPerformer(@Param("kw") String keyword); + Slice findByMember_IdAndStatusInOrderByIdDesc( Long memberId, diff --git a/src/main/java/cc/backend/apiPayLoad/PageResponse.java b/src/main/java/cc/backend/apiPayLoad/PageResponse.java new file mode 100644 index 00000000..24b1ac71 --- /dev/null +++ b/src/main/java/cc/backend/apiPayLoad/PageResponse.java @@ -0,0 +1,24 @@ +package cc.backend.apiPayLoad; + +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Slice; + +import java.util.List; + +public record PageResponse( + List content, + int pageNumber, + int pageSize, + long totalElements, + int totalPages +) { + public static PageResponse of(Page page) { + return new PageResponse<>( + page.getContent(), + page.getNumber(), + page.getSize(), + page.getTotalElements(), // 전체 요소 수 + page.getTotalPages() // 전체 페이지 수 + ); + } +} \ No newline at end of file diff --git a/src/main/java/cc/backend/apiPayLoad/SliceResponse.java b/src/main/java/cc/backend/apiPayLoad/SliceResponse.java index 484d7705..9c4ef953 100644 --- a/src/main/java/cc/backend/apiPayLoad/SliceResponse.java +++ b/src/main/java/cc/backend/apiPayLoad/SliceResponse.java @@ -17,17 +17,8 @@ public class SliceResponse { @Schema(description = "데이터 리스트") private List content; - @Schema(description = "현재 페이지 번호 (0부터 시작)") - private int page; - @Schema(description = "페이지 크기") - private int size; - - @Schema(description = "첫 번째 페이지 여부") - private boolean first; - - @Schema(description = "마지막 페이지 여부") - private boolean last; + private int pageSize; @Schema(description = "다음 페이지 존재 여부") private boolean hasNext; @@ -35,10 +26,7 @@ public class SliceResponse { public static SliceResponse of(Slice slice) { return SliceResponse.builder() .content(slice.getContent()) - .page(slice.getNumber()) - .size(slice.getSize()) - .first(slice.isFirst()) - .last(slice.isLast()) + .pageSize(slice.getSize()) .hasNext(slice.hasNext()) .build(); } diff --git a/src/main/java/cc/backend/search/SearchController.java b/src/main/java/cc/backend/search/SearchController.java index b63b0f25..99fd993f 100644 --- a/src/main/java/cc/backend/search/SearchController.java +++ b/src/main/java/cc/backend/search/SearchController.java @@ -1,6 +1,7 @@ package cc.backend.search; import cc.backend.apiPayLoad.ApiResponse; +import cc.backend.apiPayLoad.PageResponse; import cc.backend.apiPayLoad.SliceResponse; import cc.backend.member.entity.Member; import cc.backend.search.dto.SearchShowResponseDTO; @@ -33,7 +34,7 @@ public class SearchController { summary = "소극장 공연 검색", description = "공연명, 공연진명을 대상으로 키워드 검색하는 기능." ) - public ApiResponse> searchShows( + public ApiResponse searchShows( @Parameter(description = "작성자 회원 ID", required = true) @AuthenticationPrincipal(expression = "member") Member member, @@ -48,9 +49,6 @@ public ApiResponse> searchShows( ) { Pageable pageable = PageRequest.of(page, size, Sort.by("id").descending()); - Slice slice = - searchService.searchAmateurShows(keyword, pageable); - - return ApiResponse.onSuccess(SliceResponse.of(slice)); + return ApiResponse.onSuccess(searchService.searchAmateurShows(keyword, pageable)); } } diff --git a/src/main/java/cc/backend/search/SearchService.java b/src/main/java/cc/backend/search/SearchService.java index 9fc86840..ecc03dc6 100644 --- a/src/main/java/cc/backend/search/SearchService.java +++ b/src/main/java/cc/backend/search/SearchService.java @@ -2,6 +2,7 @@ import cc.backend.amateurShow.entity.AmateurShow; import cc.backend.amateurShow.repository.AmateurShowRepository; +import cc.backend.apiPayLoad.PageResponse; import cc.backend.search.dto.SearchShowResponseDTO; import io.micrometer.core.instrument.search.Search; import lombok.RequiredArgsConstructor; @@ -19,9 +20,22 @@ public class SearchService { private final AmateurShowRepository amateurShowRepository; - public Slice searchAmateurShows(String keyword, Pageable pageable) { + public SearchShowResponseDTO.SearchShowDTO.SearchShowResultDTO searchAmateurShows(String keyword, Pageable pageable) { String kw = keyword == null ? "" : keyword.trim(); + + //Slice로 조회 Slice slice = amateurShowRepository.findByNameOrPerformer(kw, pageable); - return slice.map(SearchShowResponseDTO::from); + // DTO 변환 + List content = slice.getContent().stream() + .map(SearchShowResponseDTO.SearchShowDTO::from) + .toList(); + + // 전체 건수 조회 (Slice로는 content조회, 결과 개수는 별도 count 쿼리) + long total = amateurShowRepository.countByNameOrPerformer(kw); + + return SearchShowResponseDTO.SearchShowDTO.SearchShowResultDTO.builder() + .searchShowDTOs(content) + .total(total) + .build(); } } diff --git a/src/main/java/cc/backend/search/dto/SearchShowResponseDTO.java b/src/main/java/cc/backend/search/dto/SearchShowResponseDTO.java index 0ee0ca26..520f0af3 100644 --- a/src/main/java/cc/backend/search/dto/SearchShowResponseDTO.java +++ b/src/main/java/cc/backend/search/dto/SearchShowResponseDTO.java @@ -9,34 +9,38 @@ import lombok.Getter; import lombok.NoArgsConstructor; -@Builder -@AllArgsConstructor -@NoArgsConstructor -@Getter -@Schema(description = "검색 결과 - 소극장 공연 상세 응답 DTO") +import java.util.List; + public class SearchShowResponseDTO { - @Schema(description = "공연 ID", example = "1") - private Long showId; - @Schema(description = "공연명", example = "실종") - private String title; + @Builder + @AllArgsConstructor + @NoArgsConstructor + @Getter + @Schema(description = "검색 결과 - 소극장 공연 상세 응답 DTO") + public static class SearchShowDTO{ + @Schema(description = "공연 ID", example = "1") + private Long showId; + + @Schema(description = "공연명", example = "실종") + private String title; - @Schema(description = "공연진명", example = "홍길동") - private String performerName; + @Schema(description = "공연진명", example = "홍길동") + private String performerName; - @Schema(description = "공연장명", example = "문학관 대학로 3층 소극장") - private String hallName; + @Schema(description = "공연장명", example = "문학관 대학로 3층 소극장") + private String hallName; - @Schema(description = "일정 문자열", example = "2024.04.03(목) 19:00 ~ 2024.10.05(토) 14:00") - private String schedule; + @Schema(description = "일정 문자열", example = "2024.04.03(목) 19:00 ~ 2024.10.05(토) 14:00") + private String schedule; - @Schema(description = "포스터 URL") - private String posterImageUrl; + @Schema(description = "포스터 URL") + private String posterImageUrl; - @Schema(description = "공연 상태", example = "판매중") - private String status; + @Schema(description = "공연 상태", example = "판매중") + private String status; - public static SearchShowResponseDTO from(AmateurShow s){ + public static SearchShowDTO from(AmateurShow s){ // String statusLabel = switch (s.getStatus()) { // case APPROVED_ONGOING -> "예매 진행 중"; // case APPROVED_ENDED -> "공연 종료"; @@ -44,19 +48,35 @@ public static SearchShowResponseDTO from(AmateurShow s){ // case WAITING_APPROVAL -> "승인 대기"; // case REJECTED -> "반려"; // }; - String statusLabel = s.getStatus().toString(); - - String schedule = AmateurConverter.mergeSchedule(s.getStart(), s.getEnd()); - return SearchShowResponseDTO.builder() - .showId(s.getId()) - .title(s.getName()) - .performerName(s.getPerformerName()) - .hallName(s.getHallName()) - .schedule(schedule) - .status(statusLabel) - .posterImageUrl(s.getPosterImageUrl()) - .build(); + String statusLabel = s.getStatus().toString(); + + String schedule = AmateurConverter.mergeSchedule(s.getStart(), s.getEnd()); + return SearchShowDTO.builder() + .showId(s.getId()) + .title(s.getName()) + .performerName(s.getPerformerName()) + .hallName(s.getHallName()) + .schedule(schedule) + .status(statusLabel) + .posterImageUrl(s.getPosterImageUrl()) + .build(); + } + + @Builder + @AllArgsConstructor + @NoArgsConstructor + @Getter + @Schema(description = "검색 결과") + public static class SearchShowResultDTO{ + private List searchShowDTOs; + private long total; + } + + } + + + } From 7cdf41327f36af03a5de714f0b77c0cd0132c019 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=A0=95=EC=9C=A4=ED=98=B8?= Date: Mon, 26 Jan 2026 00:52:12 +0900 Subject: [PATCH 5/6] =?UTF-8?q?fix:=20=EC=BF=BC=EB=A6=AC=20=EC=88=98?= =?UTF-8?q?=EC=A0=95=20=EB=B0=8F=20=EC=95=88=EC=93=B0=EB=8A=94=20=ED=95=A8?= =?UTF-8?q?=EC=88=98=20=EC=A0=95=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../board/service/AdminBoardService.java | 7 ++--- .../controller/AdminPhotoAlbumController.java | 4 +-- .../service/AdminPhotoAlbumService.java | 29 +++++++------------ .../repository/AmateurShowRepository.java | 17 +---------- .../java/cc/backend/search/SearchService.java | 14 ++++----- 5 files changed, 23 insertions(+), 48 deletions(-) diff --git a/src/main/java/cc/backend/admin/board/service/AdminBoardService.java b/src/main/java/cc/backend/admin/board/service/AdminBoardService.java index 10a33647..0ff7ab02 100644 --- a/src/main/java/cc/backend/admin/board/service/AdminBoardService.java +++ b/src/main/java/cc/backend/admin/board/service/AdminBoardService.java @@ -45,10 +45,9 @@ public PageResponse getAllBoardsForAdmin(int page, int s ? boardRepository.searchBoardsIncludingDeletedByTitle(keyword, pageable) : boardRepository.findAllBoardsIncludingDeleted(pageable); - List content = boards.getContent().stream() - .map(AdminBoardListResponse::from) - .toList(); - return new PageResponse<>(content, boards.getNumber(), boards.getSize(), boards.getTotalElements(), boards.getTotalPages()); + return PageResponse.of( + boards.map(AdminBoardListResponse::from) + ); } //게시글 상세조회 diff --git a/src/main/java/cc/backend/admin/photoAlbum/controller/AdminPhotoAlbumController.java b/src/main/java/cc/backend/admin/photoAlbum/controller/AdminPhotoAlbumController.java index 92bcd43b..68240039 100644 --- a/src/main/java/cc/backend/admin/photoAlbum/controller/AdminPhotoAlbumController.java +++ b/src/main/java/cc/backend/admin/photoAlbum/controller/AdminPhotoAlbumController.java @@ -52,10 +52,10 @@ public ApiResponse deletePhotoAlbum(@PathVariable Long photoAlbumId){ @GetMapping("/search") @Operation(summary = "관리자페이지 사진첩 검색 API", description = "사진첩 id, 공연 id, 공연제목, 사진첩 내용에 키워드를 포함하면 반환") - public ApiResponse> searchPhotoAlbum( + public ApiResponse> searchPhotoAlbum( @RequestParam String keyword, @ParameterObject Pageable pageable){ - return ApiResponse.onSuccess(SliceResponse.of(adminPhotoAlbumService.searchPhotoAlbum(keyword, pageable))); + return ApiResponse.onSuccess(adminPhotoAlbumService.searchPhotoAlbum(keyword, pageable)); } diff --git a/src/main/java/cc/backend/admin/photoAlbum/service/AdminPhotoAlbumService.java b/src/main/java/cc/backend/admin/photoAlbum/service/AdminPhotoAlbumService.java index 1dec76f8..1ee98ca6 100644 --- a/src/main/java/cc/backend/admin/photoAlbum/service/AdminPhotoAlbumService.java +++ b/src/main/java/cc/backend/admin/photoAlbum/service/AdminPhotoAlbumService.java @@ -40,22 +40,15 @@ public PageResponse getAllPhotoA Page photoAlbums = photoAlbumRepository.findAll(sortedPageable); - List content = photoAlbums.getContent().stream() - .map(photoAlbum -> AdminPhotoAlbumResponseDTO.SimplePhotoAlbumDTO.builder() + return PageResponse.of( + photoAlbums.map(photoAlbum -> AdminPhotoAlbumResponseDTO.SimplePhotoAlbumDTO.builder() .id(photoAlbum.getId()) .amateurShowName(photoAlbum.getAmateurShow().getName()) .uploaderId(photoAlbum.getAmateurShow().getMember().getId()) .uploaderName(photoAlbum.getAmateurShow().getMember().getName()) .updatedAt(photoAlbum.getUpdatedAt()) - .build()) - .toList(); - - return new PageResponse<>( - content, - photoAlbums.getNumber(), - photoAlbums.getSize(), - photoAlbums.getTotalElements(), - photoAlbums.getTotalPages() + .build() + ) ); } @@ -103,21 +96,19 @@ public String deletePhotoAlbum(Long photoAlbumId) { } @Transactional(readOnly = true) - public Slice searchPhotoAlbum(String keyword, Pageable pageable) { - if (keyword == null || keyword.trim().isEmpty()) { - return new SliceImpl<>(List.of(), pageable, false); - } + public PageResponse searchPhotoAlbum(String keyword, Pageable pageable) { + String kw = (keyword == null) ? "" : keyword.trim(); - Slice results = photoAlbumRepository.searchPhotoAlbumByKeyword(keyword, pageable); + Page results = photoAlbumRepository.searchPhotoAlbumByKeyword(kw, pageable); - return results.map(p -> - AdminPhotoAlbumResponseDTO.SimplePhotoAlbumDTO.builder() + return PageResponse.of( + results.map(p -> AdminPhotoAlbumResponseDTO.SimplePhotoAlbumDTO.builder() .id(p.getId()) .amateurShowName(p.getAmateurShow().getName()) .uploaderId(p.getAmateurShow().getMember().getId()) .uploaderName(p.getAmateurShow().getMember().getName()) .updatedAt(p.getUpdatedAt()) - .build() + .build()) ); } } diff --git a/src/main/java/cc/backend/amateurShow/repository/AmateurShowRepository.java b/src/main/java/cc/backend/amateurShow/repository/AmateurShowRepository.java index 679b057b..fc9570f3 100644 --- a/src/main/java/cc/backend/amateurShow/repository/AmateurShowRepository.java +++ b/src/main/java/cc/backend/amateurShow/repository/AmateurShowRepository.java @@ -40,26 +40,13 @@ where lower(s.name) like lower(concat('%', :kw, '%')) or lower(s.performerName) like lower(concat('%', :kw, '%')) order by s.createdAt desc """) - Slice findByNameOrPerformer( + Page findByNameOrPerformer( @Param("kw") String keyword, Pageable pageable ); - @Query(""" - select count(s) - from AmateurShow s - where lower(s.name) like lower(concat('%', :kw, '%')) - or lower(s.performerName) like lower(concat('%', :kw, '%')) - """) - long countByNameOrPerformer(@Param("kw") String keyword); - Slice findByMember_IdAndStatusInOrderByIdDesc( - Long memberId, - Collection statuses, - Pageable pageable - ); - Slice findByMember_IdOrderByIdDesc(Long memberId, Pageable pageable); long countByMember_Id(Long memberId); @@ -84,8 +71,6 @@ List findHotShows( @EntityGraph(attributePaths = {"amateurRounds", "amateurNotice"}, type = EntityGraph.EntityGraphType.FETCH) List findAllWithRounds(); - List findByStatusIn(Collection statuses); - @Modifying(clearAutomatically = true) @Query("UPDATE AmateurShow s SET s.status = :newStatus WHERE s.id IN :ids") void updateStatusByIds(@Param("ids") List ids, @Param("newStatus") AmateurShowStatus newStatus); diff --git a/src/main/java/cc/backend/search/SearchService.java b/src/main/java/cc/backend/search/SearchService.java index ecc03dc6..e5279415 100644 --- a/src/main/java/cc/backend/search/SearchService.java +++ b/src/main/java/cc/backend/search/SearchService.java @@ -6,6 +6,7 @@ import cc.backend.search.dto.SearchShowResponseDTO; import io.micrometer.core.instrument.search.Search; import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Slice; import org.springframework.stereotype.Service; @@ -23,19 +24,18 @@ public class SearchService { public SearchShowResponseDTO.SearchShowDTO.SearchShowResultDTO searchAmateurShows(String keyword, Pageable pageable) { String kw = keyword == null ? "" : keyword.trim(); - //Slice로 조회 - Slice slice = amateurShowRepository.findByNameOrPerformer(kw, pageable); + // Page로 조회 + Page pageResult = amateurShowRepository.findByNameOrPerformer(kw, pageable); + // DTO 변환 - List content = slice.getContent().stream() + List content = pageResult.getContent().stream() .map(SearchShowResponseDTO.SearchShowDTO::from) .toList(); - // 전체 건수 조회 (Slice로는 content조회, 결과 개수는 별도 count 쿼리) - long total = amateurShowRepository.countByNameOrPerformer(kw); - + // 결과 반환 return SearchShowResponseDTO.SearchShowDTO.SearchShowResultDTO.builder() .searchShowDTOs(content) - .total(total) + .total(pageResult.getTotalElements()) // total count 포함 .build(); } } From 644013ebc0a4881415c3aab7c7da42cdad3a56b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=A0=95=EC=9C=A4=ED=98=B8?= Date: Mon, 26 Jan 2026 01:53:31 +0900 Subject: [PATCH 6/6] =?UTF-8?q?fix:=20=EA=B2=80=EC=83=89=20=EA=B2=B0?= =?UTF-8?q?=EA=B3=BC=EC=97=90=EC=84=9C=20=EB=93=B1=EB=A1=9D=EC=8A=B9?= =?UTF-8?q?=EC=9D=B8=EB=90=9C=20=EA=B3=B5=EC=97=B0=EB=A7=8C=20=EB=82=98?= =?UTF-8?q?=EC=98=A4=EB=8F=84=EB=A1=9D=20spec=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../amateurShow/entity/AmateurShow.java | 14 ++------- .../amateurShow/entity/AmateurShowStatus.java | 2 +- .../AmateurShowSpecification.java | 16 ++++++++++ .../cc/backend/search/SearchController.java | 3 +- .../java/cc/backend/search/SearchService.java | 29 ++++++++++++------- .../search/dto/SearchShowResponseDTO.java | 17 +++++------ 6 files changed, 47 insertions(+), 34 deletions(-) diff --git a/src/main/java/cc/backend/amateurShow/entity/AmateurShow.java b/src/main/java/cc/backend/amateurShow/entity/AmateurShow.java index 27736a79..c9cbe85a 100644 --- a/src/main/java/cc/backend/amateurShow/entity/AmateurShow.java +++ b/src/main/java/cc/backend/amateurShow/entity/AmateurShow.java @@ -103,15 +103,6 @@ public class AmateurShow extends BaseEntity { @Builder.Default private List amateurRounds = new ArrayList<>(); - @Builder - public AmateurShow(String name, String detailAddress, LocalDate start, LocalDate end, List photoAlbums) { - this.name = name; - this.detailAddress = detailAddress; - this.start = start; - this.end = end; - this.photoAlbums = photoAlbums; - } - public void updateInfo(AmateurUpdateRequestDTO dto) { if (dto.getName() != null) this.name = dto.getName(); //if (dto.getPlace() != null) this.place = dto.getPlace(); @@ -159,12 +150,11 @@ public void reviseShowInfo(String hashtag, String summary, String account, Strin public void approve(){ this.approvalStatus = ApprovalStatus.APPROVED; - this.status = AmateurShowStatus.YET; + this.status = AmateurShowStatus.YET; //이것도 나중에 수정 필요 (스케쥴러로 만들면 승인할때 따로 설정 필요 X) } public void reject(String rejectReason){ this.approvalStatus = ApprovalStatus.REJECTED; - this.status = AmateurShowStatus.REJECT; + this.status = AmateurShowStatus.REJECT; //이거 수정 필요 this.rejectReason = rejectReason; - } } diff --git a/src/main/java/cc/backend/amateurShow/entity/AmateurShowStatus.java b/src/main/java/cc/backend/amateurShow/entity/AmateurShowStatus.java index cb144bab..ee128d12 100644 --- a/src/main/java/cc/backend/amateurShow/entity/AmateurShowStatus.java +++ b/src/main/java/cc/backend/amateurShow/entity/AmateurShowStatus.java @@ -1,5 +1,5 @@ package cc.backend.amateurShow.entity; - +//스케쥴러로 날짜에 맞게 상태 알아서 바뀌도록 해야할 듯 public enum AmateurShowStatus { YET, // 지금 날짜가 공연 날짜 안에 없을 때 (아직 공연 예정) ONGOING, // 지금 날짜가 공연 날짜 안에 있을 때 (예매 진행 중) diff --git a/src/main/java/cc/backend/amateurShow/repository/specification/AmateurShowSpecification.java b/src/main/java/cc/backend/amateurShow/repository/specification/AmateurShowSpecification.java index ce102a32..3760c762 100644 --- a/src/main/java/cc/backend/amateurShow/repository/specification/AmateurShowSpecification.java +++ b/src/main/java/cc/backend/amateurShow/repository/specification/AmateurShowSpecification.java @@ -8,6 +8,7 @@ import jakarta.persistence.criteria.Join; import jakarta.persistence.criteria.Path; import org.springframework.data.jpa.domain.Specification; +import org.springframework.util.StringUtils; import java.time.LocalDate; @@ -94,4 +95,19 @@ public static Specification hasLastRoundOn(LocalDate today) { return cb.equal(subquery, today); }; } + + public static Specification nameOrPerformerContains(String kw) { + return (root, query, cb) -> { + if (!StringUtils.hasText(kw)) { + return null; // 조건 없음 (where 생략) + } + + String like = "%" + kw.toLowerCase() + "%"; + + return cb.or( + cb.like(cb.lower(root.get("name")), like), + cb.like(cb.lower(root.get("performerName")), like) + ); + }; + } } diff --git a/src/main/java/cc/backend/search/SearchController.java b/src/main/java/cc/backend/search/SearchController.java index 99fd993f..76750bd9 100644 --- a/src/main/java/cc/backend/search/SearchController.java +++ b/src/main/java/cc/backend/search/SearchController.java @@ -47,8 +47,7 @@ public ApiResponse sear @Parameter(description = "페이지 크기", example = "20") @RequestParam(defaultValue = "20") int size ) { - Pageable pageable = PageRequest.of(page, size, Sort.by("id").descending()); - return ApiResponse.onSuccess(searchService.searchAmateurShows(keyword, pageable)); + return ApiResponse.onSuccess(searchService.searchAmateurShows(keyword, page, size)); } } diff --git a/src/main/java/cc/backend/search/SearchService.java b/src/main/java/cc/backend/search/SearchService.java index e5279415..1c9de0b2 100644 --- a/src/main/java/cc/backend/search/SearchService.java +++ b/src/main/java/cc/backend/search/SearchService.java @@ -2,15 +2,16 @@ import cc.backend.amateurShow.entity.AmateurShow; import cc.backend.amateurShow.repository.AmateurShowRepository; +import cc.backend.amateurShow.repository.specification.AmateurShowSpecification; import cc.backend.apiPayLoad.PageResponse; import cc.backend.search.dto.SearchShowResponseDTO; import io.micrometer.core.instrument.search.Search; import lombok.RequiredArgsConstructor; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.Slice; +import org.springframework.data.domain.*; +import org.springframework.data.jpa.domain.Specification; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.StringUtils; import java.util.List; @@ -21,20 +22,28 @@ public class SearchService { private final AmateurShowRepository amateurShowRepository; - public SearchShowResponseDTO.SearchShowDTO.SearchShowResultDTO searchAmateurShows(String keyword, Pageable pageable) { - String kw = keyword == null ? "" : keyword.trim(); + public SearchShowResponseDTO.SearchShowDTO.SearchShowResultDTO searchAmateurShows(String keyword, int page, int size) { + String kw = StringUtils.hasText(keyword) ? keyword.trim() : null; + + Pageable pageable = PageRequest.of( + page, + size, + Sort.by(Sort.Direction.DESC, "createdAt") + ); + + Specification spec = Specification + .where(AmateurShowSpecification.nameOrPerformerContains(kw)) + .and(AmateurShowSpecification.isApproved()); // Page로 조회 - Page pageResult = amateurShowRepository.findByNameOrPerformer(kw, pageable); + Page pageResult = amateurShowRepository.findAll(spec, pageable); // DTO 변환 - List content = pageResult.getContent().stream() - .map(SearchShowResponseDTO.SearchShowDTO::from) - .toList(); + Page dtoPage = pageResult.map(SearchShowResponseDTO.SearchShowDTO::from); // 결과 반환 return SearchShowResponseDTO.SearchShowDTO.SearchShowResultDTO.builder() - .searchShowDTOs(content) + .searchShowDTOs(dtoPage.getContent()) .total(pageResult.getTotalElements()) // total count 포함 .build(); } diff --git a/src/main/java/cc/backend/search/dto/SearchShowResponseDTO.java b/src/main/java/cc/backend/search/dto/SearchShowResponseDTO.java index 520f0af3..ff80908b 100644 --- a/src/main/java/cc/backend/search/dto/SearchShowResponseDTO.java +++ b/src/main/java/cc/backend/search/dto/SearchShowResponseDTO.java @@ -41,15 +41,14 @@ public static class SearchShowDTO{ private String status; public static SearchShowDTO from(AmateurShow s){ -// String statusLabel = switch (s.getStatus()) { -// case APPROVED_ONGOING -> "예매 진행 중"; -// case APPROVED_ENDED -> "공연 종료"; -// case APPROVED_YET -> "예정"; -// case WAITING_APPROVAL -> "승인 대기"; -// case REJECTED -> "반려"; -// }; - String statusLabel = s.getStatus().toString(); - + String statusLabel = + switch (s.getStatus()) { + case ONGOING -> "판매 중"; // 지금 날짜가 공연 날짜 안에 있을 때 (예매 진행 중) + case ENDED -> "공연 종료"; // 지금 날짜가 공연 날짜보다 지났을 때 (공연 종료됨) + case YET -> "공연 예정"; // 지금 날짜가 공연 날짜 안에 없을 때 (아직 공연 예정) + case REJECT -> "X"; + }; +// String statusLabel = s.getStatus().toString(); String schedule = AmateurConverter.mergeSchedule(s.getStart(), s.getEnd()); return SearchShowDTO.builder() .showId(s.getId())