diff --git a/src/main/java/io/github/xxyopen/novel/controller/front/BookController.java b/src/main/java/io/github/xxyopen/novel/controller/front/BookController.java index a4e4f2e..8b78873 100644 --- a/src/main/java/io/github/xxyopen/novel/controller/front/BookController.java +++ b/src/main/java/io/github/xxyopen/novel/controller/front/BookController.java @@ -13,6 +13,7 @@ import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; +import java.security.NoSuchAlgorithmException; import java.util.List; /** @@ -44,6 +45,14 @@ public class BookController { return bookService.getLastChapterAbout(bookId); } + /** + * 小说推荐列表查询接口 + * */ + @GetMapping("recList") + public RestResp> listRecBooks(Long bookId) throws NoSuchAlgorithmException { + return bookService.listRecBooks(bookId); + } + /** * 小说内容相关信息查询接口 * */ diff --git a/src/main/java/io/github/xxyopen/novel/core/constant/CacheConsts.java b/src/main/java/io/github/xxyopen/novel/core/constant/CacheConsts.java index a878b88..f70f351 100644 --- a/src/main/java/io/github/xxyopen/novel/core/constant/CacheConsts.java +++ b/src/main/java/io/github/xxyopen/novel/core/constant/CacheConsts.java @@ -69,6 +69,11 @@ public class CacheConsts { */ public static final String BOOK_CONTENT_CACHE_NAME = "bookContentCache"; + /** + * 最近更新小说ID列表缓存 + * */ + public static final String LAST_UPDATE_BOOK_ID_LIST_CACHE_NAME = "lastUpdateBookIdListCache"; + /** * 缓存配置常量 @@ -91,7 +96,9 @@ public class CacheConsts { BOOK_CHAPTER_CACHE(0,BOOK_CHAPTER_CACHE_NAME,60 * 60 * 6,5000), - BOOK_CONTENT_CACHE(2, BOOK_CONTENT_CACHE_NAME, 60 * 60 * 12, 3000); + BOOK_CONTENT_CACHE(2, BOOK_CONTENT_CACHE_NAME, 60 * 60 * 12, 3000), + + LAST_UPDATE_BOOK_ID_LIST_CACHE(0,LAST_UPDATE_BOOK_ID_LIST_CACHE_NAME,60 * 60, 10); /** * 缓存类型 0-本地 1-本地和远程 2-远程 diff --git a/src/main/java/io/github/xxyopen/novel/manager/BookInfoCacheManager.java b/src/main/java/io/github/xxyopen/novel/manager/BookInfoCacheManager.java index 6d19084..fadc014 100644 --- a/src/main/java/io/github/xxyopen/novel/manager/BookInfoCacheManager.java +++ b/src/main/java/io/github/xxyopen/novel/manager/BookInfoCacheManager.java @@ -11,6 +11,8 @@ import lombok.RequiredArgsConstructor; import org.springframework.cache.annotation.Cacheable; import org.springframework.stereotype.Component; +import java.util.List; + /** * 小说信息 缓存管理类 * @@ -59,5 +61,17 @@ public class BookInfoCacheManager { .build(); } + /** + * 查询每个类别下最新更新的 500 个小说ID列表,并放入缓存中 1 个小时 + */ + @Cacheable(cacheManager = CacheConsts.CAFFEINE_CACHE_MANAGER + , value = CacheConsts.LAST_UPDATE_BOOK_ID_LIST_CACHE_NAME) + public List getLastUpdateIdList(Long categoryId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("category_id", categoryId) + .orderByDesc("last_chapter_update_time") + .last("limit 500"); + return bookInfoMapper.selectList(queryWrapper).stream().map(BookInfo::getId).toList(); + } } diff --git a/src/main/java/io/github/xxyopen/novel/service/BookService.java b/src/main/java/io/github/xxyopen/novel/service/BookService.java index aa39f15..7327966 100644 --- a/src/main/java/io/github/xxyopen/novel/service/BookService.java +++ b/src/main/java/io/github/xxyopen/novel/service/BookService.java @@ -6,6 +6,7 @@ import io.github.xxyopen.novel.dto.resp.BookContentAboutRespDto; import io.github.xxyopen.novel.dto.resp.BookInfoRespDto; import io.github.xxyopen.novel.dto.resp.BookRankRespDto; +import java.security.NoSuchAlgorithmException; import java.util.List; /** @@ -45,4 +46,9 @@ public interface BookService { * 小说最新章节相关信息查询 * */ RestResp getLastChapterAbout(Long bookId); + + /** + * 小说推荐列表查询 + * */ + RestResp> listRecBooks(Long bookId) throws NoSuchAlgorithmException; } diff --git a/src/main/java/io/github/xxyopen/novel/service/impl/BookServiceImpl.java b/src/main/java/io/github/xxyopen/novel/service/impl/BookServiceImpl.java index 0f11fb2..c7cb4ac 100644 --- a/src/main/java/io/github/xxyopen/novel/service/impl/BookServiceImpl.java +++ b/src/main/java/io/github/xxyopen/novel/service/impl/BookServiceImpl.java @@ -11,9 +11,14 @@ import io.github.xxyopen.novel.manager.BookInfoCacheManager; import io.github.xxyopen.novel.manager.BookRankCacheManager; import io.github.xxyopen.novel.service.BookService; import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; +import java.security.NoSuchAlgorithmException; +import java.security.SecureRandom; +import java.util.ArrayList; import java.util.List; +import java.util.Random; /** * 小说模块 服务实现类 @@ -23,6 +28,7 @@ import java.util.List; */ @Service @RequiredArgsConstructor +@Slf4j public class BookServiceImpl implements BookService { private final BookRankCacheManager bookRankCacheManager; @@ -35,6 +41,8 @@ public class BookServiceImpl implements BookService { private final BookChapterMapper bookChapterMapper; + private static final Integer REC_BOOK_COUNT = 4; + @Override public RestResp> listVisitRankBooks() { return RestResp.ok(bookRankCacheManager.listVisitRankBooks()); @@ -79,6 +87,27 @@ public class BookServiceImpl implements BookService { .build()); } + @Override + public RestResp> listRecBooks(Long bookId) throws NoSuchAlgorithmException { + Long categoryId = bookInfoCacheManager.getBookInfo(bookId).getCategoryId(); + List lastUpdateIdList = bookInfoCacheManager.getLastUpdateIdList(categoryId); + List respDtoList = new ArrayList<>(); + List recIdIndexList = new ArrayList<>(); + int count = 0; + Random rand = SecureRandom.getInstanceStrong(); + while (count < REC_BOOK_COUNT){ + int recIdIndex = rand.nextInt(lastUpdateIdList.size()); + if (!recIdIndexList.contains(recIdIndex)) { + recIdIndexList.add(recIdIndex); + bookId = lastUpdateIdList.get(recIdIndex); + BookInfoRespDto bookInfo = bookInfoCacheManager.getBookInfo(bookId); + respDtoList.add(bookInfo); + count ++ ; + } + } + return RestResp.ok(respDtoList); + } + @Override public RestResp getBookContentAbout(Long chapterId) { // 查询章节信息