From b2446ff160efc3b31c96f5f744b297cc780449e0 Mon Sep 17 00:00:00 2001 From: xiongxiaoyang <773861846@qq.com> Date: Sun, 15 May 2022 14:00:21 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=96=B0=E5=A2=9E=E5=B0=8F=E8=AF=B4?= =?UTF-8?q?=E5=86=85=E5=AE=B9=E6=9F=A5=E8=AF=A2=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/front/BookController.java | 13 +++- .../novel/core/constant/CacheConsts.java | 51 +++++++++----- .../novel/dto/resp/BookChapterRespDto.java | 49 +++++++++++++ .../novel/dto/resp/BookContentRespDto.java | 69 +++++++++++++++++++ .../novel/dto/resp/BookInfoRespDto.java | 5 ++ .../manager/BookChapterCacheManager.java | 39 +++++++++++ .../manager/BookContentCacheManager.java | 36 ++++++++++ .../novel/manager/BookInfoCacheManager.java | 3 +- .../xxyopen/novel/service/BookService.java | 8 ++- .../novel/service/impl/BookServiceImpl.java | 39 ++++++++++- 10 files changed, 289 insertions(+), 23 deletions(-) create mode 100644 src/main/java/io/github/xxyopen/novel/dto/resp/BookChapterRespDto.java create mode 100644 src/main/java/io/github/xxyopen/novel/dto/resp/BookContentRespDto.java create mode 100644 src/main/java/io/github/xxyopen/novel/manager/BookChapterCacheManager.java create mode 100644 src/main/java/io/github/xxyopen/novel/manager/BookContentCacheManager.java 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 8de5b3f..31f2dd6 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 @@ -2,6 +2,7 @@ package io.github.xxyopen.novel.controller.front; import io.github.xxyopen.novel.core.common.constant.ApiRouterConsts; import io.github.xxyopen.novel.core.common.resp.RestResp; +import io.github.xxyopen.novel.dto.resp.BookContentRespDto; import io.github.xxyopen.novel.dto.resp.BookInfoRespDto; import io.github.xxyopen.novel.dto.resp.BookRankRespDto; import io.github.xxyopen.novel.service.BookService; @@ -30,8 +31,16 @@ public class BookController { * 小说信息查询接口 * */ @GetMapping("{bookId}") - public RestResp getById(@PathVariable("bookId") Long bookId){ - return bookService.getById(bookId); + public RestResp getBookById(@PathVariable("bookId") Long bookId){ + return bookService.getBookById(bookId); + } + + /** + * 小说章节内容查询接口 + * */ + @GetMapping("content/{chapterId}") + public RestResp getBookContent(@PathVariable("chapterId") Long chapterId){ + return bookService.getBookContent(chapterId); } /** 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 8ee0317..a878b88 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 @@ -10,73 +10,88 @@ public class CacheConsts { /** * 本项目 Redis 缓存前缀 - * */ + */ public static final String REDIS_CACHE_PREFIX = "Cache::Novel::"; /** * Caffeine 缓存管理器 - * */ + */ public static final String CAFFEINE_CACHE_MANAGER = "caffeineCacheManager"; /** * Redis 缓存管理器 - * */ + */ public static final String REDIS_CACHE_MANAGER = "redisCacheManager"; /** * 首页小说推荐缓存 - * */ + */ public static final String HOME_BOOK_CACHE_NAME = "homeBookCache"; /** * 最新新闻缓存 - * */ + */ public static final String LATEST_NEWS_CACHE_NAME = "latestNewsCache"; /** * 小说点击榜缓存 - * */ + */ public static final String BOOK_VISIT_RANK_CACHE_NAME = "bookVisitRankCache"; /** * 小说新书榜缓存 - * */ + */ public static final String BOOK_NEWEST_RANK_CACHE_NAME = "bookNewestRankCache"; /** * 小说更新榜缓存 - * */ + */ public static final String BOOK_UPDATE_RANK_CACHE_NAME = "bookUpdateRankCache"; /** * 首页友情链接缓存 - * */ + */ public static final String HOME_FRIEND_LINK_CACHE_NAME = "homeFriendLinkCache"; - /**小说信息缓存*/ + /** + * 小说信息缓存 + */ public static final String BOOK_INFO_CACHE_NAME = "bookInfoCache"; + /** + * 小说章节缓存 + */ + public static final String BOOK_CHAPTER_CACHE_NAME = "bookChapterCache"; + + /** + * 小说内容缓存 + */ + public static final String BOOK_CONTENT_CACHE_NAME = "bookContentCache"; + /** * 缓存配置常量 */ public enum CacheEnum { - HOME_BOOK_CACHE(0,HOME_BOOK_CACHE_NAME,60 * 60 * 24,1), + HOME_BOOK_CACHE(0, HOME_BOOK_CACHE_NAME, 60 * 60 * 24, 1), - LATEST_NEWS_CACHE(0,LATEST_NEWS_CACHE_NAME,60 * 10,1), + LATEST_NEWS_CACHE(0, LATEST_NEWS_CACHE_NAME, 60 * 10, 1), - BOOK_VISIT_RANK_CACHE(2,BOOK_VISIT_RANK_CACHE_NAME,60 * 60 * 6,1), + BOOK_VISIT_RANK_CACHE(2, BOOK_VISIT_RANK_CACHE_NAME, 60 * 60 * 6, 1), - BOOK_NEWEST_RANK_CACHE(0,BOOK_NEWEST_RANK_CACHE_NAME,60 * 30,1), + BOOK_NEWEST_RANK_CACHE(0, BOOK_NEWEST_RANK_CACHE_NAME, 60 * 30, 1), - BOOK_UPDATE_RANK_CACHE(0,BOOK_UPDATE_RANK_CACHE_NAME,60,1), + BOOK_UPDATE_RANK_CACHE(0, BOOK_UPDATE_RANK_CACHE_NAME, 60, 1), - HOME_FRIEND_LINK_CACHE(2,HOME_FRIEND_LINK_CACHE_NAME,0,1), + HOME_FRIEND_LINK_CACHE(2, HOME_FRIEND_LINK_CACHE_NAME, 0, 1), - BOOK_INFO_CACHE(0,BOOK_INFO_CACHE_NAME,60 * 60 * 18, 500) - ; + BOOK_INFO_CACHE(0, BOOK_INFO_CACHE_NAME, 60 * 60 * 18, 500), + + BOOK_CHAPTER_CACHE(0,BOOK_CHAPTER_CACHE_NAME,60 * 60 * 6,5000), + + BOOK_CONTENT_CACHE(2, BOOK_CONTENT_CACHE_NAME, 60 * 60 * 12, 3000); /** * 缓存类型 0-本地 1-本地和远程 2-远程 diff --git a/src/main/java/io/github/xxyopen/novel/dto/resp/BookChapterRespDto.java b/src/main/java/io/github/xxyopen/novel/dto/resp/BookChapterRespDto.java new file mode 100644 index 0000000..ebe2da4 --- /dev/null +++ b/src/main/java/io/github/xxyopen/novel/dto/resp/BookChapterRespDto.java @@ -0,0 +1,49 @@ +package io.github.xxyopen.novel.dto.resp; + +import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.Builder; +import lombok.Data; + +import java.io.Serial; +import java.io.Serializable; +import java.time.LocalDateTime; + +/** + * 小说章节 响应DTO + * @author xiongxiaoyang + * @date 2022/5/15 + */ +@Data +@Builder +public class BookChapterRespDto implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 小说ID + */ + private Long bookId; + + /** + * 章节名 + */ + private String chapterName; + + /** + * 章节字数 + */ + private Integer chapterWordCount; + + /** + * 章节更新时间 + * */ + @JsonFormat(pattern = "yyyy/MM/dd HH:dd") + private LocalDateTime chapterUpdateTime; + + /** + * 内容概要(20字) + */ + private String contentSummary; + +} diff --git a/src/main/java/io/github/xxyopen/novel/dto/resp/BookContentRespDto.java b/src/main/java/io/github/xxyopen/novel/dto/resp/BookContentRespDto.java new file mode 100644 index 0000000..bb4b507 --- /dev/null +++ b/src/main/java/io/github/xxyopen/novel/dto/resp/BookContentRespDto.java @@ -0,0 +1,69 @@ +package io.github.xxyopen.novel.dto.resp; + +import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.Builder; +import lombok.Data; + +import java.time.LocalDateTime; + +/** + * 小说内容 响应DTO + * @author xiongxiaoyang + * @date 2022/5/15 + */ +@Data +@Builder +public class BookContentRespDto { + + /** + * 小说 ID + */ + private Long bookId; + + /** + * 类别ID + */ + private Long categoryId; + + /** + * 类别名 + */ + private String categoryName; + + /** + * 小说名 + */ + private String bookName; + + /** + * 作家id + */ + private Long authorId; + + /** + * 作家名 + */ + private String authorName; + + /** + * 章节名 + */ + private String chapterName; + + /** + * 章节字数 + */ + private Integer chapterWordCount; + + /** + * 章节更新时间 + * */ + @JsonFormat(pattern = "yyyy/MM/dd HH:dd") + private LocalDateTime chapterUpdateTime; + + /** + * 章节内容 + */ + private String content; + +} diff --git a/src/main/java/io/github/xxyopen/novel/dto/resp/BookInfoRespDto.java b/src/main/java/io/github/xxyopen/novel/dto/resp/BookInfoRespDto.java index 943bc8e..e955c2a 100644 --- a/src/main/java/io/github/xxyopen/novel/dto/resp/BookInfoRespDto.java +++ b/src/main/java/io/github/xxyopen/novel/dto/resp/BookInfoRespDto.java @@ -77,5 +77,10 @@ public class BookInfoRespDto { * */ private Long firstChapterId; + /** + * 最新章节ID + */ + private Long lastChapterId; + } diff --git a/src/main/java/io/github/xxyopen/novel/manager/BookChapterCacheManager.java b/src/main/java/io/github/xxyopen/novel/manager/BookChapterCacheManager.java new file mode 100644 index 0000000..d8296d8 --- /dev/null +++ b/src/main/java/io/github/xxyopen/novel/manager/BookChapterCacheManager.java @@ -0,0 +1,39 @@ +package io.github.xxyopen.novel.manager; + +import io.github.xxyopen.novel.core.constant.CacheConsts; +import io.github.xxyopen.novel.dao.entity.BookChapter; +import io.github.xxyopen.novel.dao.mapper.BookChapterMapper; +import io.github.xxyopen.novel.dto.resp.BookChapterRespDto; +import lombok.RequiredArgsConstructor; +import org.springframework.cache.annotation.Cacheable; +import org.springframework.stereotype.Component; + +/** + * 小说章节 缓存管理类 + * + * @author xiongxiaoyang + * @date 2022/5/12 + */ +@Component +@RequiredArgsConstructor +public class BookChapterCacheManager { + + private final BookChapterMapper bookChapterMapper; + + /** + * 查询小说章节信息,并放入缓存中 + */ + @Cacheable(cacheManager = CacheConsts.CAFFEINE_CACHE_MANAGER + , value = CacheConsts.BOOK_CHAPTER_CACHE_NAME) + public BookChapterRespDto getChapter(Long chapterId) { + BookChapter bookChapter = bookChapterMapper.selectById(chapterId); + return BookChapterRespDto.builder() + .bookId(bookChapter.getBookId()) + .chapterName(bookChapter.getChapterName()) + .chapterWordCount(bookChapter.getWordCount()) + .chapterUpdateTime(bookChapter.getUpdateTime()) + .build(); + } + + +} diff --git a/src/main/java/io/github/xxyopen/novel/manager/BookContentCacheManager.java b/src/main/java/io/github/xxyopen/novel/manager/BookContentCacheManager.java new file mode 100644 index 0000000..a9e9403 --- /dev/null +++ b/src/main/java/io/github/xxyopen/novel/manager/BookContentCacheManager.java @@ -0,0 +1,36 @@ +package io.github.xxyopen.novel.manager; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import io.github.xxyopen.novel.core.constant.CacheConsts; +import io.github.xxyopen.novel.dao.entity.BookContent; +import io.github.xxyopen.novel.dao.mapper.BookContentMapper; +import lombok.RequiredArgsConstructor; +import org.springframework.cache.annotation.Cacheable; +import org.springframework.stereotype.Component; + +/** + * 小说内容 缓存管理类 + * + * @author xiongxiaoyang + * @date 2022/5/12 + */ +@Component +@RequiredArgsConstructor +public class BookContentCacheManager { + + private final BookContentMapper bookContentMapper; + + /** + * 查询小说内容,并放入缓存中 + */ + @Cacheable(cacheManager = CacheConsts.REDIS_CACHE_MANAGER + , value = CacheConsts.BOOK_CONTENT_CACHE_NAME) + public String getBookContent(Long chapterId) { + QueryWrapper contentQueryWrapper = new QueryWrapper<>(); + contentQueryWrapper.eq("chapter_id",chapterId).last("limit 1"); + BookContent bookContent = bookContentMapper.selectOne(contentQueryWrapper); + return bookContent.getContent(); + } + + +} 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 ce5cf0b..6d19084 100644 --- a/src/main/java/io/github/xxyopen/novel/manager/BookInfoCacheManager.java +++ b/src/main/java/io/github/xxyopen/novel/manager/BookInfoCacheManager.java @@ -33,7 +33,7 @@ public class BookInfoCacheManager { public BookInfoRespDto getBookInfo(Long id) { // 查询基础信息 BookInfo bookInfo = bookInfoMapper.selectById(id); - // 查询最新章节ID + // 查询首章ID QueryWrapper queryWrapper = new QueryWrapper<>(); queryWrapper .eq("book_id", id) @@ -52,6 +52,7 @@ public class BookInfoCacheManager { .categoryName(bookInfo.getCategoryName()) .commentCount(bookInfo.getCommentCount()) .firstChapterId(firstBookChapter.getId()) + .lastChapterId(bookInfo.getLastChapterId()) .picUrl(bookInfo.getPicUrl()) .visitCount(bookInfo.getVisitCount()) .wordCount(bookInfo.getWordCount()) 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 1a197b2..c28a018 100644 --- a/src/main/java/io/github/xxyopen/novel/service/BookService.java +++ b/src/main/java/io/github/xxyopen/novel/service/BookService.java @@ -1,6 +1,7 @@ package io.github.xxyopen.novel.service; import io.github.xxyopen.novel.core.common.resp.RestResp; +import io.github.xxyopen.novel.dto.resp.BookContentRespDto; import io.github.xxyopen.novel.dto.resp.BookInfoRespDto; import io.github.xxyopen.novel.dto.resp.BookRankRespDto; @@ -32,5 +33,10 @@ public interface BookService { /** * 小说信息查询 * */ - RestResp getById(Long bookId); + RestResp getBookById(Long bookId); + + /** + * 小说章节内容查询 + * */ + RestResp getBookContent(Long chapterId); } 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 480eb50..0793d71 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 @@ -1,8 +1,13 @@ package io.github.xxyopen.novel.service.impl; import io.github.xxyopen.novel.core.common.resp.RestResp; +import io.github.xxyopen.novel.dao.mapper.BookChapterMapper; +import io.github.xxyopen.novel.dto.resp.BookChapterRespDto; +import io.github.xxyopen.novel.dto.resp.BookContentRespDto; import io.github.xxyopen.novel.dto.resp.BookInfoRespDto; import io.github.xxyopen.novel.dto.resp.BookRankRespDto; +import io.github.xxyopen.novel.manager.BookChapterCacheManager; +import io.github.xxyopen.novel.manager.BookContentCacheManager; import io.github.xxyopen.novel.manager.BookInfoCacheManager; import io.github.xxyopen.novel.manager.BookRankCacheManager; import io.github.xxyopen.novel.service.BookService; @@ -25,6 +30,12 @@ public class BookServiceImpl implements BookService { private final BookInfoCacheManager bookInfoCacheManager; + private final BookChapterCacheManager bookChapterCacheManager; + + private final BookContentCacheManager bookContentCacheManager; + + private final BookChapterMapper bookChapterMapper; + @Override public RestResp> listVisitRankBooks() { return RestResp.ok(bookRankCacheManager.listVisitRankBooks()); @@ -41,7 +52,33 @@ public class BookServiceImpl implements BookService { } @Override - public RestResp getById(Long bookId) { + public RestResp getBookById(Long bookId) { return RestResp.ok(bookInfoCacheManager.getBookInfo(bookId)); } + + @Override + public RestResp getBookContent(Long chapterId) { + // 查询章节信息 + BookChapterRespDto bookChapter = bookChapterCacheManager.getChapter(chapterId); + + // 查询章节内容 + String content = bookContentCacheManager.getBookContent(chapterId); + + // 查询小说信息 + BookInfoRespDto bookInfo = bookInfoCacheManager.getBookInfo(bookChapter.getBookId()); + + // 组装数据并返回 + return RestResp.ok(BookContentRespDto.builder() + .authorId(bookInfo.getAuthorId()) + .bookName(bookInfo.getBookName()) + .authorName(bookInfo.getAuthorName()) + .bookId(bookInfo.getId()) + .content(content) + .categoryId(bookInfo.getCategoryId()) + .categoryName(bookInfo.getCategoryName()) + .chapterName(bookChapter.getChapterName()) + .chapterUpdateTime(bookChapter.getChapterUpdateTime()) + .chapterWordCount(bookChapter.getChapterWordCount()) + .build()); + } }