Skip to content
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package org.websoso.WSSServer.scheduler;
package org.websoso.WSSServer.application;

import java.util.List;
import java.util.stream.Collectors;
Expand All @@ -7,28 +7,29 @@
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.websoso.WSSServer.library.service.LibraryService;
import org.websoso.WSSServer.novel.domain.PopularNovel;
import org.websoso.WSSServer.novel.repository.PopularNovelRepository;
import org.websoso.WSSServer.library.repository.UserNovelRepository;
import org.websoso.WSSServer.novel.service.PopularNovelService;

@Service
@Transactional
@RequiredArgsConstructor
public class NovelScheduler {
public class PopularNovelScheduler {

private final UserNovelRepository userNovelRepository;
private final PopularNovelRepository popularNovelRepository;
private final PopularNovelService popularNovelService;
private final LibraryService libraryService;

@Scheduled(cron = "0 0 0 * * ?")
public void updatePopularNovels() {
List<PopularNovel> yesterdayScheduledPopularNovels = popularNovelRepository.findAll();
List<PopularNovel> yesterdayScheduledPopularNovels = popularNovelService.getPopularNovels();

List<Long> topNovelIds = libraryService.getTodayPopularNovelIds(PageRequest.of(0, 30));

List<Long> topNovelIds = userNovelRepository.findTodayPopularNovelsId(PageRequest.of(0, 30));
List<PopularNovel> popularNovels = topNovelIds.stream()
.map(PopularNovel::from)
.collect(Collectors.toList());

popularNovelRepository.saveAll(popularNovels);
popularNovelRepository.deleteAll(yesterdayScheduledPopularNovels);
popularNovelService.saveAll(popularNovels);
popularNovelService.deleteAll(yesterdayScheduledPopularNovels);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
import org.websoso.WSSServer.novel.service.GenreServiceImpl;
import org.websoso.WSSServer.novel.service.KeywordServiceImpl;
import org.websoso.WSSServer.novel.service.NovelServiceImpl;
import org.websoso.WSSServer.novel.service.PopularNovelService;
import org.websoso.WSSServer.repository.AvatarRepository;
import org.websoso.WSSServer.repository.GenrePreferenceRepository;

Expand All @@ -47,6 +48,7 @@
public class SearchNovelApplication {

private final NovelServiceImpl novelService;
private final PopularNovelService popularNovelService;
private final GenreServiceImpl genreService;
private final KeywordServiceImpl keywordService;
private final LibraryService libraryService;
Expand Down Expand Up @@ -155,7 +157,7 @@ public TasteNovelsGetResponse getTasteNovels(User user) {

@Transactional(readOnly = true)
public PopularNovelsGetResponse getTodayPopularNovels() {
List<Long> novelIdsFromPopularNovel = novelService.getNovelIdsFromPopularNovel();
List<Long> novelIdsFromPopularNovel = popularNovelService.getNovelIdsFromPopularNovel();
List<Long> selectedNovelIdsFromPopularNovel = getSelectedNovelIdsFromPopularNovel(novelIdsFromPopularNovel);
List<Novel> popularNovels = novelService.getSelectedPopularNovels(selectedNovelIdsFromPopularNovel);
List<Feed> popularFeedsFromPopularNovels = feedRepository.findPopularFeedsByNovelIds(selectedNovelIdsFromPopularNovel);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,28 @@
package org.websoso.WSSServer.controller;

import static org.springframework.http.HttpStatus.CREATED;
import static org.springframework.http.HttpStatus.NO_CONTENT;
import static org.springframework.http.HttpStatus.OK;

import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.DeleteMapping;
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.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.websoso.WSSServer.application.LibraryEvaluationApplication;
import org.websoso.WSSServer.application.LibraryInterestApplication;
import org.websoso.WSSServer.domain.User;
import org.websoso.WSSServer.dto.userNovel.UserNovelCreateRequest;
import org.websoso.WSSServer.dto.userNovel.UserNovelGetResponse;
import org.websoso.WSSServer.dto.userNovel.UserNovelUpdateRequest;
import org.websoso.WSSServer.library.service.LibraryService;

@RestController
Expand All @@ -21,6 +31,7 @@
public class LibraryController {

private final LibraryInterestApplication libraryInterestApplication;
private final LibraryEvaluationApplication libraryEvaluationApplication;

/**
* 관심있어요 등록
Expand Down Expand Up @@ -56,4 +67,73 @@ public ResponseEntity<Void> unregisterAsInterest(@AuthenticationPrincipal User u
.build();
}

/**
* 작품 평가하기
*
* @param user 로그인 유저 객체
* @param request 서재 (작품 평가) 생성 객체
* @return 201 CREATED
*/
@PostMapping("/user-novels")
@PreAuthorize("isAuthenticated()")
public ResponseEntity<Void> createEvaluation(@AuthenticationPrincipal User user,
@Valid @RequestBody UserNovelCreateRequest request) {
libraryEvaluationApplication.createEvaluation(user, request);
return ResponseEntity
.status(CREATED)
.build();
}

/**
* 작품 평가 불러오기
*
* @param user 로그인 유저 객체
* @param novelId 소설 ID
* @return UserNovelGetResponse
*/
@GetMapping("/user-novels/{novelId}")
@PreAuthorize("isAuthenticated()")
public ResponseEntity<UserNovelGetResponse> getEvaluation(@AuthenticationPrincipal User user,
@PathVariable Long novelId) {
return ResponseEntity
.status(OK)
.body(libraryEvaluationApplication.getEvaluation(user, novelId));
}

/**
* 작품 평가 업데이트하기
*
* @param user 로그인 유저 객체
* @param novelId 소설 ID
* @param request 서재 (작품 평가) 업데이트 객체
* @return 204 NO_CONTENT
*/
@PutMapping("/user-novels/{novelId}")
@PreAuthorize("isAuthenticated() and @authorizationService.validate(#novelId, #user, T(org.websoso.WSSServer.library.domain.UserNovel))")
public ResponseEntity<Void> updateEvaluation(@AuthenticationPrincipal User user,
@PathVariable Long novelId,
@Valid @RequestBody UserNovelUpdateRequest request) {
libraryEvaluationApplication.updateEvaluation(user, novelId, request);
return ResponseEntity
.status(NO_CONTENT)
.build();
}

/**
* 작품 평가 삭제하기
*
* @param user 로그인 유저 객체
* @param novelId 소설 ID
* @return 204 NO_CONTENT
*/
@DeleteMapping("/user-novels/{novelId}")
@PreAuthorize("isAuthenticated() and @authorizationService.validate(#novelId, #user, T(org.websoso.WSSServer.library.domain.UserNovel))")
public ResponseEntity<Void> deleteEvaluation(@AuthenticationPrincipal User user,
@PathVariable Long novelId) {
libraryEvaluationApplication.deleteEvaluation(user, novelId);
return ResponseEntity
.status(NO_CONTENT)
.build();
}

}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package org.websoso.WSSServer.dto.platform;

import org.websoso.WSSServer.novel.domain.NovelPlatform;
import org.websoso.WSSServer.domain.Platform;
import org.websoso.WSSServer.novel.domain.Platform;

public record PlatformGetResponse(
String platformName,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import java.util.Random;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.websoso.WSSServer.domain.Genre;
Expand Down Expand Up @@ -140,6 +141,10 @@ public List<String> getAttractivePoints(Novel novel) {
return getTOP3AttractivePoints(attractivePointMap);
}

public List<Long> getTodayPopularNovelIds(PageRequest pageRequest) {
return userNovelRepository.findTodayPopularNovelsId(pageRequest);
}

private Map<String, Integer> makeAttractivePointMapExcludingZero(Novel novel) {
Map<String, Integer> attractivePointMap = new HashMap<>();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
import org.websoso.WSSServer.library.repository.UserNovelRepository;
import org.websoso.WSSServer.service.UserService;

// TODO: 남아있는 코드는 User Controller에서 사용중이라 일단 유지
@Service
@RequiredArgsConstructor
@Transactional
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.websoso.WSSServer.domain.Platform;

@Entity
@Getter
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package org.websoso.WSSServer.domain;
package org.websoso.WSSServer.novel.domain;

import static jakarta.persistence.GenerationType.IDENTITY;

Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ public class NovelServiceImpl {
private final NovelRepository novelRepository;
private final NovelGenreRepository novelGenreRepository;
private final NovelPlatformRepository novelPlatformRepository;
private final PopularNovelRepository popularNovelRepository;

@Transactional(readOnly = true)
public Novel getNovelOrException(Long novelId) {
Expand Down Expand Up @@ -58,13 +57,6 @@ public List<PlatformGetResponse> getPlatforms(Novel novel) {
.toList();
}

public List<Long> getNovelIdsFromPopularNovel() {
return new ArrayList<>(popularNovelRepository.findAll()
.stream()
.map(PopularNovel::getNovelId)
.toList());
}

public List<Novel> getSelectedPopularNovels(List<Long> selectedPopularNovelIds) {
return novelRepository.findAllById(selectedPopularNovelIds);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package org.websoso.WSSServer.novel.service;

import java.util.ArrayList;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.websoso.WSSServer.novel.domain.PopularNovel;
import org.websoso.WSSServer.novel.repository.PopularNovelRepository;

@Service
@RequiredArgsConstructor
public class PopularNovelService {

private final PopularNovelRepository popularNovelRepository;

public void saveAll(List<PopularNovel> popularNovels) {
popularNovelRepository.saveAll(popularNovels);
}

public List<PopularNovel> getPopularNovels() {
return popularNovelRepository.findAll();
}

public List<Long> getNovelIdsFromPopularNovel() {
return new ArrayList<>(popularNovelRepository.findAll()
.stream()
.map(PopularNovel::getNovelId)
.toList());
}

public void deleteAll(List<PopularNovel> popularNovels) {
popularNovelRepository.deleteAll(popularNovels);
}


}