Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Feature/borrow posts #69

Merged
merged 3 commits into from
Dec 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,16 @@
import site.billbill.apiserver.common.response.BaseResponse;
import site.billbill.apiserver.common.utils.jwt.JWTUtil;

import java.util.List;

@Slf4j
@RestController
@Tag(name = "borrowPosts", description = "대여 게시물 관련")
@RequestMapping("/api/v1/posts/borrowPosts")
@RequiredArgsConstructor
public class PostsController {
private final PostsService postsService;
@Operation(summary = "게시물 생성", description = "게시물 생성 API")
@PostMapping("")
public BaseResponse<PostsResponse.UploadResponse> uploadPostsController(@RequestBody @Valid PostsRequest.UploadRequest request){

Expand All @@ -47,12 +50,14 @@ public BaseResponse<PostsResponse.ViewAllResultResponse> getPostsController(
@Parameter(name = "order", description = "정렬 방향 (asc: 오름차순, desc: 내림차순)", example = "desc", in = ParameterIn.QUERY, required = false)
@RequestParam(value ="order",required = false,defaultValue = "desc") String order,
@Parameter(name = "sortBy", description = "정렬 기준 (예: price, createdAt, likeCount)", example = "createdAt", in = ParameterIn.QUERY, required = true)
@RequestParam(value="sortBy",required = true,defaultValue = "accuracy") String sortBy){
@RequestParam(value="sortBy",required = true,defaultValue = "accuracy") String sortBy
){


Sort.Direction direction = "asc".equalsIgnoreCase(order) ? Sort.Direction.ASC : Sort.Direction.DESC;
return new BaseResponse<>(postsService.ViewAllPostService(category,page,direction,sortBy));
}
@Operation(summary = "게시물 검색", description = "게시물 검색 API")
@GetMapping("/search")
public BaseResponse<PostsResponse.ViewAllResultResponse> getSearchPostsController(
@Parameter(name = "category", description = "카테고리 필터 (예: entire, camp, sports,tools )", example = "entire", in = ParameterIn.QUERY, required = false)
Expand All @@ -64,17 +69,24 @@ public BaseResponse<PostsResponse.ViewAllResultResponse> getSearchPostsControlle
@Parameter(name = "sortBy", description = "정렬 기준 (예: price, createdAt, likeCount)", example = "createdAt", in = ParameterIn.QUERY, required = true)
@RequestParam(value="sortBy",required = true,defaultValue = "accuracy") String sortBy,
@Parameter(name="keyword",description = "검색 키워드(예: 6인용+텐트)",in = ParameterIn.QUERY, required = true)
@RequestParam(value = "keyword",required = true) String keyword) {

@RequestParam(value = "keyword",required = true) String keyword,
@Parameter(name = "state",description = "검색어 저장 여부", in = ParameterIn.QUERY, required = true)
@RequestParam(value = "state",required = true,defaultValue = "true") boolean state) {

String userId = "";
if(MDC.get(JWTUtil.MDC_USER_ID) != null) {
userId= MDC.get(JWTUtil.MDC_USER_ID).toString();
}
Sort.Direction direction = "asc".equalsIgnoreCase(order) ? Sort.Direction.ASC : Sort.Direction.DESC;
return new BaseResponse<>(postsService.ViewSearchPostService(category, page, direction, sortBy,keyword));
return new BaseResponse<>(postsService.ViewSearchPostService(userId,category, page, direction, sortBy,keyword,state));
}
@Operation(summary = "게시물 조회", description = "게시물 상세 조회")
@GetMapping("/{postId}")
public BaseResponse<PostsResponse.ViewPostResponse> getPostController(@PathVariable(value = "postId",required = true)String postId){

return new BaseResponse<>(postsService.ViewPostService(postId));
}
@Operation(summary = "게시물 삭제", description = "게시물 삭제")
@DeleteMapping("/{postId}")
public BaseResponse<String> deletePostController(@PathVariable(value = "postId",required = true)String postId){

Expand All @@ -84,6 +96,21 @@ public BaseResponse<String> deletePostController(@PathVariable(value = "postId",
}
return new BaseResponse<>(postsService.deletePostService(postId,userId));
}
@Operation(summary = "저장한 검색어 불러오기", description = "저장한 검색어 불러오기")
@GetMapping("/searchHist")
public BaseResponse<List<String>> getSearchHistController(){
String userId = "";
if(MDC.get(JWTUtil.MDC_USER_ID) != null) {
userId= MDC.get(JWTUtil.MDC_USER_ID).toString();
}
return new BaseResponse<>(postsService.findSearchService(userId));
}
@Operation(summary = "추천 검색어 불러오기", description = "추천 검색어 주기")
@GetMapping("/recommend")
public BaseResponse<List<String>> getRecommendController(){
return new BaseResponse<>(postsService.findRecommandService());
}
@Operation(summary = "게시물 수정", description = "게시물 수정")
@PatchMapping("/{postId}")
public BaseResponse<String> updatePostController(@PathVariable(value="postId",required = true)String postId,
@RequestBody @Valid PostsRequest.UploadRequest request){
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,10 @@

import site.billbill.apiserver.api.borrowPosts.dto.request.PostsRequest;
import site.billbill.apiserver.api.borrowPosts.dto.response.PostsResponse;
import site.billbill.apiserver.model.post.ItemsBorrowJpaEntity;
import site.billbill.apiserver.model.post.ItemsBorrowStatusJpaEntity;
import site.billbill.apiserver.model.post.ItemsCategoryJpaEntity;
import site.billbill.apiserver.model.post.ItemsJpaEntity;
import site.billbill.apiserver.model.post.*;
import site.billbill.apiserver.model.user.UserJpaEntity;
import site.billbill.apiserver.model.user.UserSearchHistJpaEntity;
import site.billbill.apiserver.repository.borrowPosts.SearchKeywordStatRepository;

import java.time.format.DateTimeFormatter;
import java.util.List;
Expand Down Expand Up @@ -88,5 +87,22 @@ public static PostsResponse.NoRentalPeriodResponse toNoRentalPeriod(ItemsBorrowS
.endDate(borrowStatus.getEndDate().format(DATE_FORMATTER))
.build();
}
public static UserSearchHistJpaEntity toUserSearch(UserJpaEntity user,String keyword){
return UserSearchHistJpaEntity.builder()
.keyword(keyword)
.user(user).build();
}
public static SearchKeywordStatsJpaEntity toSearchKeywordStats(String keyword){
return SearchKeywordStatsJpaEntity.builder()
.keyword(keyword)
.searchCount(1).build();
}
public static String toUserSearchHist(UserSearchHistJpaEntity userSearchHist){
return userSearchHist.getKeyword();
}
public static String toRecommandSearch(SearchKeywordStatsJpaEntity searchKeywordStats){
return searchKeywordStats.getKeyword();
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
import site.billbill.apiserver.api.borrowPosts.dto.request.PostsRequest;
import site.billbill.apiserver.api.borrowPosts.dto.response.PostsResponse;

import java.util.List;

public interface PostsService {
PostsResponse.UploadResponse uploadPostService(PostsRequest.UploadRequest request,String userId);

Expand All @@ -12,7 +14,13 @@ public interface PostsService {
PostsResponse.ViewPostResponse ViewPostService(String postId);

String deletePostService(String postId,String userId);

String UpdatePostService(String postId,String userId,PostsRequest.UploadRequest request);

PostsResponse.ViewAllResultResponse ViewSearchPostService(String category, int page, Sort.Direction direction, String orderType,String keyword);
PostsResponse.ViewAllResultResponse ViewSearchPostService(String userId,String category, int page, Sort.Direction direction, String orderType,String keyword,boolean state);

List<String> findSearchService(String userId);

List<String> findRecommandService();

}
Original file line number Diff line number Diff line change
@@ -1,37 +1,28 @@
package site.billbill.apiserver.api.borrowPosts.service;

import lombok.RequiredArgsConstructor;
import lombok.extern.java.Log;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.http.HttpStatus;
import org.springframework.transaction.annotation.Transactional;
import site.billbill.apiserver.api.borrowPosts.controller.PostsController;
import site.billbill.apiserver.api.borrowPosts.converter.PostsConverter;
import site.billbill.apiserver.api.borrowPosts.dto.request.PostsRequest;
import site.billbill.apiserver.api.borrowPosts.dto.response.PostsResponse;
import site.billbill.apiserver.common.enums.exception.ErrorCode;
import site.billbill.apiserver.common.utils.ULID.ULIDUtil;
import site.billbill.apiserver.exception.CustomException;
import site.billbill.apiserver.model.post.ItemsBorrowJpaEntity;
import site.billbill.apiserver.model.post.ItemsBorrowStatusJpaEntity;
import site.billbill.apiserver.model.post.ItemsCategoryJpaEntity;
import site.billbill.apiserver.model.post.ItemsJpaEntity;
import site.billbill.apiserver.model.post.*;
import site.billbill.apiserver.model.user.UserJpaEntity;
import site.billbill.apiserver.repository.borrowPosts.ItemsBorrowRepository;
import site.billbill.apiserver.repository.borrowPosts.ItemsBorrowStatusRepository;
import site.billbill.apiserver.repository.borrowPosts.ItemsCategoryRepository;
import site.billbill.apiserver.repository.borrowPosts.ItemsRepository;
import site.billbill.apiserver.model.user.UserSearchHistJpaEntity;
import site.billbill.apiserver.repository.borrowPosts.*;
import site.billbill.apiserver.repository.user.UserRepository;
import site.billbill.apiserver.repository.user.UserSearchHistRepository;

import javax.swing.text.html.Option;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

@org.springframework.stereotype.Service
@RequiredArgsConstructor
Expand All @@ -44,6 +35,8 @@ public class PostsServiceImpl implements PostsService {
private final ItemsBorrowRepository itemsBorrowRepository;
private final ItemsBorrowStatusRepository itemsBorrowStatusRepository;
private final ItemsCategoryRepository itemsCategoryRepository;
private final UserSearchHistRepository userSearchHistRepository;
private final SearchKeywordStatRepository searchKeywordStatRepository;
public PostsResponse.UploadResponse uploadPostService(PostsRequest.UploadRequest request,String userId){
//먼저 item 생성,
Optional<UserJpaEntity> isUser=userRepository.findById(userId);
Expand Down Expand Up @@ -160,14 +153,45 @@ public String UpdatePostService(String postId,String userId,PostsRequest.UploadR
}
return "success";
}
public PostsResponse.ViewAllResultResponse ViewSearchPostService(String category, int page, Sort.Direction direction, String orderType,String keyword){
@Transactional
public PostsResponse.ViewAllResultResponse ViewSearchPostService(String userId, String category, int page, Sort.Direction direction, String orderType,String keyword,boolean state){
UserJpaEntity user = userRepository.findById(userId).orElse(null);

Pageable pageable = createPageable(page, direction, orderType);
List<PostsResponse.Post> items = findAndConvertItems(category, pageable, keyword);
//사용자가 검색어 저장을 허용했을 경우
String tempKeyword = keyword.replaceAll("\\+", " ");
if(state){

UserSearchHistJpaEntity userSearchHist= PostsConverter.toUserSearch(user,tempKeyword);
userSearchHistRepository.save(userSearchHist);
}
//추천 검색어를 위해 검색어 를 저장
SearchKeywordStatsJpaEntity searchKeywordStats = searchKeywordStatRepository.findByKeyword(tempKeyword);
if(searchKeywordStats!=null){
int count=searchKeywordStats.getSearchCount()+1;
searchKeywordStats.setSearchCount(count);
}else{
searchKeywordStats = PostsConverter.toSearchKeywordStats(tempKeyword);
searchKeywordStatRepository.save(searchKeywordStats);
}

return PostsConverter.toViewAllList(items);
}

public List<String> findSearchService(String userId){
UserJpaEntity user = userRepository.findById(userId).orElse(null);
List<UserSearchHistJpaEntity> searchHists=userSearchHistRepository.findByUserAndDelYnOrderByCreatedAtDesc(user,false);
List<String> result= searchHists.stream().map(searchHist-> PostsConverter.toUserSearchHist(searchHist)).toList();
return result;

}

public List<String> findRecommandService(){
List<SearchKeywordStatsJpaEntity> searchKeywordStats=searchKeywordStatRepository.findAllByOrderBySearchCountDesc();
List<String> result =searchKeywordStats.stream().map(searchKeywordStat-> PostsConverter.toRecommandSearch(searchKeywordStat)).toList();
return result;
}
//모듈화 코드

private Pageable createPageable(int page, Sort.Direction direction, String orderType) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package site.billbill.apiserver.model.post;

import jakarta.persistence.*;
import lombok.*;

import site.billbill.apiserver.model.BaseTime;

import java.time.LocalDate;

@Entity
@Table(name = "search_keyword_stats")
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class SearchKeywordStatsJpaEntity extends BaseTime {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name="keyword_seq")
private long id;

@Column(name="keyword",nullable = true)
private String keyword;
@Column(name = "search_count", nullable = false)
private int searchCount;

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package site.billbill.apiserver.model.user;

import jakarta.persistence.*;
import lombok.*;
import org.hibernate.annotations.DynamicUpdate;
import site.billbill.apiserver.common.converter.BooleanConverter;
import site.billbill.apiserver.model.BaseTime;
@DynamicUpdate
@Entity
@Table(name = "users_search_hist")
@Getter
@Setter
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class UserSearchHistJpaEntity extends BaseTime {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "search_seq", nullable = false)
private String searchId;
@Column(name = "keyword", nullable = true)
private String keyword;
@Column(name = "del_yn", nullable = false)
@Convert(converter = BooleanConverter.class)
private boolean delYn;
@ManyToOne
@JoinColumn(name="user_id")
private UserJpaEntity user;

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package site.billbill.apiserver.repository.borrowPosts;

import org.springframework.data.jpa.repository.JpaRepository;
import site.billbill.apiserver.model.post.SearchKeywordStatsJpaEntity;

import java.util.List;

public interface SearchKeywordStatRepository extends JpaRepository<SearchKeywordStatsJpaEntity, Long> {
SearchKeywordStatsJpaEntity findByKeyword(String keyword);
List<SearchKeywordStatsJpaEntity> findAllByOrderBySearchCountDesc();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package site.billbill.apiserver.repository.user;

import org.springframework.data.jpa.repository.JpaRepository;
import site.billbill.apiserver.model.user.UserJpaEntity;
import site.billbill.apiserver.model.user.UserSearchHistJpaEntity;

import java.util.List;


public interface UserSearchHistRepository extends JpaRepository<UserSearchHistJpaEntity, String> {
List<UserSearchHistJpaEntity> findByUserAndDelYnOrderByCreatedAtDesc(UserJpaEntity user,boolean delYn);
}
Loading