Skip to content
Original file line number Diff line number Diff line change
@@ -1,23 +1,41 @@
package site.kikihi.custom.global.response.page;

import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.Builder;
import org.springframework.data.domain.Slice;

import java.util.List;

/// null 값은 직렬화에서 제외

@Builder
@JsonInclude(JsonInclude.Include.NON_NULL)
public record SliceResponse<T>(

Long totalCount,
List<T> content,
boolean hasNext,
int page,
int size
) {
public static <T> SliceResponse<T> from(Slice<T> slice) {
return SliceResponse.<T>builder()
.totalCount(null)
.content(slice.getContent())
.hasNext(slice.hasNext())
.page(slice.getNumber() + 1)
.size(slice.getSize())
.build();
}

public static <T> SliceResponse<T> from(Slice<T> slice, long totalCount) {
return SliceResponse.<T>builder()
.totalCount(totalCount)
.content(slice.getContent())
.hasNext(slice.hasNext())
.page(slice.getNumber() + 1)
.size(slice.getSize())
.build();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,6 @@ private User createDev() {
.provider(Provider.KAKAO) // 테스트용 값 (Enum)
.role(Role.ADMIN) // 관리자 권한 부여
.address(Address.of())
.isSearch(true)
.build();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ public ApiResponse<SliceResponse<ProductListResponse>> getProductList(PageReques
Sort.by(Sort.Direction.DESC, "id")
);


/// 공통 객체들 저장
Slice<ProductListResponse> products;

Expand Down Expand Up @@ -84,7 +85,10 @@ public ApiResponse<SliceResponse<ProductListResponse>> getProductList(PageReques
throw new IllegalArgumentException(ErrorCode.BAD_REQUEST.getMessage());
}

return ApiResponse.ok(SliceResponse.from(products));
/// 카테고리에 따른 전체 개수 조회
Long totalCounts = productService.getCountProducts(category.getValue());

return ApiResponse.ok(SliceResponse.from(products, totalCounts));
}

/**
Expand Down Expand Up @@ -129,22 +133,5 @@ public ApiResponse<SliceResponse<String>> getManufacturers(
return ApiResponse.ok(SliceResponse.from(responses));
}


/**
* 전체 상품 개수 조회 API
* @param category 카테 고리
*/
@GetMapping("/total")
public ApiResponse<Long> getTotalProducts(
@RequestParam CategoryType category
) {

/// 서비스 호출
Long response = productService.getCountProducts(category.getValue());

/// 리턴
return ApiResponse.ok(response);
}

}

Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
package site.kikihi.custom.platform.adapter.in.web;

import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Slice;
import org.springframework.data.domain.Sort;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import site.kikihi.custom.global.response.ApiResponse;
import site.kikihi.custom.global.response.page.PageRequest;
import site.kikihi.custom.global.response.page.SliceResponse;
import site.kikihi.custom.platform.adapter.in.web.dto.response.product.ProductListResponse;
import site.kikihi.custom.platform.adapter.in.web.dto.response.search.SearchListResponse;
import site.kikihi.custom.platform.adapter.in.web.swagger.SearchControllerSpec;
import site.kikihi.custom.platform.application.in.search.SearchUseCase;
import site.kikihi.custom.platform.domain.product.Product;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;
import site.kikihi.custom.platform.domain.search.Search;
Expand All @@ -25,23 +28,30 @@ public class SearchController implements SearchControllerSpec {

/// 상품 검색
@GetMapping
public ApiResponse<List<ProductListResponse>> searchProducts(
public ApiResponse<SliceResponse<ProductListResponse>> searchProducts(
@RequestParam("keyword") String keyword,
PageRequest pageRequest,
@AuthenticationPrincipal PrincipalDetails principalDetails
) {

/// Pageable
Pageable pageable = org.springframework.data.domain.PageRequest.of(
pageRequest.getPage() - 1,
pageRequest.getSize(),
Sort.by(Sort.Direction.DESC, "id")
);

/// 유저가 없다면 null 저장
UUID userId = principalDetails != null ? principalDetails.getId() : null;

/// 서비스 호출
List<Product> productList = service.searchProducts(keyword, pageRequest.getPage(), pageRequest.getSize(), userId);
Slice<ProductListResponse> products = service.searchProducts(keyword, pageable, userId);

/// DTO 수정
List<ProductListResponse> responses = ProductListResponse.from(productList);
/// 서비스 호출(총 검색 결과 개수)
long countByKeyword = service.countByKeyword(keyword);

/// 응답
return ApiResponse.ok(responses);
return ApiResponse.ok(SliceResponse.from(products, countByKeyword));
}

/// 나의 최근 검색어 조회
Expand Down Expand Up @@ -84,47 +94,4 @@ public ApiResponse<Void> deleteAllSearch(
return ApiResponse.deleted();
}

/// 자동 저장 기능 조회
@GetMapping("/auto")
public ApiResponse<String> getMyAutoSearch(
@AuthenticationPrincipal PrincipalDetails principalDetails
) {

/// 서비스 호출
boolean checked = service.checkSearch(principalDetails.getId());

String autoSearch = checked ? "자동 저장이 활성화되었습니다." : "자동 저장이 꺼져있습니다.";

/// 리턴
return ApiResponse.ok(autoSearch);

}

/// 자동 저장 기능 켜기
@PutMapping("/auto/on")
public ApiResponse<Void> turnOnSearch(
@AuthenticationPrincipal PrincipalDetails principalDetails
){

/// 서비스 호출
service.turnOnMySearchKeyword(principalDetails.getId());

/// 리턴
return ApiResponse.updated();

}

/// 자동 저장 기능 끄기
@PutMapping("/auto/off")
public ApiResponse<Void> turnOffSearch(
@AuthenticationPrincipal PrincipalDetails principalDetails
){

/// 서비스 호출
service.turnOffMySearchKeyword(principalDetails.getId());

/// 리턴
return ApiResponse.updated();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,6 @@
public interface ProductControllerSpec {


@Operation(
summary = "상품 개수 조회 API",
description = "카테고리별 상품 전체 개수를 파악합니다."
)
ApiResponse<Long> getTotalProducts(
@RequestParam CategoryType category
);

/**
* 상품 상세 조회 API
* @param id 상품 아이디
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import org.springframework.web.bind.annotation.RequestParam;
import site.kikihi.custom.global.response.ApiResponse;
import site.kikihi.custom.global.response.page.PageRequest;
import site.kikihi.custom.global.response.page.SliceResponse;
import site.kikihi.custom.platform.adapter.in.web.dto.response.product.ProductListResponse;
import site.kikihi.custom.platform.adapter.in.web.dto.response.search.SearchListResponse;
import site.kikihi.custom.security.oauth2.domain.PrincipalDetails;
Expand All @@ -21,7 +22,7 @@ public interface SearchControllerSpec {
summary = "검색 API",
description = "키워드를 바탕으로 조회합니다."
)
ApiResponse<List<ProductListResponse>> searchProducts(
ApiResponse<SliceResponse<ProductListResponse>> searchProducts(
@Parameter(example = "하우징")
@RequestParam("keyword") String keyword,
PageRequest pageRequest,
Expand Down Expand Up @@ -57,32 +58,4 @@ ApiResponse<Void> deleteAllSearch(
@AuthenticationPrincipal PrincipalDetails principalDetails
);


@Operation(
summary = "검색어 자동저장 여부 API",
description = "JWT를 바탕으로 자동저장을 확인합니다."
)
ApiResponse<String> getMyAutoSearch(
@AuthenticationPrincipal PrincipalDetails principalDetails
);


@Operation(
summary = "검색어 자동저장 기능 ON API",
description = "JWT를 바탕으로 자동저장을 킵니다."
)
ApiResponse<Void> turnOnSearch(
@AuthenticationPrincipal PrincipalDetails principalDetails
);




@Operation(
summary = "검색어 자동저장 기능 OFF API",
description = "JWT를 바탕으로 자동저장을 끕니다."
)
ApiResponse<Void> turnOffSearch(
@AuthenticationPrincipal PrincipalDetails principalDetails
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,13 @@ public List<Bookmark> getBookmarksByUserIdAndCategoryId(UUID userId, String cate
.toList();
}

@Override
public List<Bookmark> getBookmarksByUserId(UUID userId) {
return repository.findByUserId(userId).stream()
.map(BookmarkJpaEntity::toDomain)
.toList();
}

/**
* 북마크ID 와 유저가 존재하는지 체크
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,6 @@ public void updateUser(User user) {
/// 조회
var entity = userJpaRepository.findById(user.getId())
.orElseThrow(() -> new IllegalArgumentException(ErrorCode.USER_NOT_FOUND.getMessage()));

/// 자동저장 여부 수정
entity.updateSearch(user.isSearch());
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import site.kikihi.custom.platform.domain.bookmark.Bookmark;

import java.util.List;
import java.util.UUID;
Expand Down Expand Up @@ -35,4 +36,5 @@ public interface BookmarkJpaRepository extends JpaRepository<BookmarkJpaEntity,
Long countByProductId();


List<BookmarkJpaEntity> findByUserId(UUID userId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,6 @@ public class UserJpaEntity extends BaseTimeEntity {
@Embedded
private AddressJpaEntity address;

private boolean isSearch;

@PrePersist
public void generateUUID() {
if (this.id == null) {
Expand All @@ -61,7 +59,6 @@ public static UserJpaEntity from(User user) {
.role(user.getRole())
.profileImage(user.getProfileImage())
.address(AddressJpaEntity.from(user.getAddress()))
.isSearch(user.isSearch())
.build();
}

Expand All @@ -76,12 +73,7 @@ public User toDomain() {
.role(role)
.profileImage(profileImage)
.address(address.toDomain())
.isSearch(isSearch)
.build();
}

/// 엔티티 수정용
public void updateSearch(boolean isSearch) {
this.isSearch = isSearch;
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package site.kikihi.custom.platform.application.in.search;

import site.kikihi.custom.platform.domain.product.Product;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Slice;
import site.kikihi.custom.platform.adapter.in.web.dto.response.product.ProductListResponse;
import site.kikihi.custom.platform.domain.search.Search;

import java.util.List;
Expand All @@ -16,25 +18,17 @@
public interface SearchUseCase {

/// 검색
List<Product> searchProducts(String keyword, int page, int size, UUID userId);
Slice<ProductListResponse> searchProducts(String keyword, Pageable pageable, UUID userId);

/// 나의 검색에 목록 확인하기
List<Search> getMySearches(UUID userId);

/// 키워드 검색 결과 개수
long countByKeyword(String keyword);

/// 키워드 하나 삭제하기
void deleteMySearchKeyword(Long searchId, UUID userId);

/// 키워드 모두 삭제하기
void deleteAllKeywords(UUID userId);

/// 나의 최근 검색어 여부
boolean checkSearch(UUID userId);

/// 나의 최근 검색어 저장 끄기
void turnOffMySearchKeyword(UUID userId);

/// 나의 최근 검색어 저장 켜기
void turnOnMySearchKeyword(UUID userId);


}
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ public interface BookmarkPort {
/// 유저와 카테고리 ID를 바탕으로 북마크 목록 조회
List<Bookmark> getBookmarksByUserIdAndCategoryId(UUID userId, String category);

List<Bookmark> getBookmarksByUserId(UUID userId);

/// 유저와 북마크 ID를 바탕으로 북마크 여부 조회
boolean checkBookmarkByUserIdAndId(UUID userId, Long bookmarkId);

Expand Down
Loading
Loading