From 709e98f417c90a9ecbfd5f35acdcfae93fd0a78d Mon Sep 17 00:00:00 2001 From: min429 Date: Thu, 29 Aug 2024 00:26:50 +0900 Subject: [PATCH 1/5] =?UTF-8?q?feat:=20=EC=BB=A4=EC=84=9C=20=EA=B8=B0?= =?UTF-8?q?=EB=B0=98=20=ED=8E=98=EC=9D=B4=EC=A7=95=EC=9D=84=20=EC=9C=84?= =?UTF-8?q?=ED=95=B4=20dto=EB=A5=BC=20=EC=88=98=EC=A0=95=20=EB=B0=8F=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80=ED=95=9C=EB=8B=A4.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/dto/FindApplicantDetailsResult.java | 33 +++++++++++---- .../api/dto/FindBoardThumbnailsResult.java | 40 ++++++++++++++----- .../accompany/api/dto/FindSlicesResult.java | 34 ++++++++++++++++ .../domain/accompany/api/dto/PageRequest.java | 40 +++++++++++++++++++ .../accompany/api/dto/PageResponse.java | 3 +- 5 files changed, 132 insertions(+), 18 deletions(-) create mode 100644 src/main/java/com/dnd/accompany/domain/accompany/api/dto/FindSlicesResult.java create mode 100644 src/main/java/com/dnd/accompany/domain/accompany/api/dto/PageRequest.java diff --git a/src/main/java/com/dnd/accompany/domain/accompany/api/dto/FindApplicantDetailsResult.java b/src/main/java/com/dnd/accompany/domain/accompany/api/dto/FindApplicantDetailsResult.java index ef9d713..1fa7309 100644 --- a/src/main/java/com/dnd/accompany/domain/accompany/api/dto/FindApplicantDetailsResult.java +++ b/src/main/java/com/dnd/accompany/domain/accompany/api/dto/FindApplicantDetailsResult.java @@ -5,14 +5,31 @@ import java.util.Arrays; import java.util.List; -public record FindApplicantDetailsResult( - Long requestId, - Long userId, - String nickname, - String provider, - String profileImageUrl, - String imageUrls -) { +import lombok.Getter; +import lombok.experimental.SuperBuilder; + +@Getter +@SuperBuilder +public class FindApplicantDetailsResult extends FindSlicesResult { + private final Long requestId; + private final Long userId; + private final String nickname; + private final String provider; + private final String profileImageUrl; + private final String imageUrls; + + public FindApplicantDetailsResult(Long requestId, Long userId, String nickname, String provider, + String profileImageUrl, String imageUrls, String cursor) { + super(cursor); + + this.requestId = requestId; + this.userId = userId; + this.nickname = nickname; + this.provider = provider; + this.profileImageUrl = profileImageUrl; + this.imageUrls = imageUrls; + } + public List getImageUrlsAsList() { if (imageUrls == null || imageUrls.isEmpty()) { return emptyList(); diff --git a/src/main/java/com/dnd/accompany/domain/accompany/api/dto/FindBoardThumbnailsResult.java b/src/main/java/com/dnd/accompany/domain/accompany/api/dto/FindBoardThumbnailsResult.java index ae02b09..36e6ddd 100644 --- a/src/main/java/com/dnd/accompany/domain/accompany/api/dto/FindBoardThumbnailsResult.java +++ b/src/main/java/com/dnd/accompany/domain/accompany/api/dto/FindBoardThumbnailsResult.java @@ -8,15 +8,37 @@ import com.dnd.accompany.domain.accompany.entity.enums.Region; -public record FindBoardThumbnailsResult( - Long requestId, - String title, - Region region, - LocalDateTime startDate, - LocalDateTime endDate, - String nickname, - String imageUrls -) { +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.experimental.SuperBuilder; + +@Getter +@SuperBuilder +public class FindBoardThumbnailsResult extends FindSlicesResult{ + private final Long requestId; + private final String title; + private final Region region; + private final LocalDateTime startDate; + private final LocalDateTime endDate; + private final String nickname; + private final String imageUrls; + + public FindBoardThumbnailsResult(Long requestId, String title, Region region, + LocalDateTime startDate, LocalDateTime endDate, + String nickname, String imageUrls, String cursor) { + super(cursor); + + this.requestId = requestId; + this.title = title; + this.region = region; + this.startDate = startDate; + this.endDate = endDate; + this.nickname = nickname; + this.imageUrls = imageUrls; + } + public List getImageUrlsAsList() { if (imageUrls == null || imageUrls.isEmpty()) { return emptyList(); diff --git a/src/main/java/com/dnd/accompany/domain/accompany/api/dto/FindSlicesResult.java b/src/main/java/com/dnd/accompany/domain/accompany/api/dto/FindSlicesResult.java new file mode 100644 index 0000000..5aa7258 --- /dev/null +++ b/src/main/java/com/dnd/accompany/domain/accompany/api/dto/FindSlicesResult.java @@ -0,0 +1,34 @@ +package com.dnd.accompany.domain.accompany.api.dto; + +import java.util.List; + +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Slice; +import org.springframework.data.domain.SliceImpl; + +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.experimental.SuperBuilder; + +@Getter +@AllArgsConstructor(access = AccessLevel.PROTECTED) +@SuperBuilder +public abstract class FindSlicesResult { + private final String cursor; + + public static String getLastCursor(List result) { + return result.get(result.size() - 1).getCursor(); + } + + public static Slice createSlice(int size, List content) { + boolean hasNext = content.size() > size; + + if (hasNext) { + content.remove(content.size() - 1); + } + + return new SliceImpl<>(content, PageRequest.of(0, size), hasNext); + } +} diff --git a/src/main/java/com/dnd/accompany/domain/accompany/api/dto/PageRequest.java b/src/main/java/com/dnd/accompany/domain/accompany/api/dto/PageRequest.java new file mode 100644 index 0000000..ad4b2a2 --- /dev/null +++ b/src/main/java/com/dnd/accompany/domain/accompany/api/dto/PageRequest.java @@ -0,0 +1,40 @@ +package com.dnd.accompany.domain.accompany.api.dto; + +import java.time.LocalDateTime; + +import org.springframework.boot.context.properties.bind.DefaultValue; +import org.springframework.lang.Nullable; + +import com.querydsl.core.BooleanBuilder; +import com.querydsl.core.types.dsl.DateTimePath; +import com.querydsl.core.types.dsl.Expressions; +import com.querydsl.core.types.dsl.NumberPath; +import com.querydsl.core.types.dsl.NumberTemplate; +import com.querydsl.core.types.dsl.StringTemplate; + +public record PageRequest( + String cursor, + Integer size +) { + + public PageRequest { + if (size == null) { + size = 10; + } + } + + public static BooleanBuilder cursorCondition(String cursor, DateTimePath updatedAt, NumberPath id) { + BooleanBuilder builder = new BooleanBuilder(); + + if (cursor == null) return builder; + + StringTemplate nextCursor = Expressions.stringTemplate( + "CONCAT(DATE_FORMAT({0}, '%Y%m%d%H%i%S'), LPAD(CAST({1} AS STRING), 6, '0'))", + updatedAt, + id + ); + builder.and(nextCursor.lt(cursor)); + + return builder; + } +} diff --git a/src/main/java/com/dnd/accompany/domain/accompany/api/dto/PageResponse.java b/src/main/java/com/dnd/accompany/domain/accompany/api/dto/PageResponse.java index 556304e..70c2d8f 100644 --- a/src/main/java/com/dnd/accompany/domain/accompany/api/dto/PageResponse.java +++ b/src/main/java/com/dnd/accompany/domain/accompany/api/dto/PageResponse.java @@ -4,6 +4,7 @@ public record PageResponse( boolean hasNext, - List data + List data, + String cursor ) { } \ No newline at end of file From 0bc227521279cabe83627c09faf8a45bfa6a41ef Mon Sep 17 00:00:00 2001 From: min429 Date: Thu, 29 Aug 2024 00:28:50 +0900 Subject: [PATCH 2/5] =?UTF-8?q?feat:=20=EC=BB=A4=EC=84=9C=20=EA=B8=B0?= =?UTF-8?q?=EB=B0=98=20=ED=8E=98=EC=9D=B4=EC=A7=95=EC=9D=84=20=EC=9C=84?= =?UTF-8?q?=ED=95=B4=20=EA=B4=80=EB=A0=A8=20controller,=20service=EB=A5=BC?= =?UTF-8?q?=20=EC=88=98=EC=A0=95=ED=95=9C=EB=8B=A4.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/AccompanyBoardController.java | 15 +++---- .../api/AccompanyRequestController.java | 18 ++++---- .../service/AccompanyBoardService.java | 29 ++++++------- .../service/AccompanyRequestService.java | 42 ++++++++++--------- 4 files changed, 50 insertions(+), 54 deletions(-) diff --git a/src/main/java/com/dnd/accompany/domain/accompany/api/AccompanyBoardController.java b/src/main/java/com/dnd/accompany/domain/accompany/api/AccompanyBoardController.java index c97fe67..88f17fc 100644 --- a/src/main/java/com/dnd/accompany/domain/accompany/api/AccompanyBoardController.java +++ b/src/main/java/com/dnd/accompany/domain/accompany/api/AccompanyBoardController.java @@ -18,6 +18,7 @@ import com.dnd.accompany.domain.accompany.api.dto.CreateAccompanyBoardRequest; import com.dnd.accompany.domain.accompany.api.dto.CreateAccompanyBoardResponse; import com.dnd.accompany.domain.accompany.api.dto.CreateAccompanyRequest; +import com.dnd.accompany.domain.accompany.api.dto.PageRequest; import com.dnd.accompany.domain.accompany.api.dto.PageResponse; import com.dnd.accompany.domain.accompany.api.dto.ReadAccompanyBoardResponse; import com.dnd.accompany.domain.accompany.entity.enums.Region; @@ -50,13 +51,11 @@ public ResponseEntity create( } @Operation(summary = "동행글 목록 조회") - @GetMapping + @PostMapping("/all") public ResponseEntity> readAll( - @PageableDefault( - sort = {"updatedAt", "createdAt"}, - direction = Sort.Direction.DESC) Pageable pageable, + @RequestBody @Valid PageRequest request, @RequestParam(value = "region", required = false) Region region) { - return ResponseEntity.ok(accompanyBoardService.getAllBoards(pageable, region)); + return ResponseEntity.ok(accompanyBoardService.getAllBoards(request, region)); } @Operation(summary = "동행글 상세 조회") @@ -95,10 +94,8 @@ public ResponseEntity remove( @Operation(summary = "동행 기록 조회") @GetMapping("/records") public ResponseEntity> readAllRecords( - @PageableDefault( - sort = {"createdAt"}, - direction = Sort.Direction.DESC) Pageable pageable, + @RequestBody @Valid PageRequest request, @AuthenticationPrincipal JwtAuthentication user) { - return ResponseEntity.ok(accompanyBoardService.getAllRecords(pageable, user.getId())); + return ResponseEntity.ok(accompanyBoardService.getAllRecords(request, user.getId())); } } diff --git a/src/main/java/com/dnd/accompany/domain/accompany/api/AccompanyRequestController.java b/src/main/java/com/dnd/accompany/domain/accompany/api/AccompanyRequestController.java index 86f8310..64994c1 100644 --- a/src/main/java/com/dnd/accompany/domain/accompany/api/AccompanyRequestController.java +++ b/src/main/java/com/dnd/accompany/domain/accompany/api/AccompanyRequestController.java @@ -7,10 +7,11 @@ import org.springframework.security.core.annotation.AuthenticationPrincipal; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; +import com.dnd.accompany.domain.accompany.api.dto.PageRequest; import com.dnd.accompany.domain.accompany.api.dto.PageResponse; import com.dnd.accompany.domain.accompany.api.dto.ReadAccompanyResponse; import com.dnd.accompany.domain.accompany.api.dto.ReceivedAccompany; @@ -20,9 +21,8 @@ import com.dnd.accompany.domain.auth.dto.jwt.JwtAuthentication; import io.swagger.v3.oas.annotations.Operation; -import io.swagger.v3.oas.annotations.Parameter; -import io.swagger.v3.oas.annotations.enums.ParameterIn; import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; @Tag(name = "AccompanyRequest") @@ -37,21 +37,17 @@ public class AccompanyRequestController { @Operation(summary = "보낸 동행 신청서 목록 조회") @GetMapping("/sended") public ResponseEntity> readAllSended( - @PageableDefault( - sort = {"updatedAt", "createdAt"}, - direction = Sort.Direction.DESC) Pageable pageable, + @RequestBody @Valid PageRequest request, @AuthenticationPrincipal JwtAuthentication user) { - return ResponseEntity.ok(accompanyRequestService.getAllSendedAccompanies(pageable, user.getId())); + return ResponseEntity.ok(accompanyRequestService.getAllSendedAccompanies(request, user.getId())); } @Operation(summary = "받은 동행 신청서 목록 조회") @GetMapping("/received") public ResponseEntity> readAllReceived( - @PageableDefault( - sort = {"updatedAt", "createdAt"}, - direction = Sort.Direction.DESC) Pageable pageable, + @RequestBody @Valid PageRequest request, @AuthenticationPrincipal JwtAuthentication user) { - return ResponseEntity.ok(accompanyRequestService.getAllReceivedAccompanies(pageable, user.getId())); + return ResponseEntity.ok(accompanyRequestService.getAllReceivedAccompanies(request, user.getId())); } @Operation(summary = "동행 신청서 조회") diff --git a/src/main/java/com/dnd/accompany/domain/accompany/service/AccompanyBoardService.java b/src/main/java/com/dnd/accompany/domain/accompany/service/AccompanyBoardService.java index f8cb6ea..a6a3ca6 100644 --- a/src/main/java/com/dnd/accompany/domain/accompany/service/AccompanyBoardService.java +++ b/src/main/java/com/dnd/accompany/domain/accompany/service/AccompanyBoardService.java @@ -1,9 +1,9 @@ package com.dnd.accompany.domain.accompany.service; +import static com.dnd.accompany.domain.accompany.api.dto.FindBoardThumbnailsResult.*; import static com.dnd.accompany.domain.accompany.entity.AccompanyBoard.*; import java.util.List; -import java.util.Optional; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Slice; @@ -14,6 +14,7 @@ import com.dnd.accompany.domain.accompany.api.dto.CreateAccompanyBoardRequest; import com.dnd.accompany.domain.accompany.api.dto.FindBoardThumbnailResult; import com.dnd.accompany.domain.accompany.api.dto.FindBoardThumbnailsResult; +import com.dnd.accompany.domain.accompany.api.dto.PageRequest; import com.dnd.accompany.domain.accompany.api.dto.PageResponse; import com.dnd.accompany.domain.accompany.entity.AccompanyBoard; import com.dnd.accompany.domain.accompany.entity.enums.Region; @@ -32,7 +33,7 @@ public class AccompanyBoardService { @Transactional public AccompanyBoard save(CreateAccompanyBoardRequest request) { return accompanyBoardRepository.save( - builder() + AccompanyBoard.builder() .title(request.title()) .content(request.content()) .region(request.region()) @@ -49,21 +50,21 @@ public AccompanyBoard save(CreateAccompanyBoardRequest request) { } @Transactional(readOnly = true) - public PageResponse getAllBoards(Pageable pageable, Region region) { - Slice sliceResult = accompanyBoardRepository.findBoardThumbnails(pageable, region); + public PageResponse getAllBoards(PageRequest request, Region region) { + Slice sliceResult = accompanyBoardRepository.findBoardThumbnails(request.cursor(), request.size(), region); List thumbnails = getBoardThumbnails(sliceResult.getContent()); - return new PageResponse<>(sliceResult.hasNext(), thumbnails); + return new PageResponse<>(sliceResult.hasNext(), thumbnails, getLastCursor(sliceResult.getContent())); } @Transactional(readOnly = true) - public PageResponse getAllRecords(Pageable pageable, Long userId) { - Slice sliceResult = accompanyBoardRepository.findBoardThumbnailsByUserId(pageable, userId); + public PageResponse getAllRecords(PageRequest request, Long userId) { + Slice sliceResult = accompanyBoardRepository.findBoardThumbnailsByUserId(request.cursor(), request.size(), userId); List thumbnails = getBoardThumbnails(sliceResult.getContent()); - return new PageResponse<>(sliceResult.hasNext(), thumbnails); + return new PageResponse<>(sliceResult.hasNext(), thumbnails, getLastCursor(sliceResult.getContent())); } @@ -73,12 +74,12 @@ public PageResponse getAllRecords(Pageable pageable, Lo private List getBoardThumbnails(List results) { List thumbnails = results.stream() .map(result -> AccompanyBoardThumbnail.builder() - .boardId(result.requestId()) - .title(result.title()) - .region(result.region()) - .startDate(result.startDate()) - .endDate(result.endDate()) - .nickname(result.nickname()) + .boardId(result.getRequestId()) + .title(result.getTitle()) + .region(result.getRegion()) + .startDate(result.getStartDate()) + .endDate(result.getEndDate()) + .nickname(result.getNickname()) .imageUrls(result.getImageUrlsAsList()) .build()) .toList(); diff --git a/src/main/java/com/dnd/accompany/domain/accompany/service/AccompanyRequestService.java b/src/main/java/com/dnd/accompany/domain/accompany/service/AccompanyRequestService.java index b7c2dae..092a7c9 100644 --- a/src/main/java/com/dnd/accompany/domain/accompany/service/AccompanyRequestService.java +++ b/src/main/java/com/dnd/accompany/domain/accompany/service/AccompanyRequestService.java @@ -1,9 +1,9 @@ package com.dnd.accompany.domain.accompany.service; +import static com.dnd.accompany.domain.accompany.api.dto.FindApplicantDetailsResult.*; import static com.dnd.accompany.domain.accompany.entity.enums.RequestState.*; import static java.util.stream.Collectors.*; -import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Set; @@ -18,6 +18,8 @@ import com.dnd.accompany.domain.accompany.api.dto.CreateAccompanyRequest; import com.dnd.accompany.domain.accompany.api.dto.FindBoardThumbnailsResult; import com.dnd.accompany.domain.accompany.api.dto.FindApplicantDetailsResult; +import com.dnd.accompany.domain.accompany.api.dto.FindSlicesResult; +import com.dnd.accompany.domain.accompany.api.dto.PageRequest; import com.dnd.accompany.domain.accompany.api.dto.PageResponse; import com.dnd.accompany.domain.accompany.api.dto.ReceivedAccompany; import com.dnd.accompany.domain.accompany.api.dto.SendedAccompany; @@ -52,20 +54,20 @@ public void save(Long userId, CreateAccompanyRequest request) { } @Transactional(readOnly = true) - public PageResponse getAllReceivedAccompanies(Pageable pageable, Long hostId){ - Slice sliceResult = accompanyRequestRepository.findApplicantDetails(pageable, hostId); + public PageResponse getAllReceivedAccompanies(PageRequest request, Long hostId){ + Slice sliceResult = accompanyRequestRepository.findApplicantDetails(request.cursor(), request.size(), hostId); Set userIds = getUserIds(sliceResult); Map userProfileMap = getUserProfileMap(userIds); List receivedAccompanies = getReceivedAccompanies(sliceResult.getContent(), userProfileMap); - return new PageResponse<>(sliceResult.hasNext(), receivedAccompanies); + return new PageResponse<>(sliceResult.hasNext(), receivedAccompanies, FindSlicesResult.getLastCursor(sliceResult.getContent())); } private Set getUserIds(Slice results) { return results.getContent().stream() - .map(result -> result.userId()) + .map(result -> result.getUserId()) .collect(toSet()); } @@ -80,14 +82,14 @@ private Map getUserProfileMap(Set userIds) { private static List getReceivedAccompanies(List results, Map userProfileMap) { return results.stream() .map(result -> { - UserProfile userProfile = userProfileMap.get(result.userId()); + UserProfile userProfile = userProfileMap.get(result.getUserId()); return ReceivedAccompany.builder() - .requestId(result.requestId()) - .userId(result.userId()) - .nickname(result.nickname()) - .provider(result.provider()) - .profileImageUrl(result.profileImageUrl()) + .requestId(result.getRequestId()) + .userId(result.getUserId()) + .nickname(result.getNickname()) + .provider(result.getProvider()) + .profileImageUrl(result.getProfileImageUrl()) .description(userProfile.getDescription()) .gender(userProfile.getGender()) .birthYear(userProfile.getBirthYear()) @@ -103,12 +105,12 @@ private static List getReceivedAccompanies(List getAllSendedAccompanies(Pageable pageable, Long applicantId){ - Slice sliceResult = accompanyRequestRepository.findBoardThumbnails(pageable, applicantId); + public PageResponse getAllSendedAccompanies(PageRequest request, Long applicantId){ + Slice sliceResult = accompanyRequestRepository.findBoardThumbnails(request.cursor(), request.size(), applicantId); List sendedAccompanies = getSendedAccompanies(sliceResult.getContent()); - return new PageResponse<>(sliceResult.hasNext(), sendedAccompanies); + return new PageResponse<>(sliceResult.hasNext(), sendedAccompanies, getLastCursor(sliceResult.getContent())); } /** @@ -117,12 +119,12 @@ public PageResponse getAllSendedAccompanies(Pageable pageable, private static List getSendedAccompanies(List results) { List sendedAccompanies = results.stream() .map(result -> SendedAccompany.builder() - .requestId(result.requestId()) - .title(result.title()) - .region(result.region()) - .startDate(result.startDate()) - .endDate(result.endDate()) - .nickname(result.nickname()) + .requestId(result.getRequestId()) + .title(result.getTitle()) + .region(result.getRegion()) + .startDate(result.getStartDate()) + .endDate(result.getEndDate()) + .nickname(result.getNickname()) .imageUrls(result.getImageUrlsAsList()) .build()) .toList(); From 4e383db5104a5ec61e5e16ff050753011dc30669 Mon Sep 17 00:00:00 2001 From: min429 Date: Thu, 29 Aug 2024 00:32:08 +0900 Subject: [PATCH 3/5] =?UTF-8?q?feat:=20=EC=BB=A4=EC=84=9C=20=EA=B8=B0?= =?UTF-8?q?=EB=B0=98=20=ED=8E=98=EC=9D=B4=EC=A7=95=20=EB=B0=A9=EC=8B=9D?= =?UTF-8?q?=EC=9C=BC=EB=A1=9C=20=EC=BF=BC=EB=A6=AC=EB=A5=BC=20=EC=9E=AC?= =?UTF-8?q?=EA=B5=AC=EC=84=B1=ED=95=9C=EB=8B=A4.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../AccompanyBoardRepositoryImpl.java | 37 ++++++++++++++----- .../AccompanyRequestRepositoryImpl.java | 34 ++++++++++++----- .../AccompanyBoardRepositoryCustom.java | 4 +- .../AccompanyRequestRepositoryCustom.java | 4 +- 4 files changed, 55 insertions(+), 24 deletions(-) diff --git a/src/main/java/com/dnd/accompany/domain/accompany/infrastructure/querydsl/AccompanyBoardRepositoryImpl.java b/src/main/java/com/dnd/accompany/domain/accompany/infrastructure/querydsl/AccompanyBoardRepositoryImpl.java index 10cf31f..ef0d19e 100644 --- a/src/main/java/com/dnd/accompany/domain/accompany/infrastructure/querydsl/AccompanyBoardRepositoryImpl.java +++ b/src/main/java/com/dnd/accompany/domain/accompany/infrastructure/querydsl/AccompanyBoardRepositoryImpl.java @@ -1,19 +1,24 @@ package com.dnd.accompany.domain.accompany.infrastructure.querydsl; +import static com.dnd.accompany.domain.accompany.api.dto.FindSlicesResult.*; +import static com.dnd.accompany.domain.accompany.api.dto.PageRequest.*; import static com.dnd.accompany.domain.accompany.entity.QAccompanyBoard.*; import static com.dnd.accompany.domain.accompany.entity.QAccompanyImage.*; +import static com.dnd.accompany.domain.accompany.entity.QAccompanyRequest.*; import static com.dnd.accompany.domain.accompany.entity.QAccompanyUser.*; import static com.dnd.accompany.domain.accompany.entity.enums.Role.*; import static com.dnd.accompany.domain.user.entity.QUser.*; import java.util.List; +import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Slice; import org.springframework.data.domain.SliceImpl; import org.springframework.stereotype.Repository; import com.dnd.accompany.domain.accompany.api.dto.FindBoardThumbnailsResult; +import com.dnd.accompany.domain.accompany.api.dto.FindSlicesResult; import com.dnd.accompany.domain.accompany.entity.enums.Region; import com.dnd.accompany.domain.accompany.infrastructure.querydsl.interfaces.AccompanyBoardRepositoryCustom; import com.querydsl.core.BooleanBuilder; @@ -44,7 +49,7 @@ private BooleanBuilder isRegion(Region region) { } @Override - public Slice findBoardThumbnails(Pageable pageable, Region region) { + public Slice findBoardThumbnails(String cursor, int size, Region region) { List content = queryFactory .select(Projections.constructor(FindBoardThumbnailsResult.class, accompanyBoard.id, @@ -53,18 +58,24 @@ public Slice findBoardThumbnails(Pageable pageable, R accompanyBoard.startDate, accompanyBoard.endDate, user.nickname, - Expressions.stringTemplate("GROUP_CONCAT(DISTINCT {0})", accompanyImage.imageUrl))) + Expressions.stringTemplate("GROUP_CONCAT(DISTINCT {0})", accompanyImage.imageUrl), + Expressions.stringTemplate( + "CONCAT(DATE_FORMAT({0}, '%Y%m%d%H%i%S'), LPAD(CAST({1} AS STRING), 6, '0'))", + accompanyBoard.updatedAt, + accompanyBoard.id + )) + ) .from(accompanyUser) .join(accompanyUser.accompanyBoard, accompanyBoard) .join(accompanyUser.user, user) .leftJoin(accompanyImage).on(accompanyImage.accompanyBoard.id.eq(accompanyBoard.id)) .where(isHost()) .where(isRegion(region)) + .where(cursorCondition(cursor, accompanyBoard.updatedAt, accompanyBoard.id)) .groupBy(accompanyBoard.id, accompanyBoard.title, accompanyBoard.region, accompanyBoard.startDate, accompanyBoard.endDate, user.nickname) - .orderBy(accompanyBoard.updatedAt.desc(), accompanyBoard.createdAt.desc()) - .offset(pageable.getOffset()) - .limit(pageable.getPageSize() + 1) + .orderBy(accompanyBoard.updatedAt.desc(), accompanyBoard.id.desc()) + .limit(size + 1) .fetch(); boolean hasNext = content.size() > pageable.getPageSize(); @@ -77,7 +88,7 @@ public Slice findBoardThumbnails(Pageable pageable, R } @Override - public Slice findBoardThumbnailsByUserId(Pageable pageable, Long userId) { + public Slice findBoardThumbnailsByUserId(String cursor, int size, Long userId) { List content = queryFactory .select(Projections.constructor(FindBoardThumbnailsResult.class, accompanyBoard.id, @@ -86,18 +97,24 @@ public Slice findBoardThumbnailsByUserId(Pageable pag accompanyBoard.startDate, accompanyBoard.endDate, user.nickname, - Expressions.stringTemplate("GROUP_CONCAT(DISTINCT {0})", accompanyImage.imageUrl))) + Expressions.stringTemplate("GROUP_CONCAT(DISTINCT {0})", accompanyImage.imageUrl), + Expressions.stringTemplate( + "CONCAT(DATE_FORMAT({0}, '%Y%m%d%H%i%S'), LPAD(CAST({1} AS STRING), 6, '0'))", + accompanyUser.updatedAt, + accompanyUser.id + )) + ) .from(accompanyUser) .join(accompanyUser.accompanyBoard, accompanyBoard) .join(accompanyUser.user, user) .leftJoin(accompanyImage).on(accompanyImage.accompanyBoard.id.eq(accompanyBoard.id)) .where(accompanyUser.user.id.eq(userId)) + .where(cursorCondition(cursor, accompanyUser.updatedAt, accompanyUser.id)) .groupBy(accompanyBoard.id, accompanyBoard.title, accompanyBoard.region, accompanyBoard.startDate, accompanyBoard.endDate, user.nickname, accompanyUser.id) - .orderBy(accompanyUser.createdAt.desc()) - .offset(pageable.getOffset()) - .limit(pageable.getPageSize() + 1) + .orderBy(accompanyUser.updatedAt.desc(), accompanyUser.id.desc()) + .limit(size + 1) .fetch(); boolean hasNext = content.size() > pageable.getPageSize(); diff --git a/src/main/java/com/dnd/accompany/domain/accompany/infrastructure/querydsl/AccompanyRequestRepositoryImpl.java b/src/main/java/com/dnd/accompany/domain/accompany/infrastructure/querydsl/AccompanyRequestRepositoryImpl.java index 0d8a23d..e2a1fa4 100644 --- a/src/main/java/com/dnd/accompany/domain/accompany/infrastructure/querydsl/AccompanyRequestRepositoryImpl.java +++ b/src/main/java/com/dnd/accompany/domain/accompany/infrastructure/querydsl/AccompanyRequestRepositoryImpl.java @@ -1,5 +1,7 @@ package com.dnd.accompany.domain.accompany.infrastructure.querydsl; +import static com.dnd.accompany.domain.accompany.api.dto.FindSlicesResult.*; +import static com.dnd.accompany.domain.accompany.api.dto.PageRequest.*; import static com.dnd.accompany.domain.accompany.entity.QAccompanyBoard.*; import static com.dnd.accompany.domain.accompany.entity.QAccompanyImage.*; import static com.dnd.accompany.domain.accompany.entity.QAccompanyRequest.*; @@ -37,7 +39,7 @@ private BooleanExpression isHost() { } @Override - public Slice findBoardThumbnails(Pageable pageable, Long applicantId) { + public Slice findBoardThumbnails(String cursor, int size, Long applicantId) { List content = queryFactory .select(Projections.constructor(FindBoardThumbnailsResult.class, accompanyRequest.id, @@ -46,7 +48,13 @@ public Slice findBoardThumbnails(Pageable pageable, L accompanyBoard.startDate, accompanyBoard.endDate, user.nickname, - Expressions.stringTemplate("GROUP_CONCAT(DISTINCT {0})", accompanyImage.imageUrl))) + Expressions.stringTemplate("GROUP_CONCAT(DISTINCT {0})", accompanyImage.imageUrl), + Expressions.stringTemplate( + "CONCAT(DATE_FORMAT({0}, '%Y%m%d%H%i%S'), LPAD(CAST({1} AS STRING), 6, '0'))", + accompanyRequest.updatedAt, + accompanyRequest.id + )) + ) .from(accompanyUser) .join(accompanyUser.accompanyBoard, accompanyBoard) .join(accompanyUser.user, user) @@ -55,11 +63,11 @@ public Slice findBoardThumbnails(Pageable pageable, L .where(isHost()) .where(accompanyRequest.user.id.eq(applicantId)) .where(accompanyRequest.requestState.eq(HOLDING)) + .where(cursorCondition(cursor, accompanyRequest.updatedAt, accompanyRequest.id)) .groupBy(accompanyRequest.id, accompanyBoard.title, accompanyBoard.region, accompanyBoard.startDate, accompanyBoard.endDate, user.nickname) - .orderBy(accompanyRequest.updatedAt.desc(), accompanyRequest.createdAt.desc()) - .offset(pageable.getOffset()) - .limit(pageable.getPageSize() + 1) + .orderBy(accompanyRequest.updatedAt.desc(), accompanyRequest.id.desc()) + .limit(size + 1) .fetch(); boolean hasNext = content.size() > pageable.getPageSize(); @@ -72,7 +80,7 @@ public Slice findBoardThumbnails(Pageable pageable, L } @Override - public Slice findApplicantDetails(Pageable pageable, Long hostId) { + public Slice findApplicantDetails(String cursor, int size, Long hostId) { List content = queryFactory .select(Projections.constructor(FindApplicantDetailsResult.class, accompanyRequest.id, @@ -80,7 +88,13 @@ public Slice findApplicantDetails(Pageable pageable, user.nickname, user.provider, user.profileImageUrl, - Expressions.stringTemplate("GROUP_CONCAT(DISTINCT {0})", userImage.imageUrl))) + Expressions.stringTemplate("GROUP_CONCAT(DISTINCT {0})", userImage.imageUrl), + Expressions.stringTemplate( + "CONCAT(DATE_FORMAT({0}, '%Y%m%d%H%i%S'), LPAD(CAST({1} AS STRING), 6, '0'))", + accompanyRequest.updatedAt, + accompanyRequest.id + )) + ) .from(accompanyUser) .join(accompanyUser.accompanyBoard, accompanyBoard) .join(accompanyRequest).on(accompanyRequest.accompanyBoard.id.eq(accompanyBoard.id)) @@ -89,11 +103,11 @@ public Slice findApplicantDetails(Pageable pageable, .where(isHost()) .where(accompanyUser.user.id.eq(hostId)) .where(accompanyRequest.requestState.eq(HOLDING)) + .where(cursorCondition(cursor, accompanyRequest.updatedAt, accompanyRequest.id)) .groupBy(accompanyRequest.id, user.id, user.nickname, user.provider, user.profileImageUrl) - .orderBy(accompanyRequest.updatedAt.desc(), accompanyRequest.createdAt.desc()) - .offset(pageable.getOffset()) - .limit(pageable.getPageSize() + 1) + .orderBy(accompanyRequest.updatedAt.desc(), accompanyRequest.id.desc()) + .limit(size + 1) .fetch(); boolean hasNext = content.size() > pageable.getPageSize(); diff --git a/src/main/java/com/dnd/accompany/domain/accompany/infrastructure/querydsl/interfaces/AccompanyBoardRepositoryCustom.java b/src/main/java/com/dnd/accompany/domain/accompany/infrastructure/querydsl/interfaces/AccompanyBoardRepositoryCustom.java index 6c11be9..660ba68 100644 --- a/src/main/java/com/dnd/accompany/domain/accompany/infrastructure/querydsl/interfaces/AccompanyBoardRepositoryCustom.java +++ b/src/main/java/com/dnd/accompany/domain/accompany/infrastructure/querydsl/interfaces/AccompanyBoardRepositoryCustom.java @@ -7,9 +7,9 @@ import com.dnd.accompany.domain.accompany.entity.enums.Region; public interface AccompanyBoardRepositoryCustom { - Slice findBoardThumbnails(Pageable pageable, Region region); + Slice findBoardThumbnails(String cursor, int size, Region region); - Slice findBoardThumbnailsByUserId(Pageable pageable, Long userId); + Slice findBoardThumbnailsByUserId(String cursor, int size, Long userId); boolean isHostOfBoard(Long userId, Long boardId); } diff --git a/src/main/java/com/dnd/accompany/domain/accompany/infrastructure/querydsl/interfaces/AccompanyRequestRepositoryCustom.java b/src/main/java/com/dnd/accompany/domain/accompany/infrastructure/querydsl/interfaces/AccompanyRequestRepositoryCustom.java index 46ae14b..78eb92e 100644 --- a/src/main/java/com/dnd/accompany/domain/accompany/infrastructure/querydsl/interfaces/AccompanyRequestRepositoryCustom.java +++ b/src/main/java/com/dnd/accompany/domain/accompany/infrastructure/querydsl/interfaces/AccompanyRequestRepositoryCustom.java @@ -7,7 +7,7 @@ import com.dnd.accompany.domain.accompany.api.dto.FindApplicantDetailsResult; public interface AccompanyRequestRepositoryCustom { - Slice findBoardThumbnails(Pageable pageable, Long applicantId); + Slice findBoardThumbnails(String cursor, int size, Long applicantId); - Slice findApplicantDetails(Pageable pageable, Long hostId); + Slice findApplicantDetails(String cursor, int size, Long hostId); } From c520ab5a1c0ea38a1e2835c3b5d4aed65d998517 Mon Sep 17 00:00:00 2001 From: min429 Date: Thu, 29 Aug 2024 00:32:43 +0900 Subject: [PATCH 4/5] =?UTF-8?q?refactor:=20=EB=A9=94=EC=86=8C=EB=93=9C=20?= =?UTF-8?q?=EC=9C=84=EC=B9=98=EB=A5=BC=20=EB=B3=80=EA=B2=BD=ED=95=98?= =?UTF-8?q?=EA=B3=A0=20=EC=A4=91=EB=B3=B5=20=EB=A9=94=EC=86=8C=EB=93=9C?= =?UTF-8?q?=EB=A5=BC=20=EC=B6=94=EC=B6=9C=ED=95=9C=EB=8B=A4.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../AccompanyBoardRepositoryImpl.java | 42 +++++++------------ .../AccompanyRequestRepositoryImpl.java | 16 +------ 2 files changed, 17 insertions(+), 41 deletions(-) diff --git a/src/main/java/com/dnd/accompany/domain/accompany/infrastructure/querydsl/AccompanyBoardRepositoryImpl.java b/src/main/java/com/dnd/accompany/domain/accompany/infrastructure/querydsl/AccompanyBoardRepositoryImpl.java index ef0d19e..e4da524 100644 --- a/src/main/java/com/dnd/accompany/domain/accompany/infrastructure/querydsl/AccompanyBoardRepositoryImpl.java +++ b/src/main/java/com/dnd/accompany/domain/accompany/infrastructure/querydsl/AccompanyBoardRepositoryImpl.java @@ -35,19 +35,6 @@ public class AccompanyBoardRepositoryImpl implements AccompanyBoardRepositoryCus private final JPAQueryFactory queryFactory; - private BooleanExpression isHost() { - return accompanyUser.role.eq(HOST); - } - - private BooleanBuilder isRegion(Region region) { - BooleanBuilder clause = new BooleanBuilder(); - if (region != null) { - clause.and(accompanyBoard.region.eq(region)); - } - - return clause; - } - @Override public Slice findBoardThumbnails(String cursor, int size, Region region) { List content = queryFactory @@ -78,13 +65,7 @@ public Slice findBoardThumbnails(String cursor, int s .limit(size + 1) .fetch(); - boolean hasNext = content.size() > pageable.getPageSize(); - - if (hasNext) { - content.remove(content.size() - 1); - } - - return new SliceImpl<>(content, pageable, hasNext); + return createSlice(size, content); } @Override @@ -117,13 +98,7 @@ public Slice findBoardThumbnailsByUserId(String curso .limit(size + 1) .fetch(); - boolean hasNext = content.size() > pageable.getPageSize(); - - if (hasNext) { - content.remove(content.size() - 1); - } - - return new SliceImpl<>(content, pageable, hasNext); + return createSlice(size, content); } @Override @@ -139,4 +114,17 @@ public boolean isHostOfBoard(Long userId, Long boardId) { return fetchCount != null; } + + private BooleanExpression isHost() { + return accompanyUser.role.eq(HOST); + } + + private BooleanBuilder isRegion(Region region) { + BooleanBuilder clause = new BooleanBuilder(); + if (region != null) { + clause.and(accompanyBoard.region.eq(region)); + } + + return clause; + } } diff --git a/src/main/java/com/dnd/accompany/domain/accompany/infrastructure/querydsl/AccompanyRequestRepositoryImpl.java b/src/main/java/com/dnd/accompany/domain/accompany/infrastructure/querydsl/AccompanyRequestRepositoryImpl.java index e2a1fa4..6e0b572 100644 --- a/src/main/java/com/dnd/accompany/domain/accompany/infrastructure/querydsl/AccompanyRequestRepositoryImpl.java +++ b/src/main/java/com/dnd/accompany/domain/accompany/infrastructure/querydsl/AccompanyRequestRepositoryImpl.java @@ -70,13 +70,7 @@ public Slice findBoardThumbnails(String cursor, int s .limit(size + 1) .fetch(); - boolean hasNext = content.size() > pageable.getPageSize(); - - if (hasNext) { - content.remove(content.size() - 1); - } - - return new SliceImpl<>(content, pageable, hasNext); + return createSlice(size, content); } @Override @@ -110,12 +104,6 @@ public Slice findApplicantDetails(String cursor, int .limit(size + 1) .fetch(); - boolean hasNext = content.size() > pageable.getPageSize(); - - if (hasNext) { - content.remove(content.size() - 1); - } - - return new SliceImpl<>(content, pageable, hasNext); + return createSlice(size, content); } } From 01f470196a3594e27f7f7f669659f782be1a66cc Mon Sep 17 00:00:00 2001 From: min429 Date: Thu, 29 Aug 2024 00:47:03 +0900 Subject: [PATCH 5/5] =?UTF-8?q?feat:=20Controller=20=EB=A9=94=EC=86=8C?= =?UTF-8?q?=EB=93=9C=20=EB=A7=A4=ED=95=91=20=EB=B0=A9=EC=8B=9D=EC=9D=84=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD=ED=95=98=EA=B3=A0=20dto=EC=97=90=20nullable?= =?UTF-8?q?=EC=9D=84=20=EC=B6=94=EA=B0=80=ED=95=9C=EB=8B=A4.(swagger?= =?UTF-8?q?=EC=97=90=20=EB=AA=85=EC=8B=9C)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/accompany/api/AccompanyBoardController.java | 2 +- .../domain/accompany/api/AccompanyRequestController.java | 5 +++-- .../dnd/accompany/domain/accompany/api/dto/PageRequest.java | 6 ++++-- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/dnd/accompany/domain/accompany/api/AccompanyBoardController.java b/src/main/java/com/dnd/accompany/domain/accompany/api/AccompanyBoardController.java index 88f17fc..474e169 100644 --- a/src/main/java/com/dnd/accompany/domain/accompany/api/AccompanyBoardController.java +++ b/src/main/java/com/dnd/accompany/domain/accompany/api/AccompanyBoardController.java @@ -92,7 +92,7 @@ public ResponseEntity remove( } @Operation(summary = "동행 기록 조회") - @GetMapping("/records") + @PostMapping("/records") public ResponseEntity> readAllRecords( @RequestBody @Valid PageRequest request, @AuthenticationPrincipal JwtAuthentication user) { diff --git a/src/main/java/com/dnd/accompany/domain/accompany/api/AccompanyRequestController.java b/src/main/java/com/dnd/accompany/domain/accompany/api/AccompanyRequestController.java index 64994c1..8ecfe79 100644 --- a/src/main/java/com/dnd/accompany/domain/accompany/api/AccompanyRequestController.java +++ b/src/main/java/com/dnd/accompany/domain/accompany/api/AccompanyRequestController.java @@ -7,6 +7,7 @@ import org.springframework.security.core.annotation.AuthenticationPrincipal; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @@ -35,7 +36,7 @@ public class AccompanyRequestController { private final AccompanyRequestService accompanyRequestService; @Operation(summary = "보낸 동행 신청서 목록 조회") - @GetMapping("/sended") + @PostMapping("/sended") public ResponseEntity> readAllSended( @RequestBody @Valid PageRequest request, @AuthenticationPrincipal JwtAuthentication user) { @@ -43,7 +44,7 @@ public ResponseEntity> readAllSended( } @Operation(summary = "받은 동행 신청서 목록 조회") - @GetMapping("/received") + @PostMapping("/received") public ResponseEntity> readAllReceived( @RequestBody @Valid PageRequest request, @AuthenticationPrincipal JwtAuthentication user) { diff --git a/src/main/java/com/dnd/accompany/domain/accompany/api/dto/PageRequest.java b/src/main/java/com/dnd/accompany/domain/accompany/api/dto/PageRequest.java index ad4b2a2..f181feb 100644 --- a/src/main/java/com/dnd/accompany/domain/accompany/api/dto/PageRequest.java +++ b/src/main/java/com/dnd/accompany/domain/accompany/api/dto/PageRequest.java @@ -12,9 +12,11 @@ import com.querydsl.core.types.dsl.NumberTemplate; import com.querydsl.core.types.dsl.StringTemplate; +import io.swagger.v3.oas.annotations.media.Schema; + public record PageRequest( - String cursor, - Integer size + @Schema(nullable = true) String cursor, + @Schema(nullable = true) Integer size ) { public PageRequest {