feat: 增加小说章节发布接口

This commit is contained in:
xiongxiaoyang 2022-05-23 13:22:42 +08:00
parent 45fdb58ab3
commit 61d261d277
5 changed files with 127 additions and 2 deletions

View File

@ -5,6 +5,7 @@ import io.github.xxyopen.novel.core.common.resp.RestResp;
import io.github.xxyopen.novel.core.constant.ApiRouterConsts;
import io.github.xxyopen.novel.dto.req.AuthorRegisterReqDto;
import io.github.xxyopen.novel.dto.req.BookAddReqDto;
import io.github.xxyopen.novel.dto.req.ChapterAddReqDto;
import io.github.xxyopen.novel.service.AuthorService;
import io.github.xxyopen.novel.service.BookService;
import jakarta.validation.Valid;
@ -45,4 +46,12 @@ public class AuthorController {
return bookService.saveBook(dto);
}
/**
* 小说章节发布接口
*/
@PostMapping("book/chapter")
public RestResp<Void> publishBookChapter(@Valid @RequestBody ChapterAddReqDto dto) {
return bookService.saveBookChapter(dto);
}
}

View File

@ -0,0 +1,42 @@
package io.github.xxyopen.novel.dto.req;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import org.hibernate.validator.constraints.Length;
/**
* 章节发布 请求DTO
*
* @author xiongxiaoyang
* @date 2022/5/23
*/
@Data
public class ChapterAddReqDto {
/**
* 小说ID
*/
@NotNull
private Long bookId;
/**
* 章节名
*/
@NotBlank
private String chapterName;
/**
* 章节内容
*/
@NotBlank
@Length(min = 50)
private String chapterContent;
/**
* 是否收费;1-收费 0-免费
*/
@NotNull
private Integer isVip;
}

View File

