diff --git a/novel-common/src/main/java/com/java2nb/novel/core/utils/FileUtil.java b/novel-common/src/main/java/com/java2nb/novel/core/utils/FileUtil.java
index 8caf2bc..50ea3dc 100644
--- a/novel-common/src/main/java/com/java2nb/novel/core/utils/FileUtil.java
+++ b/novel-common/src/main/java/com/java2nb/novel/core/utils/FileUtil.java
@@ -19,6 +19,7 @@ import java.util.Objects;
/**
* 文件操作工具类
+ *
* @author 11797
*/
@UtilityClass
@@ -27,8 +28,8 @@ public class FileUtil {
/**
* 网络图片转本地
- * */
- public String network2Local(String picSrc,String picSavePath,String visitPrefix) {
+ */
+ public String network2Local(String picSrc, String picSavePath, String visitPrefix) {
InputStream input = null;
OutputStream out = null;
try {
@@ -53,45 +54,41 @@ public class FileUtil {
}
out.flush();
- if( ImageIO.read(picFile) == null){
+ if (ImageIO.read(picFile) == null) {
picSrc = "/images/default.gif";
}
- }catch (Exception e){
- log.error(e.getMessage(),e);
+ } catch (Exception e) {
+ log.error(e.getMessage(), e);
picSrc = "/images/default.gif";
- }finally {
- if(input != null){
- try {
- input.close();
- } catch (IOException e) {
- log.error(e.getMessage(),e);
- }finally {
- if(out != null){
- try {
- out.close();
- } catch (IOException e) {
- log.error(e.getMessage(),e);
- }
- }
- }
- }
+ } finally {
+ closeStream(input, out);
}
-
return picSrc;
}
+ @SneakyThrows
+ private void closeStream(InputStream input, OutputStream out) {
+ if (input != null) {
+ input.close();
+ }
+ if (out != null) {
+ out.close();
+ }
+ }
+
/**
* 判断文件是否为图片
+ *
* @param file 需要判断的文件
* @return true:是图片,false:不是图片
- * */
+ */
@SneakyThrows
- public boolean isImage(File file){
+ public boolean isImage(File file) {
BufferedImage bi = ImageIO.read(file);
@@ -100,6 +97,27 @@ public class FileUtil {
}
+ public void writeContentToFile(String fileSavePath, String fileSrc, String content) {
+ OutputStream out = null;
+ try {
+ File file = new File(fileSavePath + fileSrc);
+ File parentFile = file.getParentFile();
+ if (!parentFile.exists()) {
+ parentFile.mkdirs();
+ }
+ out = new FileOutputStream(file);
+ out.write(content.getBytes());
+ byte[] b = new byte[4096];
+ out.flush();
+
+ } catch (Exception e) {
+ log.error(e.getMessage(), e);
+ throw new RuntimeException("文件写入失败");
+ } finally {
+ closeStream(null, out);
+ }
+
+ }
}
diff --git a/novel-common/src/main/resources/application-common-dev.yml b/novel-common/src/main/resources/application-common-dev.yml
index 5515f1f..9018872 100644
--- a/novel-common/src/main/resources/application-common-dev.yml
+++ b/novel-common/src/main/resources/application-common-dev.yml
@@ -71,3 +71,7 @@ sharding:
+txt:
+ save:
+ storage: db #存储介质,db:数据库,file:txt文本
+ path: /Users/xiongxiaoyang/books #txt小说文本保存路径
\ No newline at end of file
diff --git a/novel-common/src/main/resources/application-common-prod.yml b/novel-common/src/main/resources/application-common-prod.yml
index 1f1c824..8853b0b 100644
--- a/novel-common/src/main/resources/application-common-prod.yml
+++ b/novel-common/src/main/resources/application-common-prod.yml
@@ -74,7 +74,10 @@ logging:
-
+txt:
+ save:
+ storage: db #存储介质,db:数据库,file:txt文本
+ path: /Users/xiongxiaoyang/books #txt小说文本保存路径
diff --git a/novel-common/src/main/resources/mybatis/generatorConfig.xml b/novel-common/src/main/resources/mybatis/generatorConfig.xml
index 7408b76..984a5aa 100644
--- a/novel-common/src/main/resources/mybatis/generatorConfig.xml
+++ b/novel-common/src/main/resources/mybatis/generatorConfig.xml
@@ -44,7 +44,7 @@
-
+
diff --git a/novel-crawl/src/main/java/com/java2nb/novel/service/BookContentService.java b/novel-crawl/src/main/java/com/java2nb/novel/service/BookContentService.java
new file mode 100644
index 0000000..7090f3a
--- /dev/null
+++ b/novel-crawl/src/main/java/com/java2nb/novel/service/BookContentService.java
@@ -0,0 +1,16 @@
+package com.java2nb.novel.service;
+
+import com.java2nb.novel.entity.BookContent;
+
+import java.util.List;
+
+public interface BookContentService {
+
+ void saveBookContent(List bookContentList,Long bookId);
+
+ void saveBookContent(BookContent bookContent,Long bookId);
+
+ void updateBookContent(BookContent bookContent,Long bookId);
+
+
+}
diff --git a/novel-crawl/src/main/java/com/java2nb/novel/service/impl/BookServiceImpl.java b/novel-crawl/src/main/java/com/java2nb/novel/service/impl/BookServiceImpl.java
index 64b6550..677d0c8 100644
--- a/novel-crawl/src/main/java/com/java2nb/novel/service/impl/BookServiceImpl.java
+++ b/novel-crawl/src/main/java/com/java2nb/novel/service/impl/BookServiceImpl.java
@@ -4,6 +4,7 @@ import com.java2nb.novel.entity.Book;
import com.java2nb.novel.entity.BookContent;
import com.java2nb.novel.entity.BookIndex;
import com.java2nb.novel.mapper.*;
+import com.java2nb.novel.service.BookContentService;
import com.java2nb.novel.service.BookService;
import com.java2nb.novel.utils.Constants;
import lombok.RequiredArgsConstructor;
@@ -37,7 +38,7 @@ public class BookServiceImpl implements BookService {
private final CrawlBookIndexMapper bookIndexMapper;
- private final BookContentMapper bookContentMapper;
+ private final BookContentService bookContentService;
@Override
@@ -46,7 +47,7 @@ public class BookServiceImpl implements BookService {
return bookMapper.count(countFrom(BookDynamicSqlSupport.book).where(BookDynamicSqlSupport.bookName, isEqualTo(bookName))
.and(BookDynamicSqlSupport.authorName, isEqualTo(authorName))
.build()
- .render(RenderingStrategies.MYBATIS3))>0;
+ .render(RenderingStrategies.MYBATIS3)) > 0;
}
@@ -57,7 +58,7 @@ public class BookServiceImpl implements BookService {
.equalTo(sourceId)
.set(crawlBookId)
.equalTo(bookId)
- .where(BookDynamicSqlSupport.id,isEqualTo(id))
+ .where(BookDynamicSqlSupport.id, isEqualTo(id))
.build()
.render(RenderingStrategies.MYBATIS3));
}
@@ -74,9 +75,9 @@ public class BookServiceImpl implements BookService {
@Transactional(rollbackFor = Exception.class)
@Override
public void saveBookAndIndexAndContent(Book book, List bookIndexList, List bookContentList) {
- if(!queryIsExistByBookNameAndAuthorName(book.getBookName(),book.getAuthorName())) {
+ if (!queryIsExistByBookNameAndAuthorName(book.getBookName(), book.getAuthorName())) {
- if(bookIndexList.size()>0) {
+ if (bookIndexList.size() > 0) {
//保存小说主表
@@ -85,7 +86,7 @@ public class BookServiceImpl implements BookService {
//批量保存目录和内容
bookIndexMapper.insertMultiple(bookIndexList);
- bookContentMapper.insertMultiple(bookContentList);
+ bookContentService.saveBookContent(bookContentList,book.getId());
}
}
@@ -96,7 +97,7 @@ public class BookServiceImpl implements BookService {
@Override
public List queryNeedUpdateBook(Date startDate, int limit) {
List books = bookMapper.queryNeedUpdateBook(startDate, limit);
- if(books.size()>0) {
+ if (books.size() > 0) {
//更新最后抓取时间为当前时间
bookMapper.updateCrawlLastTime(books, new Date());
}
@@ -105,38 +106,33 @@ public class BookServiceImpl implements BookService {
@Override
public Map queryExistBookIndexMap(Long bookId) {
- List bookIndexs = bookIndexMapper.selectMany(select(BookIndexDynamicSqlSupport.id,BookIndexDynamicSqlSupport.indexNum,BookIndexDynamicSqlSupport.indexName,BookIndexDynamicSqlSupport.wordCount)
+ List bookIndexs = bookIndexMapper.selectMany(select(BookIndexDynamicSqlSupport.id, BookIndexDynamicSqlSupport.indexNum, BookIndexDynamicSqlSupport.indexName, BookIndexDynamicSqlSupport.wordCount)
.from(BookIndexDynamicSqlSupport.bookIndex)
- .where(BookIndexDynamicSqlSupport.bookId,isEqualTo(bookId))
+ .where(BookIndexDynamicSqlSupport.bookId, isEqualTo(bookId))
.build()
.render(RenderingStrategies.MYBATIS3));
if (bookIndexs.size() > 0) {
- return bookIndexs.stream().collect(Collectors.toMap(BookIndex::getIndexNum, Function.identity()));
+ return bookIndexs.stream().collect(Collectors.toMap(BookIndex::getIndexNum, Function.identity()));
}
return new HashMap<>(0);
}
@Transactional(rollbackFor = Exception.class)
@Override
- public void updateBookAndIndexAndContent(Book book, List bookIndexList, List bookContentList, Map existBookIndexMap) {
+ public void updateBookAndIndexAndContent(Book book, List bookIndexList, List bookContentList, Map existBookIndexMap) {
for (int i = 0; i < bookIndexList.size(); i++) {
BookIndex bookIndex = bookIndexList.get(i);
BookContent bookContent = bookContentList.get(i);
- if(!existBookIndexMap.containsKey(bookIndex.getIndexNum())) {
+ if (!existBookIndexMap.containsKey(bookIndex.getIndexNum())) {
//插入
bookIndexMapper.insertSelective(bookIndex);
- bookContentMapper.insertSelective(bookContent);
- }else{
+ bookContentService.saveBookContent(bookContent,book.getId());
+ } else {
//更新
bookIndexMapper.updateByPrimaryKeySelective(bookIndex);
- bookContentMapper.update(update(BookContentDynamicSqlSupport.bookContent)
- .set(BookContentDynamicSqlSupport.content)
- .equalTo(bookContent.getContent())
- .where(BookContentDynamicSqlSupport.indexId,isEqualTo(bookContent.getIndexId()))
- .build()
- .render(RenderingStrategies.MYBATIS3));
+ bookContentService.updateBookContent(bookContent,book.getId());
}
@@ -145,7 +141,7 @@ public class BookServiceImpl implements BookService {
//更新小说主表
book.setBookName(null);
book.setAuthorName(null);
- if(Constants.VISIT_COUNT_DEFAULT.equals(book.getVisitCount())) {
+ if (Constants.VISIT_COUNT_DEFAULT.equals(book.getVisitCount())) {
book.setVisitCount(null);
}
bookMapper.updateByPrimaryKeySelective(book);
@@ -168,7 +164,7 @@ public class BookServiceImpl implements BookService {
.build()
.render(RenderingStrategies.MYBATIS3));
- if(books.size()>0){
+ if (books.size() > 0) {
return books.get(0);
}
diff --git a/novel-crawl/src/main/java/com/java2nb/novel/service/impl/DbBookContentServiceImpl.java b/novel-crawl/src/main/java/com/java2nb/novel/service/impl/DbBookContentServiceImpl.java
new file mode 100644
index 0000000..9cb75bc
--- /dev/null
+++ b/novel-crawl/src/main/java/com/java2nb/novel/service/impl/DbBookContentServiceImpl.java
@@ -0,0 +1,44 @@
+package com.java2nb.novel.service.impl;
+
+import com.java2nb.novel.entity.BookContent;
+import com.java2nb.novel.mapper.BookContentDynamicSqlSupport;
+import com.java2nb.novel.mapper.BookContentMapper;
+import com.java2nb.novel.service.BookContentService;
+import lombok.RequiredArgsConstructor;
+import org.mybatis.dynamic.sql.render.RenderingStrategies;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+import static org.mybatis.dynamic.sql.SqlBuilder.isEqualTo;
+import static org.mybatis.dynamic.sql.SqlBuilder.update;
+
+
+@Service
+@RequiredArgsConstructor
+@ConditionalOnProperty(prefix = "txt.save", name = "storage", havingValue = "db")
+public class DbBookContentServiceImpl implements BookContentService {
+
+ private final BookContentMapper bookContentMapper;
+
+ @Override
+ public void saveBookContent(List bookContentList,Long bookId) {
+ bookContentMapper.insertMultiple(bookContentList);
+ }
+
+ @Override
+ public void saveBookContent(BookContent bookContent,Long bookId) {
+ bookContentMapper.insertSelective(bookContent);
+ }
+
+ @Override
+ public void updateBookContent(BookContent bookContent,Long bookId) {
+ bookContentMapper.update(update(BookContentDynamicSqlSupport.bookContent)
+ .set(BookContentDynamicSqlSupport.content)
+ .equalTo(bookContent.getContent())
+ .where(BookContentDynamicSqlSupport.indexId,isEqualTo(bookContent.getIndexId()))
+ .build()
+ .render(RenderingStrategies.MYBATIS3));
+ }
+}
diff --git a/novel-crawl/src/main/java/com/java2nb/novel/service/impl/FileBookContentServiceImpl.java b/novel-crawl/src/main/java/com/java2nb/novel/service/impl/FileBookContentServiceImpl.java
new file mode 100644
index 0000000..28afc57
--- /dev/null
+++ b/novel-crawl/src/main/java/com/java2nb/novel/service/impl/FileBookContentServiceImpl.java
@@ -0,0 +1,36 @@
+package com.java2nb.novel.service.impl;
+
+import com.java2nb.novel.core.utils.FileUtil;
+import com.java2nb.novel.entity.BookContent;
+import com.java2nb.novel.service.BookContentService;
+import lombok.RequiredArgsConstructor;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+@Service
+@RequiredArgsConstructor
+@ConditionalOnProperty(prefix = "txt.save", name = "storage", havingValue = "file")
+public class FileBookContentServiceImpl implements BookContentService {
+
+ @Value("${txt.save.path}")
+ private String fileSavePath;
+
+ @Override
+ public void saveBookContent(List bookContentList,Long bookId) {
+ bookContentList.forEach(bookContent -> saveBookContent(bookContent,bookId));
+
+ }
+
+ @Override
+ public void saveBookContent(BookContent bookContent,Long bookId) {
+ FileUtil.writeContentToFile(fileSavePath,"/"+bookId+"/"+bookContent.getIndexId()+".txt",bookContent.getContent());
+ }
+
+ @Override
+ public void updateBookContent(BookContent bookContent,Long bookId) {
+ FileUtil.writeContentToFile(fileSavePath,"/"+bookId+"/"+bookContent.getIndexId()+".txt",bookContent.getContent());
+ }
+}
diff --git a/novel-front/src/main/java/com/java2nb/novel/page/PageController.java b/novel-front/src/main/java/com/java2nb/novel/page/PageController.java
index 615d152..44b211f 100644
--- a/novel-front/src/main/java/com/java2nb/novel/page/PageController.java
+++ b/novel-front/src/main/java/com/java2nb/novel/page/PageController.java
@@ -5,16 +5,14 @@ import com.java2nb.novel.core.bean.PageBean;
import com.java2nb.novel.core.bean.UserDetails;
import com.java2nb.novel.core.utils.ThreadLocalUtil;
import com.java2nb.novel.entity.*;
-import com.java2nb.novel.service.AuthorService;
-import com.java2nb.novel.service.BookService;
-import com.java2nb.novel.service.NewsService;
-import com.java2nb.novel.service.UserService;
+import com.java2nb.novel.service.*;
import com.java2nb.novel.vo.BookCommentVO;
import com.java2nb.novel.vo.BookSettingVO;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
@@ -36,6 +34,9 @@ import java.util.concurrent.ThreadPoolExecutor;
@Controller
public class PageController extends BaseController {
+ @Value("${txt.save.path}")
+ private String fileSavePath;
+
private final BookService bookService;
private final NewsService newsService;
@@ -44,6 +45,8 @@ public class PageController extends BaseController {
private final UserService userService;
+ private final BookContentService bookContentService;
+
private final ThreadPoolExecutor threadPoolExecutor;
@@ -174,7 +177,7 @@ public class PageController extends BaseController {
*/
@SneakyThrows
@RequestMapping("/book/{bookId}/{bookIndexId}.html")
- public String indexList(@PathVariable("bookId") Long bookId, @PathVariable("bookIndexId") Long bookIndexId, HttpServletRequest request, Model model) {
+ public String bookContent(@PathVariable("bookId") Long bookId, @PathVariable("bookIndexId") Long bookIndexId, HttpServletRequest request, Model model) {
//加载小说基本信息线程
CompletableFuture bookCompletableFuture = CompletableFuture.supplyAsync(() -> {
//查询书籍
@@ -210,7 +213,7 @@ public class PageController extends BaseController {
//加载小说内容信息线程
CompletableFuture bookContentCompletableFuture = CompletableFuture.supplyAsync(() -> {
//查询内容
- BookContent bookContent = bookService.queryBookContent(bookIndexId);
+ BookContent bookContent = bookContentService.queryBookContent(bookId, bookIndexId);
log.debug("加载小说内容信息线程结束");
return bookContent;
}, threadPoolExecutor);
diff --git a/novel-front/src/main/java/com/java2nb/novel/service/BookContentService.java b/novel-front/src/main/java/com/java2nb/novel/service/BookContentService.java
new file mode 100644
index 0000000..a610fab
--- /dev/null
+++ b/novel-front/src/main/java/com/java2nb/novel/service/BookContentService.java
@@ -0,0 +1,11 @@
+package com.java2nb.novel.service;
+
+import com.java2nb.novel.entity.BookContent;
+
+import java.util.List;
+
+public interface BookContentService {
+
+ BookContent queryBookContent(Long bookId, Long bookIndexId);
+
+}
diff --git a/novel-front/src/main/java/com/java2nb/novel/service/impl/DbBookContentServiceImpl.java b/novel-front/src/main/java/com/java2nb/novel/service/impl/DbBookContentServiceImpl.java
new file mode 100644
index 0000000..bf5e008
--- /dev/null
+++ b/novel-front/src/main/java/com/java2nb/novel/service/impl/DbBookContentServiceImpl.java
@@ -0,0 +1,38 @@
+package com.java2nb.novel.service.impl;
+
+import com.java2nb.novel.entity.BookContent;
+import com.java2nb.novel.mapper.BookContentDynamicSqlSupport;
+import com.java2nb.novel.mapper.BookContentMapper;
+import com.java2nb.novel.service.BookContentService;
+import lombok.RequiredArgsConstructor;
+import org.mybatis.dynamic.sql.render.RenderingStrategies;
+import org.mybatis.dynamic.sql.select.render.SelectStatementProvider;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+import static com.java2nb.novel.mapper.BookContentDynamicSqlSupport.bookContent;
+import static org.mybatis.dynamic.sql.SqlBuilder.isEqualTo;
+import static org.mybatis.dynamic.sql.SqlBuilder.update;
+import static org.mybatis.dynamic.sql.select.SelectDSL.select;
+
+
+@Service
+@RequiredArgsConstructor
+@ConditionalOnProperty(prefix = "txt.save", name = "storage", havingValue = "db")
+public class DbBookContentServiceImpl implements BookContentService {
+
+ private final BookContentMapper bookContentMapper;
+
+ @Override
+ public BookContent queryBookContent(Long bookId, Long bookIndexId) {
+ SelectStatementProvider selectStatement = select(BookContentDynamicSqlSupport.id, BookContentDynamicSqlSupport.content)
+ .from(bookContent)
+ .where(BookContentDynamicSqlSupport.indexId, isEqualTo(bookIndexId))
+ .limit(1)
+ .build()
+ .render(RenderingStrategies.MYBATIS3);
+ return bookContentMapper.selectMany(selectStatement).get(0);
+ }
+}
diff --git a/novel-front/src/main/java/com/java2nb/novel/service/impl/FileBookContentServiceImpl.java b/novel-front/src/main/java/com/java2nb/novel/service/impl/FileBookContentServiceImpl.java
new file mode 100644
index 0000000..aa59320
--- /dev/null
+++ b/novel-front/src/main/java/com/java2nb/novel/service/impl/FileBookContentServiceImpl.java
@@ -0,0 +1,39 @@
+package com.java2nb.novel.service.impl;
+
+import com.java2nb.novel.core.utils.FileUtil;
+import com.java2nb.novel.entity.BookContent;
+import com.java2nb.novel.service.BookContentService;
+import lombok.RequiredArgsConstructor;
+import lombok.SneakyThrows;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.stereotype.Service;
+
+import java.io.BufferedReader;
+import java.io.FileReader;
+import java.util.List;
+
+@Service
+@RequiredArgsConstructor
+@ConditionalOnProperty(prefix = "txt.save", name = "storage", havingValue = "file")
+public class FileBookContentServiceImpl implements BookContentService {
+
+ @Value("${txt.save.path}")
+ private String fileSavePath;
+
+ @SneakyThrows
+ @Override
+ public BookContent queryBookContent(Long bookId, Long bookIndexId) {
+ BufferedReader in = new BufferedReader(new FileReader(fileSavePath + "/" + bookId + "/" + bookIndexId + ".txt"));
+ StringBuffer sb = new StringBuffer();
+ String str;
+ while ((str = in.readLine()) != null) {
+ sb.append(str);
+ }
+ in.close();
+ return new BookContent() {{
+ setIndexId(bookIndexId);
+ setContent(sb.toString());
+ }};
+ }
+}