Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

fix :: 청년 시사경제 용어 사전 조회 기능 수정 #61

Merged
merged 2 commits into from
Nov 29, 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 @@ -52,6 +52,17 @@ public class UserInfo {
)
private List<Policy> favoritePolicies = new ArrayList<>();

public void addFavoriteWord(Word word) {
if (!favoriteWords.contains(word)) {
favoriteWords.add(word);
}
}

public void removeFavoriteWord(Word word) {
favoriteWords.remove(word);
}


@ManyToMany
@JoinTable(
name = "user_favorite_word",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.http.HttpStatus;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.*;

@RestController
Expand All @@ -21,11 +22,11 @@ public class WordController {
@Operation(summary = "카테고리 별 단어 조회", description = "한 페이지의 데이터 개수 설정 가능")
@GetMapping("/category/{page_num}")
public ResponseTemplate<Page<WordSummaryResponseDto>> getWords(
// @AuthenticationPrincipal Long userId,
@AuthenticationPrincipal Long userId,
@RequestParam String category,
@PathVariable("page_num") int pageNum
) {
return new ResponseTemplate<>(HttpStatus.OK, "단어 카테고리 조회 성공", wordService.getWordsByCategory(category, pageNum));
return new ResponseTemplate<>(HttpStatus.OK, "단어 카테고리 조회 성공", wordService.getWordsByCategory(category, userId, pageNum));
}

@Operation(summary = "단어 상세 조회")
Expand All @@ -34,32 +35,32 @@ public ResponseTemplate<WordResponseDto> getWord(@PathVariable("word_id") Long w
return new ResponseTemplate<>(HttpStatus.OK, "단어 상세 조회 성공", wordService.getWord(wordId));
}

// @Operation(summary = "단어 북마크", description = "만약 기존에 북마크에 있다면 삭제, 아니라면 추가")
// @PatchMapping("/bookmark/{word_id}")
// public ResponseTemplate<?> favoriteWord(
// @AuthenticationPrincipal Long userId,
// @PathVariable("word_id") Long wordId
// ) {
// wordService.favoriteWord(userId, wordId);
// return new ResponseTemplate<>(HttpStatus.OK, "북마크 추가 / 삭제 성공");
// }
//
// @Operation(summary = "단어 북마크 조회")
// @GetMapping("/book-mark/{page_num}")
// public ResponseTemplate<Page<WordSummaryResponseDto>> getBookmarks(
// @AuthenticationPrincipal Long userId,
// @PathVariable("page_num") int pageNum
// ) {
// return new ResponseTemplate<>(HttpStatus.OK, "북마크 단어 조회 성공", wordService.getBookmarkedWords(userId, pageNum));
// }
@Operation(summary = "단어 북마크", description = "만약 기존에 북마크에 있다면 삭제, 아니라면 추가")
@PatchMapping("/bookmark/{word_id}")
public ResponseTemplate<?> favoriteWord(
@AuthenticationPrincipal Long userId,
@PathVariable("word_id") Long wordId
) {
wordService.favoriteWord(userId, wordId);
return new ResponseTemplate<>(HttpStatus.OK, "북마크 추가 / 삭제 성공");
}

@Operation(summary = "단어 북마크 조회")
@GetMapping("/book-mark/{page_num}")
public ResponseTemplate<Page<WordSummaryResponseDto>> getBookmarks(
@AuthenticationPrincipal Long userId,
@PathVariable("page_num") int pageNum
) {
return new ResponseTemplate<>(HttpStatus.OK, "북마크 단어 조회 성공", wordService.getBookmarkedWords(userId, pageNum));
}

@Operation(summary = "단어 검색", description = "type에는 카테고리 종류 중 하나 / 공백 중 하나가 들어갈 수 있다.")
@GetMapping("/search")
public ResponseTemplate<WordSummaryResponseDto> searchWord(
// @AuthenticationPrincipal Long userId,
@AuthenticationPrincipal Long userId,
@RequestParam String type,
@RequestParam String word
) {
return new ResponseTemplate<>(HttpStatus.OK, "용어 검색 성공", wordService.searchWord(type, word));
return new ResponseTemplate<>(HttpStatus.OK, "용어 검색 성공", wordService.searchWord(type, word, userId));
}
}
15 changes: 15 additions & 0 deletions src/main/java/com/danpoong/onchung/domain/word/domain/Word.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
import lombok.NoArgsConstructor;
import lombok.Setter;

import java.util.Objects;


@Entity
@Getter
Expand Down Expand Up @@ -35,6 +37,19 @@ public class Word {
@Column(name = "related_welfare")
private String relatedWelfare;

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Word word = (Word) o;
return Objects.equals(id, word.id);
}

@Override
public int hashCode() {
return Objects.hash(id);
}

@Builder
public Word(String category, String term, String description, String example, String relatedWelfare) {
this.category = WordCategory.checkCategory(category);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,24 @@
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;

import java.util.List;
import java.util.Optional;

@Repository
public interface WordRepository extends JpaRepository<Word, Long> {
Page<Word> findByCategory(WordCategory category, Pageable pageable);
List<Word> findAllByCategory(WordCategory category);
Optional<Word> findByTerm(String term);

@Query("SELECT w FROM Word w " +
"LEFT JOIN UserInfo u ON :userId MEMBER OF u.favoriteWords " +
"WHERE w.category = :category " +
"ORDER BY CASE WHEN w MEMBER OF u.favoriteWords THEN 0 ELSE 1 END, w.id")
Page<Word> findWordsByCategoryWithBookmarkFirst(@Param("category") WordCategory category,
@Param("userId") Long userId,
Pageable pageable);
}
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
package com.danpoong.onchung.domain.word.service;

//import com.danpoong.onchung.domain.user.domain.UserInfo;
//import com.danpoong.onchung.domain.user.repository.UserRepository;

import com.danpoong.onchung.domain.user.domain.UserInfo;
import com.danpoong.onchung.domain.user.exception.UserNotFoundException;
import com.danpoong.onchung.domain.user.repository.UserInfoRepository;
import com.danpoong.onchung.domain.word.domain.Word;
import com.danpoong.onchung.domain.word.domain.enums.WordCategory;
import com.danpoong.onchung.domain.word.dto.WordResponseDto;
import com.danpoong.onchung.domain.word.dto.WordSummaryResponseDto;
import com.danpoong.onchung.domain.word.repository.WordRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
Expand All @@ -22,22 +23,26 @@
@Transactional(readOnly = true)
public class WordService {
private final WordRepository wordRepository;
// private final UserRepository userRepository;
private final UserInfoRepository userInfoRepository;

private static final int WORD_PAGE_SIZE = 10;

public Page<WordSummaryResponseDto> getWordsByCategory(String category, int page) {
Page<Word> words = wordRepository.findByCategory(WordCategory.checkCategory(category), PageRequest.of(page, WORD_PAGE_SIZE));
public Page<WordSummaryResponseDto> getWordsByCategory(String category, Long id, int page) {
Page<Word> words = wordRepository.findWordsByCategoryWithBookmarkFirst(
WordCategory.checkCategory(category),
id,
PageRequest.of(page, WORD_PAGE_SIZE)
);

return words.map(word -> {
boolean isBookmarked = false;

// if (userId != null) {
// UserInfo userInfo = userRepository.findById(userId)
// .orElseThrow(() -> new RuntimeException("해당 ID의 사용자가 존재하지 않습니다."));
//
// isBookmarked = userInfo.getFavoriteWords().contains(word);
// }
if (id != null) {
UserInfo userInfo = userInfoRepository.findById(id)
.orElseThrow(() -> new UserNotFoundException("해당 ID의 사용자가 존재하지 않습니다.");

isBookmarked = userInfo.getFavoriteWords().contains(word);
}

return WordSummaryResponseDto.builder()
.wordId(word.getId())
Expand All @@ -49,7 +54,7 @@ public Page<WordSummaryResponseDto> getWordsByCategory(String category, int page
}

public WordResponseDto getWord(Long wordId) {
Word word = wordRepository.findById(wordId).orElseThrow(() -> new RuntimeException("해당 ID의 단어가 존재하지 않습니다."));
Word word = wordRepository.findById(wordId).orElseThrow(() -> new UserNotFoundException("해당 ID의 단어가 존재하지 않습니다."));

return WordResponseDto.builder()
.term(word.getTerm())
Expand All @@ -60,81 +65,80 @@ public WordResponseDto getWord(Long wordId) {
.build();
}

// @Transactional
// public void favoriteWord(Long userId, Long wordId) {
// UserInfo userInfo = userRepository.findById(userId).orElseThrow(() -> new RuntimeException("사용자가 존재하지 않습니다."));
// Word word = wordRepository.findById(wordId).orElseThrow(() -> new RuntimeException("해당 ID의 단어가 존재하지 않습니다."));
//
// boolean isPresent = userInfo.getFavoriteWords().contains(wordId);
//
// if (!isPresent) {
// userInfo.addFavoriteWord(word);
// } else {
// userInfo.removeFavoriteWord(word);
// }
// }
@Transactional
public void favoriteWord(Long id, Long wordId) {
UserInfo userInfo = userInfoRepository.findById(id).orElseThrow(() -> new UserNotFoundException("사용자가 존재하지 않습니다."));
Word word = wordRepository.findById(wordId).orElseThrow(() -> new RuntimeException("해당 ID의 단어가 존재하지 않습니다."));

// public Page<WordSummaryResponseDto> getBookmarkedWords(Long userId, int page) {
// UserInfo userInfo = userRepository.findById(userId).orElseThrow(() -> new RuntimeException("해당 ID의 사용자가 존재하지 않습니다."));
// List<Word> wordList = userInfo.getFavoriteWords();
//
// int totalWords = wordList.size();
// int start = Math.min(page * WORD_PAGE_SIZE, totalWords);
// int end = Math.min((page + 1) * WORD_PAGE_SIZE, totalWords);
//
// List<Word> pagedWords = wordList.subList(start, end);
// Page<Word> pageResult = new PageImpl<>(pagedWords, PageRequest.of(page, WORD_PAGE_SIZE), totalWords);
//
// return pageResult.map(word -> WordSummaryResponseDto.builder()
// .wordId(word.getId())
// .term(word.getTerm())
// .isBookmark(true)
// .relatedWelfare(word.getRelatedWelfare())
// .build()
// );
// }

public WordSummaryResponseDto searchWord(String type, String term) {
// UserInfo userInfo = userRepository.findById(userId)
// .orElseThrow(() -> new RuntimeException("해당 ID의 사용자가 존재하지 않습니다."));
boolean isPresent = userInfo.getFavoriteWords().contains(word);

if (!isPresent) {
userInfo.addFavoriteWord(word);
} else {
userInfo.removeFavoriteWord(word);
}
}

public Page<WordSummaryResponseDto> getBookmarkedWords(Long id, int page) {
UserInfo userInfo = userInfoRepository.findById(id).orElseThrow(() -> new UserNotFoundException("해당 ID의 사용자가 존재하지 않습니다."));
List<Word> wordList = userInfo.getFavoriteWords();

int totalWords = wordList.size();
int start = Math.min(page * WORD_PAGE_SIZE, totalWords);
int end = Math.min((page + 1) * WORD_PAGE_SIZE, totalWords);

List<Word> pagedWords = wordList.subList(start, end);
Page<Word> pageResult = new PageImpl<>(pagedWords, PageRequest.of(page, WORD_PAGE_SIZE), totalWords);

return pageResult.map(word -> WordSummaryResponseDto.builder()
.wordId(word.getId())
.term(word.getTerm())
.isBookmark(true)
.relatedWelfare(word.getRelatedWelfare())
.build()
);
}

public WordSummaryResponseDto searchWord(String type, String term, Long id) {
UserInfo userInfo = userInfoRepository.findById(id)
.orElseThrow(() -> new UserNotFoundException("해당 ID의 사용자가 존재하지 않습니다."));

Word word = wordRepository.findByTerm(term).orElse(null);
if (word == null) {
return WordSummaryResponseDto.empty();
}

// // 북마크 검색
// if (type.equals("북마크")) {
// return searchBookmark(userInfo, word);
// }
//
// 북마크 검색
if (type.equals("북마크")) {
return searchBookmark(userInfo, word);
}

// 전체 검색
if (type.isEmpty()) {
return searchAll(word);
return searchAll(word, userInfo);
}

// 카테고리 검색
return searchByCategory(type, word);
return searchByCategory(type, word, userInfo);
}

// 북마크 내 검색
// private WordSummaryResponseDto searchBookmark(UserInfo userInfo, Word word) {
// for (Word favoriteWord : userInfo.getFavoriteWords()) {
// if (favoriteWord.getTerm().equals(word.getTerm())) {
// return createWordSummaryResponse(favoriteWord, true);
// }
// }
// return WordSummaryResponseDto.empty();
// }
private WordSummaryResponseDto searchBookmark(UserInfo userInfo, Word word) {
if (userInfo.getFavoriteWords().contains(word)) {
return createWordSummaryResponse(word, true);
}
return WordSummaryResponseDto.empty();
}

// 전체 검색
private WordSummaryResponseDto searchAll(Word word) {
// boolean isBookmark = userInfo.getFavoriteWords().contains(word);
return createWordSummaryResponse(word, false);
private WordSummaryResponseDto searchAll(Word word, UserInfo userInfo) {
boolean isBookmark = userInfo.getFavoriteWords().contains(word);
return createWordSummaryResponse(word, isBookmark);
}


// 카테고리 내 검색
private WordSummaryResponseDto searchByCategory(String type, Word word) {
private WordSummaryResponseDto searchByCategory(String type, Word word, UserInfo userInfo) {
WordCategory wordCategoryEng = WordCategory.checkCategory(type);
List<Word> wordList = wordRepository.findAllByCategory(wordCategoryEng);

Expand Down
Loading