@ -9,6 +9,7 @@ import io.github.xxyopen.novel.dao.mapper.BookChapterMapper;
import io.github.xxyopen.novel.dao.mapper.BookInfoMapper;
import io.github.xxyopen.novel.dto.resp.BookInfoRespDto;
import lombok.RequiredArgsConstructor;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Component;
@ -29,11 +30,20 @@ public class BookInfoCacheManager {
private final BookChapterMapper bookChapterMapper;
/**
* 查询小说信息并放入缓存中
* 从缓存中查询小说信息先判断缓存中是否已存在存在则直接从缓存中取否则执行方法体中的逻辑后缓存结果
*/
@Cacheable(cacheManager = CacheConsts.CAFFEINE_CACHE_MANAGER
, value = CacheConsts.BOOK_INFO_CACHE_NAME)
public BookInfoRespDto getBookInfo(Long id) {
return cachePutBookInfo(id);
}
/**
* 缓存小说信息不管缓存中是否存在都执行方法体中的逻辑然后缓存起来
* */
@CachePut(cacheManager = CacheConsts.CAFFEINE_CACHE_MANAGER
, value = CacheConsts.BOOK_INFO_CACHE_NAME)
public BookInfoRespDto cachePutBookInfo(Long id) {
// 查询基础信息
BookInfo bookInfo = bookInfoMapper.selectById(id);
// 查询首章ID
@ -62,6 +72,8 @@ public class BookInfoCacheManager {
.build();
}
/**
* 查询每个类别下最新更新的 500 个小说ID列表并放入缓存中 1 个小时
*/

View File

@ -4,6 +4,7 @@ import io.github.xxyopen.novel.core.common.resp.PageRespDto;
import io.github.xxyopen.novel.core.common.resp.RestResp;
import io.github.xxyopen.novel.dto.req.BookAddReqDto;
import io.github.xxyopen.novel.dto.req.BookSearchReqDto;
import io.github.xxyopen.novel.dto.req.ChapterAddReqDto;
import io.github.xxyopen.novel.dto.req.UserCommentReqDto;
import io.github.xxyopen.novel.dto.resp.*;
@ -153,9 +154,16 @@ public interface BookService {
RestResp<Void> updateComment(Long userId, Long id, String content);
/**
* 小说发布
* 小说信息保存
* @param dto 小说信息
* @return void
* */
RestResp<Void> saveBook(BookAddReqDto dto);
/**
* 小说章节信息保存
* @param dto 章节信息
* @return void
* */
RestResp<Void> saveBookChapter(ChapterAddReqDto dto);
}

View File

@ -10,10 +10,12 @@ import io.github.xxyopen.novel.core.constant.DatabaseConsts;
import io.github.xxyopen.novel.dao.entity.*;
import io.github.xxyopen.novel.dao.mapper.BookChapterMapper;
import io.github.xxyopen.novel.dao.mapper.BookCommentMapper;
import io.github.xxyopen.novel.dao.mapper.BookContentMapper;
import io.github.xxyopen.novel.dao.mapper.BookInfoMapper;
import io.github.xxyopen.novel.dto.AuthorInfoDto;
import io.github.xxyopen.novel.dto.req.BookAddReqDto;
import io.github.xxyopen.novel.dto.req.BookSearchReqDto;
import io.github.xxyopen.novel.dto.req.ChapterAddReqDto;
import io.github.xxyopen.novel.dto.req.UserCommentReqDto;
import io.github.xxyopen.novel.dto.resp.*;
import io.github.xxyopen.novel.manager.*;
@ -21,6 +23,7 @@ import io.github.xxyopen.novel.service.BookService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
@ -56,6 +59,8 @@ public class BookServiceImpl implements BookService {
private final BookChapterMapper bookChapterMapper;
private final BookContentMapper bookContentMapper;
private final BookCommentMapper bookCommentMapper;
private final UserDaoManager userDaoManager;
@ -306,6 +311,55 @@ public class BookServiceImpl implements BookService {
return RestResp.ok();
}
@Transactional(rollbackFor = Exception.class)
@Override
public RestResp<Void> saveBookChapter(ChapterAddReqDto dto) {
// 1) 保存章节相关信息到小说章节表
// a) 查询最新章节号
int chapterNum = 0;
QueryWrapper<BookChapter> chapterQueryWrapper = new QueryWrapper<>();
chapterQueryWrapper.eq(DatabaseConsts.BookChapterTable.COLUMN_BOOK_ID,dto.getBookId())
.orderByDesc(DatabaseConsts.BookChapterTable.COLUMN_CHAPTER_NUM)
.last(DatabaseConsts.SqlEnum.LIMIT_1.getSql());
BookChapter bookChapter = bookChapterMapper.selectOne(chapterQueryWrapper);
if(Objects.nonNull(bookChapter)){
chapterNum = bookChapter.getChapterNum() + 1;
}
// b) 设置章节相关信息并保存
BookChapter newBookChapter = new BookChapter();
newBookChapter.setBookId(dto.getBookId());
newBookChapter.setChapterName(dto.getChapterName());
newBookChapter.setChapterNum(chapterNum);
newBookChapter.setWordCount(dto.getChapterContent().length());
newBookChapter.setIsVip(dto.getIsVip());
newBookChapter.setCreateTime(LocalDateTime.now());
newBookChapter.setUpdateTime(LocalDateTime.now());
bookChapterMapper.insert(newBookChapter);
// 2) 保存章节内容到小说内容表
BookContent bookContent = new BookContent();
bookContent.setContent(dto.getChapterContent());
bookContent.setChapterId(newBookChapter.getId());
bookContent.setCreateTime(LocalDateTime.now());
bookContent.setUpdateTime(LocalDateTime.now());
bookContentMapper.insert(bookContent);
// 3) 更新小说表最新章节信息和小说总字数信息
// a) 更新小说表关于最新章节的信息
BookInfoRespDto bookInfo = bookInfoCacheManager.getBookInfo(dto.getBookId());
BookInfo newBookInfo = new BookInfo();
newBookInfo.setId(dto.getBookId());
newBookInfo.setLastChapterId(newBookChapter.getId());
newBookInfo.setLastChapterName(newBookChapter.getChapterName());
newBookInfo.setLastChapterUpdateTime(LocalDateTime.now());
newBookInfo.setWordCount(bookInfo.getWordCount() + newBookChapter.getWordCount());
newBookChapter.setUpdateTime(LocalDateTime.now());
bookInfoMapper.updateById(newBookInfo);
// b) 刷新小说信息缓存
bookInfoCacheManager.cachePutBookInfo(dto.getBookId());
return RestResp.ok();
}
@Override
public RestResp<BookContentAboutRespDto> getBookContentAbout(Long chapterId) {
// 查询章节信息