From 960b9124d5c0b5da49bb9daf7878f7b3288d9cc7 Mon Sep 17 00:00:00 2001 From: xiongxiaoyang <773861846@qq.com> Date: Sun, 15 May 2022 20:47:07 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=96=B0=E5=A2=9E=E5=B0=8F=E8=AF=B4?= =?UTF-8?q?=E6=8E=A8=E8=8D=90=E5=88=97=E8=A1=A8=E6=9F=A5=E8=AF=A2=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/front/BookController.java | 9 ++++++ .../novel/core/constant/CacheConsts.java | 9 +++++- .../novel/manager/BookInfoCacheManager.java | 14 +++++++++ .../xxyopen/novel/service/BookService.java | 6 ++++ .../novel/service/impl/BookServiceImpl.java | 29 +++++++++++++++++++ 5 files changed, 66 insertions(+), 1 deletion(-) 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) { // 查询章节信息