|
@@ -0,0 +1,258 @@
|
|
|
+package com.sf.service.impl;
|
|
|
+
|
|
|
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
+import com.baomidou.mybatisplus.core.metadata.IPage;
|
|
|
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
|
|
+import com.sf.dto.RestResp;
|
|
|
+import com.sf.dto.req.BookAddReqDto;
|
|
|
+import com.sf.dto.req.ChapterAddReqDto;
|
|
|
+import com.sf.dto.req.ChapterUpdateReqDto;
|
|
|
+import com.sf.dto.req.PageReqDto;
|
|
|
+import com.sf.dto.resp.*;
|
|
|
+import com.sf.entity.AuthorInfo;
|
|
|
+import com.sf.entity.BookChapter;
|
|
|
+import com.sf.entity.BookContent;
|
|
|
+import com.sf.entity.BookInfo;
|
|
|
+import com.sf.mapper.AuthorInfoMapper;
|
|
|
+import com.sf.mapper.BookChapterMapper;
|
|
|
+import com.sf.mapper.BookContentMapper;
|
|
|
+import com.sf.mapper.BookInfoMapper;
|
|
|
+import com.sf.service.IAuthorBookService;
|
|
|
+import com.sf.util.UserHolder;
|
|
|
+import lombok.RequiredArgsConstructor;
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
+import org.springframework.transaction.annotation.Transactional;
|
|
|
+
|
|
|
+import java.time.LocalDateTime;
|
|
|
+import java.util.Objects;
|
|
|
+
|
|
|
+@Service
|
|
|
+@RequiredArgsConstructor
|
|
|
+public class AuthorBookServiceImpl implements IAuthorBookService {
|
|
|
+
|
|
|
+ private final BookInfoMapper bookInfoMapper;
|
|
|
+ private final BookChapterMapper bookChapterMapper;
|
|
|
+ private final BookContentMapper bookContentMapper;
|
|
|
+ private final AuthorInfoMapper authorInfoMapper;
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public RestResp<Void> saveBook(BookAddReqDto dto) {
|
|
|
+ // 校验小说名是否已存在
|
|
|
+ LambdaQueryWrapper<BookInfo> queryWrapper = new LambdaQueryWrapper<>();
|
|
|
+ queryWrapper.eq(BookInfo::getBookName, dto.getBookName());
|
|
|
+ if (bookInfoMapper.selectCount(queryWrapper) > 0) {
|
|
|
+ return RestResp.fail("00010", "小说名已经存在");
|
|
|
+ }
|
|
|
+ BookInfo bookInfo = new BookInfo();
|
|
|
+ // 设置作家信息
|
|
|
+ LambdaQueryWrapper<AuthorInfo> authorInfoLambdaQueryWrapper = new LambdaQueryWrapper<>();
|
|
|
+ authorInfoLambdaQueryWrapper.eq(AuthorInfo::getUserId, UserHolder.getUserId());
|
|
|
+ AuthorInfo authorInfo = authorInfoMapper.selectOne(authorInfoLambdaQueryWrapper);
|
|
|
+
|
|
|
+ bookInfo.setAuthorId(authorInfo.getId());
|
|
|
+ bookInfo.setAuthorName(authorInfo.getPenName());
|
|
|
+ // 设置其他信息
|
|
|
+ bookInfo.setWorkDirection(dto.getWorkDirection());
|
|
|
+ bookInfo.setCategoryId(dto.getCategoryId());
|
|
|
+ bookInfo.setCategoryName(dto.getCategoryName());
|
|
|
+ bookInfo.setBookName(dto.getBookName());
|
|
|
+ bookInfo.setPicUrl(dto.getPicUrl());
|
|
|
+ bookInfo.setBookDesc(dto.getBookDesc());
|
|
|
+ bookInfo.setIsVip(dto.getIsVip());
|
|
|
+ bookInfo.setScore(0);
|
|
|
+ bookInfo.setCreateTime(LocalDateTime.now());
|
|
|
+ bookInfo.setUpdateTime(LocalDateTime.now());
|
|
|
+ // 保存小说信息
|
|
|
+ bookInfoMapper.insert(bookInfo);
|
|
|
+ return RestResp.ok(null);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
+ @Override
|
|
|
+ public RestResp<Void> saveBookChapter(ChapterAddReqDto dto) {
|
|
|
+ // 校验该作品是否属于当前作家
|
|
|
+ BookInfo bookInfo = bookInfoMapper.selectById(dto.getBookId());
|
|
|
+// if (!Objects.equals(bookInfo.getAuthorId(), UserHolder.getAuthorId())) {
|
|
|
+// return RestResp.fail(ErrorCodeEnum.USER_UN_AUTH);
|
|
|
+// }
|
|
|
+ // 1) 保存章节相关信息到小说章节表
|
|
|
+ // a) 查询最新章节号
|
|
|
+ int chapterNum = 0;
|
|
|
+ LambdaQueryWrapper<BookChapter> chapterQueryWrapper = new LambdaQueryWrapper<>();
|
|
|
+ chapterQueryWrapper.eq(BookChapter::getBookId, dto.getBookId())
|
|
|
+ .orderByDesc(BookChapter::getChapterNum).last("limit 1");
|
|
|
+ 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) 更新小说表关于最新章节的信息
|
|
|
+ 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);
|
|
|
+
|
|
|
+ return RestResp.ok(null);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public RestResp<PageRespDto<BookInfoRespDto>> listAuthorBooks(PageReqDto dto) {
|
|
|
+ IPage<BookInfo> page = new Page<>();
|
|
|
+ page.setCurrent(dto.getPageNum());
|
|
|
+ page.setSize(dto.getPageSize());
|
|
|
+
|
|
|
+ LambdaQueryWrapper<AuthorInfo> authorInfoLambdaQueryWrapper = new LambdaQueryWrapper<>();
|
|
|
+ authorInfoLambdaQueryWrapper.eq(AuthorInfo::getUserId, UserHolder.getUserId());
|
|
|
+ AuthorInfo authorInfo = authorInfoMapper.selectOne(authorInfoLambdaQueryWrapper);
|
|
|
+
|
|
|
+ LambdaQueryWrapper<BookInfo> queryWrapper = new LambdaQueryWrapper<>();
|
|
|
+ queryWrapper.eq(BookInfo::getAuthorId, authorInfo.getId())
|
|
|
+ .orderByDesc(BookInfo::getCreateTime);
|
|
|
+ IPage<BookInfo> bookInfoPage = bookInfoMapper.selectPage(page, queryWrapper);
|
|
|
+ return RestResp.ok(PageRespDto.of(dto.getPageNum(), dto.getPageSize(), page.getTotal(),
|
|
|
+ bookInfoPage.getRecords().stream().map(v -> BookInfoRespDto.builder()
|
|
|
+ .id(v.getId())
|
|
|
+ .bookName(v.getBookName())
|
|
|
+ .picUrl(v.getPicUrl())
|
|
|
+ .categoryName(v.getCategoryName())
|
|
|
+ .wordCount(v.getWordCount())
|
|
|
+ .visitCount(v.getVisitCount())
|
|
|
+ .updateTime(v.getUpdateTime())
|
|
|
+ .build()).toList()));
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public RestResp<PageRespDto<BookChapterRespDto>> listBookChapters(Long bookId, PageReqDto dto) {
|
|
|
+ IPage<BookChapter> page = new Page<>();
|
|
|
+ page.setCurrent(dto.getPageNum());
|
|
|
+ page.setSize(dto.getPageSize());
|
|
|
+ LambdaQueryWrapper<BookChapter> queryWrapper = new LambdaQueryWrapper<>();
|
|
|
+ queryWrapper.eq(BookChapter::getBookId, bookId)
|
|
|
+ .orderByDesc(BookChapter::getChapterNum);
|
|
|
+ IPage<BookChapter> bookChapterPage = bookChapterMapper.selectPage(page, queryWrapper);
|
|
|
+ return RestResp.ok(PageRespDto.of(dto.getPageNum(), dto.getPageSize(), page.getTotal(),
|
|
|
+ bookChapterPage.getRecords().stream().map(bookChapter -> BookChapterRespDto.builder()
|
|
|
+ .id(bookChapter.getId())
|
|
|
+ .chapterName(bookChapter.getChapterName())
|
|
|
+ .chapterUpdateTime(bookChapter.getUpdateTime())
|
|
|
+ .isVip(bookChapter.getIsVip())
|
|
|
+ .build()).toList()));
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
+ @Override
|
|
|
+ public RestResp<Void> deleteBookChapter(Long chapterId) {
|
|
|
+ // 1.查询章节信息
|
|
|
+ BookChapter chapter = bookChapterMapper.selectById(chapterId);
|
|
|
+ // 2.查询小说信息
|
|
|
+ BookInfo bookInfo = bookInfoMapper.selectById(chapter.getBookId());
|
|
|
+ // 3.删除章节信息
|
|
|
+ bookChapterMapper.deleteById(chapterId);
|
|
|
+ // 4.删除章节内容
|
|
|
+ LambdaQueryWrapper<BookContent> bookContentQueryWrapper = new LambdaQueryWrapper<>();
|
|
|
+ bookContentQueryWrapper.eq(BookContent::getChapterId, chapterId);
|
|
|
+ bookContentMapper.delete(bookContentQueryWrapper);
|
|
|
+ // 5.更新小说信息
|
|
|
+ BookInfo newBookInfo = new BookInfo();
|
|
|
+ newBookInfo.setId(chapter.getBookId());
|
|
|
+ newBookInfo.setUpdateTime(LocalDateTime.now());
|
|
|
+ newBookInfo.setWordCount(bookInfo.getWordCount() - chapter.getWordCount());
|
|
|
+ if (Objects.equals(bookInfo.getLastChapterId(), chapterId)) {
|
|
|
+ // 设置最新章节信息
|
|
|
+ LambdaQueryWrapper<BookChapter> bookChapterQueryWrapper = new LambdaQueryWrapper<>();
|
|
|
+ bookChapterQueryWrapper.eq(BookChapter::getBookId, chapter.getBookId())
|
|
|
+ .orderByDesc(BookChapter::getChapterNum).last("limit 1");
|
|
|
+ BookChapter bookChapter = bookChapterMapper.selectOne(bookChapterQueryWrapper);
|
|
|
+ Long lastChapterId = 0L;
|
|
|
+ String lastChapterName = "";
|
|
|
+ LocalDateTime lastChapterUpdateTime = null;
|
|
|
+ if (Objects.nonNull(bookChapter)) {
|
|
|
+ lastChapterId = bookChapter.getId();
|
|
|
+ lastChapterName = bookChapter.getChapterName();
|
|
|
+ lastChapterUpdateTime = bookChapter.getUpdateTime();
|
|
|
+ }
|
|
|
+ newBookInfo.setLastChapterId(lastChapterId);
|
|
|
+ newBookInfo.setLastChapterName(lastChapterName);
|
|
|
+ newBookInfo.setLastChapterUpdateTime(lastChapterUpdateTime);
|
|
|
+ }
|
|
|
+ bookInfoMapper.updateById(newBookInfo);
|
|
|
+ return RestResp.ok(null);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public RestResp<ChapterContentRespDto> getBookChapter(Long chapterId) {
|
|
|
+ BookChapter chapter = bookChapterMapper.selectById(chapterId);
|
|
|
+ LambdaQueryWrapper<BookContent> queryWrapper = new LambdaQueryWrapper<>();
|
|
|
+ queryWrapper.eq(BookContent::getChapterId, chapterId);
|
|
|
+ BookContent bookContent = bookContentMapper.selectOne(queryWrapper);
|
|
|
+ String content = bookContent.getContent();
|
|
|
+ return RestResp.ok(
|
|
|
+ ChapterContentRespDto.builder()
|
|
|
+ .chapterName(chapter.getChapterName())
|
|
|
+ .chapterContent(content)
|
|
|
+ .isVip(chapter.getIsVip())
|
|
|
+ .build());
|
|
|
+ }
|
|
|
+
|
|
|
+ @Transactional
|
|
|
+ @Override
|
|
|
+ public RestResp<Void> updateBookChapter(Long chapterId, ChapterUpdateReqDto dto) {
|
|
|
+ // 1.查询章节信息
|
|
|
+ BookChapter chapter = bookChapterMapper.selectById(chapterId);
|
|
|
+ // 2.查询小说信息
|
|
|
+ BookInfo bookInfo = bookInfoMapper.selectById(chapter.getBookId());
|
|
|
+ // 3.更新章节信息
|
|
|
+ BookChapter newChapter = new BookChapter();
|
|
|
+ newChapter.setId(chapterId);
|
|
|
+ newChapter.setChapterName(dto.getChapterName());
|
|
|
+ newChapter.setWordCount(dto.getChapterContent().length());
|
|
|
+ newChapter.setIsVip(dto.getIsVip());
|
|
|
+ newChapter.setUpdateTime(LocalDateTime.now());
|
|
|
+ bookChapterMapper.updateById(newChapter);
|
|
|
+ // 4.更新章节内容
|
|
|
+ BookContent newContent = new BookContent();
|
|
|
+ newContent.setContent(dto.getChapterContent());
|
|
|
+ newContent.setUpdateTime(LocalDateTime.now());
|
|
|
+ LambdaQueryWrapper<BookContent> bookContentQueryWrapper = new LambdaQueryWrapper<>();
|
|
|
+ bookContentQueryWrapper.eq(BookContent::getChapterId, chapterId);
|
|
|
+ bookContentMapper.update(newContent, bookContentQueryWrapper);
|
|
|
+ // 5.更新小说信息
|
|
|
+ BookInfo newBookInfo = new BookInfo();
|
|
|
+ newBookInfo.setId(chapter.getBookId());
|
|
|
+ newBookInfo.setUpdateTime(LocalDateTime.now());
|
|
|
+ newBookInfo.setWordCount(
|
|
|
+ bookInfo.getWordCount() - chapter.getWordCount() + dto.getChapterContent().length());
|
|
|
+ if (Objects.equals(bookInfo.getLastChapterId(), chapterId)) {
|
|
|
+ // 更新最新章节信息
|
|
|
+ newBookInfo.setLastChapterName(dto.getChapterName());
|
|
|
+ newBookInfo.setLastChapterUpdateTime(LocalDateTime.now());
|
|
|
+ }
|
|
|
+ bookInfoMapper.updateById(newBookInfo);
|
|
|
+ return RestResp.ok(null);
|
|
|
+ }
|
|
|
+
|
|
|
+}
|