38 Commits

Author SHA1 Message Date
05d9e22df9 2.6.0发布,新增笔趣窝源 2020-06-22 16:07:41 +08:00
ef36527ed6 2.4.1发布,修复部分bug 2020-06-22 14:34:35 +08:00
6688d5b017 更新文档 2020-06-01 16:51:02 +08:00
xxy
b242d6d89f 文档更新 2020-05-29 10:02:56 +08:00
xxy
5ec0f39b89 fix bug 2020-05-05 08:51:42 +08:00
xxy
bc445548ce 优化 2020-05-05 07:45:36 +08:00
xxy
7c3fb654bb 文档更新 2020-05-04 13:39:25 +08:00
xxy
060429001c 文档更新 2020-05-03 07:03:03 +08:00
df60698082 Merge branch 'develop' of https://gitee.com/xiongxyang/fiction_house into develop 2020-04-26 12:29:26 +08:00
979bcb47df 增加抓取模式的配置 2020-04-26 12:29:15 +08:00
xxy
495bd40644 文档更新 2020-04-26 07:01:48 +08:00
52f6bd2519 v2.4.0发布 2020-04-25 08:34:49 +08:00
0e4c181265 修复顶点小说的爬取 2020-04-24 16:54:25 +08:00
2a05353d95 update 2020-04-24 12:48:36 +08:00
5144ef9679 新增轻轻小说书源 2020-04-24 08:59:57 +08:00
9c1d954bfd update books.sql and fix xss 2020-04-23 09:00:05 +08:00
8aa724bd69 优化 2020-04-22 12:55:24 +08:00
d7e3dee2af update 2020-04-21 18:08:39 +08:00
075df46572 update 2020-04-21 18:04:43 +08:00
e77af7d6ca 优化 2020-04-21 18:04:05 +08:00
c7caa3049c 新增指定单本小说爬取任务 2020-04-21 13:00:32 +08:00
xxy
ccab7f01a2 新增小说容量配置 2020-04-21 07:11:01 +08:00
dc20ad42bd update 2020-04-15 13:32:26 +08:00
290522ef6d v2.3.0发布 2020-04-15 10:14:23 +08:00
56645720b3 增加百书斋源 2020-04-14 18:42:09 +08:00
xxy
f648a8e79e 优化 2020-02-07 12:22:50 +08:00
55635e098c 优化 2020-01-20 15:29:30 +08:00
16ac61e8ee 优化 2020-01-20 15:06:46 +08:00
548ab44f87 去除统计代码 2020-01-20 15:03:55 +08:00
d4230f32b0 更新bug修复 2020-01-20 10:55:46 +08:00
637b01e50b 优化 2020-01-18 11:37:35 +08:00
04ab2045f3 更新优化 2020-01-18 11:25:35 +08:00
bb83f5628b bug修复 2020-01-17 12:36:46 +08:00
507a10077d bug修复 2020-01-17 11:03:49 +08:00
eb4785d8fd bug修复 2020-01-17 10:58:36 +08:00
2967a94e59 更新策略优化 2020-01-17 10:46:22 +08:00
05dcf7056b 更新间隔外部配置 2020-01-16 10:32:34 +08:00
d898e412c7 更新策略优化 2020-01-13 14:26:55 +08:00
43 changed files with 1833 additions and 596 deletions

View File

@ -1,12 +1,34 @@
[![index](./assets/热门云产品1040.100.jpg)](https://cloud.tencent.com/act/cps/redirect?redirect=1052&cps_key=736e609d66e0ac4e57813316cec6fd0b&from=console) [![index]( https://s1.ax1x.com/2020/06/22/NG6N2n.png )](https://cloud.tencent.com/act/cps/redirect?redirect=1052&cps_key=736e609d66e0ac4e57813316cec6fd0b&from=console)
# 小说精品屋 # 小说精品屋
#### 项目文档 #### 项目:小说精品屋-plus推荐
通用文档:[点击前往]( http://www.java2nb.com/article/5.html ) 小说精品屋-plus致力于打造一个完整的可商用、可学习的小说门户平台。小说精品屋-plus是在小说精品屋的基础上重新进行了数据库设计、代码重构和功能增强提升了程序整体的可读性和性能增加了很多商用特性。
非JAVA开发参考安装文档[点击前往]( https://my.oschina.net/java2nb/blog/3145593 ) Gitee仓库地址 https://gitee.com/xiongxyang/novel-plus
GitHub仓库地址 https://github.com/201206030/novel-plus
#### 新项目:小说精品屋-微服务版(推荐)
基于小说精品屋-plus构建的Spring Cloud 微服务小说门户平台,可用于学习和商用。
Gitee仓库地址 https://gitee.com/xiongxyang/novel-cloud
GitHub仓库地址 https://github.com/201206030/novel-cloud
#### 前言
安装前请先阅读完此文档,了解项目基础配置和模块功能,再根据安装文档安装项目,避免一些不必要的错误。
#### 安装文档
源码安装文档(适合有一定技术基础的人):[点击前往](https://my.oschina.net/java2nb/blog/3145593)
包安装文档(适合非技术人员):[点击前往](https://my.oschina.net/java2nb/blog/3146627)
宝塔安装教程:[点击前往](https://www.daniao.org/7822.html )
#### 项目介绍 #### 项目介绍
@ -105,7 +127,7 @@ novel-admin :平台后台管理系统源码(独立项目,按需安装)
![mini4](./assets/android_index.png) ![mini4](./assets/android_index.png)
#### 安装教程 #### 安装说明
数据库安装: 数据库安装:
@ -119,7 +141,7 @@ novel-admin :平台后台管理系统源码(独立项目,按需安装)
1. 运行script/crawlbook/crawlbook.bat脚本文件。适用于本地多机器运行 1. 运行script/crawlbook/crawlbook.bat脚本文件。适用于本地多机器运行
2. 安装后台管理系统后,打开爬虫管理菜单,点击爬虫运行按钮。(适用于线上环境运行,会占用较多服务器资源) 2. 安装后台管理系统后,打开爬虫管理菜单,点击爬虫运行按钮。(适用于线上环境运行,会占用较多服务器资源)
平台后台管理系统安装(独立项目,按需安装) 平台后台管理系统安装(独立项目,按需安装)已停止维护爬虫功能请使用crawlbook.bat
1. 修改application.yml文件中数据库配置。 1. 修改application.yml文件中数据库配置。
@ -191,7 +213,7 @@ novel-admin :平台后台管理系统源码(独立项目,按需安装)
#### QQ交流群 #### QQ交流群
![mini-code](./assets/小说精品屋开源项目交流群群聊二维码.png) ![mini-code](./assets/qq_group.png)
#### 捐赠支持 #### 捐赠支持
@ -203,6 +225,7 @@ novel-admin :平台后台管理系统源码(独立项目,按需安装)
| 捐赠者 | 金额 | 时间 | | 捐赠者 | 金额 | 时间 |
| :----- | :------- | :-------------------------- | | :----- | :------- | :-------------------------- |
| **阳 | ¥10.00 | 2020年03月06日 下午14点10分 |
| *梦 | ¥66.00 | 2019年12月27日 下午21点39分 | | *梦 | ¥66.00 | 2019年12月27日 下午21点39分 |
| *金名 | ¥50.00 | 2019年12月27日 下午19点29分 | | *金名 | ¥50.00 | 2019年12月27日 下午19点29分 |
| *天气 | ¥300.00 | 2019年12月27日 上午10点13分 | | *天气 | ¥300.00 | 2019年12月27日 上午10点13分 |
@ -224,4 +247,4 @@ novel-admin :平台后台管理系统源码(独立项目,按需安装)
精品小说屋所有相关项目均已在开源中国公开,感兴趣的可进入[开源中国](https://www.oschina.net/p/fiction_house)按关键字`精品小说屋`搜索。 精品小说屋所有相关项目均已在开源中国公开,感兴趣的可进入[开源中国](https://www.oschina.net/p/fiction_house)按关键字`精品小说屋`搜索。
[![index](./assets/120060.jpg)](https://www.aliyun.com/minisite/goods?userCode=uf4nasee ) [![index]( https://s1.ax1x.com/2020/06/22/NG6N2n.png)](https://www.aliyun.com/minisite/goods?userCode=uf4nasee )

BIN
assets/qq_group.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

View File

@ -10,7 +10,7 @@
</parent> </parent>
<groupId>xyz.zinglizingli</groupId> <groupId>xyz.zinglizingli</groupId>
<artifactId>novel-front</artifactId> <artifactId>novel-front</artifactId>
<version>2.2.0.beta</version> <version>2.5.0.beta</version>
<name>novel-front</name> <name>novel-front</name>
<description>小说精品楼-前台web网站</description> <description>小说精品楼-前台web网站</description>
@ -109,6 +109,41 @@
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId> <artifactId>spring-boot-maven-plugin</artifactId>
</plugin> </plugin>
<!--<plugin>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-maven-plugin</artifactId>
<version>1.3.2</version>
<configuration>
<configurationFile>src/main/resources/mybatis/generatorConfig.xml</configurationFile>
<verbose>false</verbose>
<overwrite>false</overwrite>
</configuration>
<executions>
<execution>
<id>Generate MyBatis Artifacts</id>
<goals>
<goal>generate</goal>
</goals>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
</dependency>
&lt;!&ndash;<dependency>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-core</artifactId>
<version>1.3.5</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.2</version>
</dependency>&ndash;&gt;
</dependencies>
</plugin>-->
</plugins> </plugins>
</build> </build>
<repositories> <repositories>

View File

@ -7,12 +7,14 @@ import org.springframework.boot.web.servlet.ServletComponentScan;
import org.springframework.cache.annotation.EnableCaching; import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.scheduling.TaskScheduler; import org.springframework.scheduling.TaskScheduler;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling; import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler; import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
@SpringBootApplication @SpringBootApplication
@EnableCaching @EnableCaching
@EnableScheduling @EnableScheduling
@EnableAsync
@MapperScan({"xyz.zinglizingli.*.mapper"}) @MapperScan({"xyz.zinglizingli.*.mapper"})
@ServletComponentScan @ServletComponentScan
public class BookApplication { public class BookApplication {

View File

@ -0,0 +1,29 @@
package xyz.zinglizingli.books.core.config;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import xyz.zinglizingli.books.core.crawl.BaseHtmlCrawlSource;
import xyz.zinglizingli.books.core.crawl.BiquCrawlSource;
/**
* @author 11797
*/
@Slf4j
@Configuration
public class CrawlBaishuzhaiConfig {
@Bean
@Primary //必须加此注解,不然报错,下一个类则不需要添加
@ConfigurationProperties(prefix = "baishuzhai.crawlsource") // prefix值必须是application.yml中对应属性的前缀
@ConditionalOnProperty(prefix = "crawl.website",name = "type",havingValue = "4")
public BaseHtmlCrawlSource dingdianCrawlSource() {
return new BiquCrawlSource();
}
}

View File

@ -0,0 +1,27 @@
package xyz.zinglizingli.books.core.config;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import xyz.zinglizingli.books.core.crawl.BaseHtmlCrawlSource;
import xyz.zinglizingli.books.core.crawl.BiquCrawlSource;
/**
* @author 11797
*/
@Slf4j
@Configuration
public class CrawlBiquwoConfig {
@Bean
@ConfigurationProperties(prefix = "biquwo.crawlsource") // prefix值必须是application.yml中对应属性的前缀
@ConditionalOnProperty(prefix = "crawl.website",name = "type",havingValue = "6")
public BaseHtmlCrawlSource biquwoCrawlSource() {
return new BiquCrawlSource();
}
}

View File

@ -18,7 +18,6 @@ public class CrawlDingdianConfig {
@Bean @Bean
@Primary //必须加此注解,不然报错,下一个类则不需要添加
@ConfigurationProperties(prefix = "dingdian.crawlsource") // prefix值必须是application.yml中对应属性的前缀 @ConfigurationProperties(prefix = "dingdian.crawlsource") // prefix值必须是application.yml中对应属性的前缀
@ConditionalOnProperty(prefix = "crawl.website",name = "type",havingValue = "3") @ConditionalOnProperty(prefix = "crawl.website",name = "type",havingValue = "3")
public BaseHtmlCrawlSource dingdianCrawlSource() { public BaseHtmlCrawlSource dingdianCrawlSource() {

View File

@ -7,4 +7,5 @@ public class CacheKeyConstans {
public static final String EMAIL_URL_PREFIX_KEY = "emailUrlPrefixKey"; public static final String EMAIL_URL_PREFIX_KEY = "emailUrlPrefixKey";
public static final String RANDOM_NEWS_CONTENT_KEY = "randomNewsContentKey"; public static final String RANDOM_NEWS_CONTENT_KEY = "randomNewsContentKey";
public static final String REC_BOOK_LIST_KEY = "recBookListKey"; public static final String REC_BOOK_LIST_KEY = "recBookListKey";
public static final String BOOK_NUMBER_KEY= "bookNumberKey";
} }

View File

@ -3,22 +3,15 @@ package xyz.zinglizingli.books.core.crawl;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import xyz.zinglizingli.books.core.utils.Constants; import xyz.zinglizingli.books.core.utils.Constants;
import xyz.zinglizingli.books.mapper.BookParseLogMapper; import xyz.zinglizingli.books.po.*;
import xyz.zinglizingli.books.po.Book;
import xyz.zinglizingli.books.po.BookContent;
import xyz.zinglizingli.books.po.BookIndex;
import xyz.zinglizingli.books.po.BookParseLog;
import xyz.zinglizingli.books.service.BookService; import xyz.zinglizingli.books.service.BookService;
import xyz.zinglizingli.books.core.utils.CatUtil; import xyz.zinglizingli.books.core.utils.CatUtil;
import xyz.zinglizingli.common.utils.ExcutorUtils; import xyz.zinglizingli.common.cache.CommonCacheUtil;
import xyz.zinglizingli.common.utils.RestTemplateUtil; import xyz.zinglizingli.common.utils.RestTemplateUtil;
import java.text.SimpleDateFormat; import java.util.*;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
@ -34,6 +27,12 @@ public class BiquCrawlSource extends BaseHtmlCrawlSource {
@Autowired @Autowired
private BookService bookService; private BookService bookService;
@Autowired
private CommonCacheUtil cacheUtil;
@Value("${books.maxNum}")
private Integer maxNumBooks;
@Override @Override
public void parse() { public void parse() {
@ -55,13 +54,9 @@ public class BiquCrawlSource extends BaseHtmlCrawlSource {
Matcher bookNameMatch = bookNamePatten.matcher(forObject); Matcher bookNameMatch = bookNamePatten.matcher(forObject);
Pattern authorPatten = compile(getAuthorPattern());
Matcher authorMatch = authorPatten.matcher(forObject);
boolean isBookNameMatch = bookNameMatch.find(); boolean isBookNameMatch = bookNameMatch.find();
while (isFind && scoreFind && isBookNameMatch && authorMatch.find()) { while (isFind && scoreFind && isBookNameMatch) {
try { try {
Float score = Float.parseFloat(scoreMatch.group(1)); Float score = Float.parseFloat(scoreMatch.group(1));
@ -75,14 +70,7 @@ public class BiquCrawlSource extends BaseHtmlCrawlSource {
String bookName = bookNameMatch.group(1); String bookName = bookNameMatch.group(1);
String author = authorMatch.group(1); bookService.addBookParseLog(bookUrl, bookName, score, (byte) 10);
Boolean hasBook = bookService.hasBook(bookName, author);
if(hasBook) {
bookService.addBookParseLog(bookUrl, bookName, score);
}
} catch (Exception e) { } catch (Exception e) {
@ -106,7 +94,6 @@ public class BiquCrawlSource extends BaseHtmlCrawlSource {
@Override @Override
public void update() { public void update() {
List<BookParseLog> logs = bookService.queryBookParseLogs(); List<BookParseLog> logs = bookService.queryBookParseLogs();
List<Long> successLogIds = new ArrayList<>();
for (BookParseLog bookParseLog : logs) { for (BookParseLog bookParseLog : logs) {
try { try {
@ -139,10 +126,16 @@ public class BiquCrawlSource extends BaseHtmlCrawlSource {
Pattern updateTimePatten = compile(getUpdateTimePattern()); Pattern updateTimePatten = compile(getUpdateTimePattern());
Matcher updateTimeMatch = updateTimePatten.matcher(body); Matcher updateTimeMatch = updateTimePatten.matcher(body);
if (updateTimeMatch.find()) { /*if (updateTimeMatch.find()) {
String updateTimeStr = updateTimeMatch.group(1); String updateTimeStr = updateTimeMatch.group(1);
SimpleDateFormat format = new SimpleDateFormat("yy-MM-dd HH:mm:ss"); SimpleDateFormat format ;
Date updateTime = format.parse(updateTimeStr); if(updateTimeStr.length()>10){
format = new SimpleDateFormat("yy-MM-dd HH:mm:ss");
}else{
format = new SimpleDateFormat("yy-MM-dd");
}
Date updateTime = format.parse(updateTimeStr);*/
Pattern picPatten = compile(getPicPattern()); Pattern picPatten = compile(getPicPattern());
Matcher picMather = picPatten.matcher(body); Matcher picMather = picPatten.matcher(body);
if (picMather.find()) { if (picMather.find()) {
@ -159,7 +152,7 @@ public class BiquCrawlSource extends BaseHtmlCrawlSource {
book.setScore(score > 10 ? 8.0f : score); book.setScore(score > 10 ? 8.0f : score);
book.setPicUrl(picSrc); book.setPicUrl(picSrc);
book.setBookStatus(status); book.setBookStatus(status);
book.setUpdateTime(updateTime); book.setUpdateTime(new Date());
List<BookIndex> indexList = new ArrayList<>(); List<BookIndex> indexList = new ArrayList<>();
List<BookContent> contentList = new ArrayList<>(); List<BookContent> contentList = new ArrayList<>();
@ -180,8 +173,11 @@ public class BiquCrawlSource extends BaseHtmlCrawlSource {
//查询该书籍已存在目录号 //查询该书籍已存在目录号
Map<Integer, BookIndex> hasIndexs = bookService.queryIndexByBookNameAndAuthor(bookName, author); Map<Integer, BookIndex> hasIndexs = bookService.queryIndexByBookNameAndAuthor(bookName, author);
//查询数据库书籍数量
long bookNumber = bookService.queryBookNumber();
//更新和插入分别开,此处只做更新 //更新和插入分别开,此处只做更新
if (hasIndexs.size() > 0) { if (hasIndexs.size() > 0 || bookNumber < maxNumBooks) {
while (isFindIndex) { while (isFindIndex) {
BookIndex hasIndex = hasIndexs.get(indexNum); BookIndex hasIndex = hasIndexs.get(indexNum);
String indexName = indexListMatch.group(2); String indexName = indexListMatch.group(2);
@ -222,7 +218,7 @@ public class BiquCrawlSource extends BaseHtmlCrawlSource {
} }
} }
successLogIds.add(bookParseLog.getId()); bookService.deleteBookParseLog(bookParseLog.getId());
} }
@ -231,7 +227,7 @@ public class BiquCrawlSource extends BaseHtmlCrawlSource {
} }
} //}
} }
} }
@ -247,7 +243,7 @@ public class BiquCrawlSource extends BaseHtmlCrawlSource {
} }
} }
bookService.deleteBookParseLogs(successLogIds);
} }

View File

@ -31,6 +31,9 @@ public class StartListener implements ServletContextListener {
@Value("${website.domain}") @Value("${website.domain}")
private String webSiteDomain; private String webSiteDomain;
@Value("${books.updatePeriod}")
private float bookUpdatePeriod;
private final SeoConfig seoConfig; private final SeoConfig seoConfig;
@ -47,10 +50,23 @@ public class StartListener implements ServletContextListener {
while (true) { while (true) {
try { try {
log.info("crawlBooks执行中。。。。。。。。。。。。"); log.info("parseBooks执行中。。。。。。。。。。。。");
crawlSource.parse(); crawlSource.parse();
Thread.sleep(new Float(1000 * 60 * bookUpdatePeriod).longValue());
} catch (Exception e) {
log.error(e.getMessage(), e);
}
Thread.sleep(1000 * 60 * 5); }
}).start();
new Thread(() -> {
while (true) {
try {
log.info("updateBooks执行中。。。。。。。。。。。。");
crawlSource.update();
Thread.sleep(2000);
} catch (Exception e) { } catch (Exception e) {
log.error(e.getMessage(), e); log.error(e.getMessage(), e);
} }

View File

@ -42,13 +42,16 @@ public class Network2LocalPicSchedule {
log.info("Network2LocalPicSchedule。。。。。。。。。。。。"); log.info("Network2LocalPicSchedule。。。。。。。。。。。。");
Integer offset = 0, limit = 100; Integer offset = 0, limit = 100;
List<Book> networkPicBooks; List<Book> networkPicBooks;
do { do {
networkPicBooks = bookService.queryNetworkPicBooks(limit, offset); networkPicBooks = bookService.queryNetworkPicBooks(limit, offset);
for (Book book : networkPicBooks) { for (Book book : networkPicBooks) {
bookService.updateBook(book, book.getId()); try {
bookService.networkPicToLocal(book);
} catch (Exception e) {
log.error(e.getMessage(), e);
}
} }
offset += limit; offset += limit;
} while (networkPicBooks.size() > 0); } while (networkPicBooks.size() > 0);

View File

@ -1,39 +0,0 @@
package xyz.zinglizingli.books.core.schedule;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import xyz.zinglizingli.books.core.crawl.BaseCrawlSource;
import xyz.zinglizingli.books.po.Book;
import xyz.zinglizingli.books.service.BookService;
import java.util.List;
/**
* 定时更新
*
* @author 11797
*/
@Service
@RequiredArgsConstructor
@Slf4j
public class UpdateBookSchedule {
private final BaseCrawlSource crawlSource;
/**
* 10分钟更新一次
*/
@Scheduled(fixedRate = 1000 * 60 * 10)
public void updateBook() {
log.info("UpdateBookSchedule。。。。。。。。。。。。");
crawlSource.update();
}
}

View File

@ -27,4 +27,15 @@ public interface BookParseLogMapper {
int updateByPrimaryKeySelective(BookParseLog record); int updateByPrimaryKeySelective(BookParseLog record);
int updateByPrimaryKey(BookParseLog record); int updateByPrimaryKey(BookParseLog record);
/**
* 增加小说更新次数
*
* @param logs*/
void addBookUpdateCount(List<BookParseLog> logs);
/**
* 查询解析日志
* */
List<BookParseLog> queryBookParseLogs();
} }

View File

@ -0,0 +1,30 @@
package xyz.zinglizingli.books.mapper;
import java.util.List;
import org.apache.ibatis.annotations.Param;
import xyz.zinglizingli.books.po.BookUpdateTimeLog;
import xyz.zinglizingli.books.po.BookUpdateTimeLogExample;
public interface BookUpdateTimeLogMapper {
int countByExample(BookUpdateTimeLogExample example);
int deleteByExample(BookUpdateTimeLogExample example);
int deleteByPrimaryKey(Integer id);
int insert(BookUpdateTimeLog record);
int insertSelective(BookUpdateTimeLog record);
List<BookUpdateTimeLog> selectByExample(BookUpdateTimeLogExample example);
BookUpdateTimeLog selectByPrimaryKey(Integer id);
int updateByExampleSelective(@Param("record") BookUpdateTimeLog record, @Param("example") BookUpdateTimeLogExample example);
int updateByExample(@Param("record") BookUpdateTimeLog record, @Param("example") BookUpdateTimeLogExample example);
int updateByPrimaryKeySelective(BookUpdateTimeLog record);
int updateByPrimaryKey(BookUpdateTimeLog record);
}

View File

@ -13,6 +13,10 @@ public class BookParseLog {
private Date createTime; private Date createTime;
private Byte priority;
private Byte updateCount;
public Long getId() { public Long getId() {
return id; return id;
} }
@ -52,4 +56,20 @@ public class BookParseLog {
public void setCreateTime(Date createTime) { public void setCreateTime(Date createTime) {
this.createTime = createTime; this.createTime = createTime;
} }
public Byte getPriority() {
return priority;
}
public void setPriority(Byte priority) {
this.priority = priority;
}
public Byte getUpdateCount() {
return updateCount;
}
public void setUpdateCount(Byte updateCount) {
this.updateCount = updateCount;
}
} }

View File

@ -424,6 +424,126 @@ public class BookParseLogExample {
addCriterion("create_time not between", value1, value2, "createTime"); addCriterion("create_time not between", value1, value2, "createTime");
return (Criteria) this; return (Criteria) this;
} }
public Criteria andPriorityIsNull() {
addCriterion("priority is null");
return (Criteria) this;
}
public Criteria andPriorityIsNotNull() {
addCriterion("priority is not null");
return (Criteria) this;
}
public Criteria andPriorityEqualTo(Byte value) {
addCriterion("priority =", value, "priority");
return (Criteria) this;
}
public Criteria andPriorityNotEqualTo(Byte value) {
addCriterion("priority <>", value, "priority");
return (Criteria) this;
}
public Criteria andPriorityGreaterThan(Byte value) {
addCriterion("priority >", value, "priority");
return (Criteria) this;
}
public Criteria andPriorityGreaterThanOrEqualTo(Byte value) {
addCriterion("priority >=", value, "priority");
return (Criteria) this;
}
public Criteria andPriorityLessThan(Byte value) {
addCriterion("priority <", value, "priority");
return (Criteria) this;
}
public Criteria andPriorityLessThanOrEqualTo(Byte value) {
addCriterion("priority <=", value, "priority");
return (Criteria) this;
}
public Criteria andPriorityIn(List<Byte> values) {
addCriterion("priority in", values, "priority");
return (Criteria) this;
}
public Criteria andPriorityNotIn(List<Byte> values) {
addCriterion("priority not in", values, "priority");
return (Criteria) this;
}
public Criteria andPriorityBetween(Byte value1, Byte value2) {
addCriterion("priority between", value1, value2, "priority");
return (Criteria) this;
}
public Criteria andPriorityNotBetween(Byte value1, Byte value2) {
addCriterion("priority not between", value1, value2, "priority");
return (Criteria) this;
}
public Criteria andUpdateCountIsNull() {
addCriterion("update_count is null");
return (Criteria) this;
}
public Criteria andUpdateCountIsNotNull() {
addCriterion("update_count is not null");
return (Criteria) this;
}
public Criteria andUpdateCountEqualTo(Byte value) {
addCriterion("update_count =", value, "updateCount");
return (Criteria) this;
}
public Criteria andUpdateCountNotEqualTo(Byte value) {
addCriterion("update_count <>", value, "updateCount");
return (Criteria) this;
}
public Criteria andUpdateCountGreaterThan(Byte value) {
addCriterion("update_count >", value, "updateCount");
return (Criteria) this;
}
public Criteria andUpdateCountGreaterThanOrEqualTo(Byte value) {
addCriterion("update_count >=", value, "updateCount");
return (Criteria) this;
}
public Criteria andUpdateCountLessThan(Byte value) {
addCriterion("update_count <", value, "updateCount");
return (Criteria) this;
}
public Criteria andUpdateCountLessThanOrEqualTo(Byte value) {
addCriterion("update_count <=", value, "updateCount");
return (Criteria) this;
}
public Criteria andUpdateCountIn(List<Byte> values) {
addCriterion("update_count in", values, "updateCount");
return (Criteria) this;
}
public Criteria andUpdateCountNotIn(List<Byte> values) {
addCriterion("update_count not in", values, "updateCount");
return (Criteria) this;
}
public Criteria andUpdateCountBetween(Byte value1, Byte value2) {
addCriterion("update_count between", value1, value2, "updateCount");
return (Criteria) this;
}
public Criteria andUpdateCountNotBetween(Byte value1, Byte value2) {
addCriterion("update_count not between", value1, value2, "updateCount");
return (Criteria) this;
}
} }
public static class Criteria extends GeneratedCriteria { public static class Criteria extends GeneratedCriteria {

View File

@ -0,0 +1,35 @@
package xyz.zinglizingli.books.po;
import java.util.Date;
public class BookUpdateTimeLog {
private Integer id;
private Integer bookCatId;
private Date lastUpdateTime;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Integer getBookCatId() {
return bookCatId;
}
public void setBookCatId(Integer bookCatId) {
this.bookCatId = bookCatId;
}
public Date getLastUpdateTime() {
return lastUpdateTime;
}
public void setLastUpdateTime(Date lastUpdateTime) {
this.lastUpdateTime = lastUpdateTime;
}
}

View File

@ -0,0 +1,381 @@
package xyz.zinglizingli.books.po;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
public class BookUpdateTimeLogExample {
protected String orderByClause;
protected boolean distinct;
protected List<Criteria> oredCriteria;
public BookUpdateTimeLogExample() {
oredCriteria = new ArrayList<Criteria>();
}
public void setOrderByClause(String orderByClause) {
this.orderByClause = orderByClause;
}
public String getOrderByClause() {
return orderByClause;
}
public void setDistinct(boolean distinct) {
this.distinct = distinct;
}
public boolean isDistinct() {
return distinct;
}
public List<Criteria> getOredCriteria() {
return oredCriteria;
}
public void or(Criteria criteria) {
oredCriteria.add(criteria);
}
public Criteria or() {
Criteria criteria = createCriteriaInternal();
oredCriteria.add(criteria);
return criteria;
}
public Criteria createCriteria() {
Criteria criteria = createCriteriaInternal();
if (oredCriteria.size() == 0) {
oredCriteria.add(criteria);
}
return criteria;
}
protected Criteria createCriteriaInternal() {
Criteria criteria = new Criteria();
return criteria;
}
public void clear() {
oredCriteria.clear();
orderByClause = null;
distinct = false;
}
protected abstract static class GeneratedCriteria {
protected List<Criterion> criteria;
protected GeneratedCriteria() {
super();
criteria = new ArrayList<Criterion>();
}
public boolean isValid() {
return criteria.size() > 0;
}
public List<Criterion> getAllCriteria() {
return criteria;
}
public List<Criterion> getCriteria() {
return criteria;
}
protected void addCriterion(String condition) {
if (condition == null) {
throw new RuntimeException("Value for condition cannot be null");
}
criteria.add(new Criterion(condition));
}
protected void addCriterion(String condition, Object value, String property) {
if (value == null) {
throw new RuntimeException("Value for " + property + " cannot be null");
}
criteria.add(new Criterion(condition, value));
}
protected void addCriterion(String condition, Object value1, Object value2, String property) {
if (value1 == null || value2 == null) {
throw new RuntimeException("Between values for " + property + " cannot be null");
}
criteria.add(new Criterion(condition, value1, value2));
}
public Criteria andIdIsNull() {
addCriterion("id is null");
return (Criteria) this;
}
public Criteria andIdIsNotNull() {
addCriterion("id is not null");
return (Criteria) this;
}
public Criteria andIdEqualTo(Integer value) {
addCriterion("id =", value, "id");
return (Criteria) this;
}
public Criteria andIdNotEqualTo(Integer value) {
addCriterion("id <>", value, "id");
return (Criteria) this;
}
public Criteria andIdGreaterThan(Integer value) {
addCriterion("id >", value, "id");
return (Criteria) this;
}
public Criteria andIdGreaterThanOrEqualTo(Integer value) {
addCriterion("id >=", value, "id");
return (Criteria) this;
}
public Criteria andIdLessThan(Integer value) {
addCriterion("id <", value, "id");
return (Criteria) this;
}
public Criteria andIdLessThanOrEqualTo(Integer value) {
addCriterion("id <=", value, "id");
return (Criteria) this;
}
public Criteria andIdIn(List<Integer> values) {
addCriterion("id in", values, "id");
return (Criteria) this;
}
public Criteria andIdNotIn(List<Integer> values) {
addCriterion("id not in", values, "id");
return (Criteria) this;
}
public Criteria andIdBetween(Integer value1, Integer value2) {
addCriterion("id between", value1, value2, "id");
return (Criteria) this;
}
public Criteria andIdNotBetween(Integer value1, Integer value2) {
addCriterion("id not between", value1, value2, "id");
return (Criteria) this;
}
public Criteria andBookCatIdIsNull() {
addCriterion("book_cat_id is null");
return (Criteria) this;
}
public Criteria andBookCatIdIsNotNull() {
addCriterion("book_cat_id is not null");
return (Criteria) this;
}
public Criteria andBookCatIdEqualTo(Integer value) {
addCriterion("book_cat_id =", value, "bookCatId");
return (Criteria) this;
}
public Criteria andBookCatIdNotEqualTo(Integer value) {
addCriterion("book_cat_id <>", value, "bookCatId");
return (Criteria) this;
}
public Criteria andBookCatIdGreaterThan(Integer value) {
addCriterion("book_cat_id >", value, "bookCatId");
return (Criteria) this;
}
public Criteria andBookCatIdGreaterThanOrEqualTo(Integer value) {
addCriterion("book_cat_id >=", value, "bookCatId");
return (Criteria) this;
}
public Criteria andBookCatIdLessThan(Integer value) {
addCriterion("book_cat_id <", value, "bookCatId");
return (Criteria) this;
}
public Criteria andBookCatIdLessThanOrEqualTo(Integer value) {
addCriterion("book_cat_id <=", value, "bookCatId");
return (Criteria) this;
}
public Criteria andBookCatIdIn(List<Integer> values) {
addCriterion("book_cat_id in", values, "bookCatId");
return (Criteria) this;
}
public Criteria andBookCatIdNotIn(List<Integer> values) {
addCriterion("book_cat_id not in", values, "bookCatId");
return (Criteria) this;
}
public Criteria andBookCatIdBetween(Integer value1, Integer value2) {
addCriterion("book_cat_id between", value1, value2, "bookCatId");
return (Criteria) this;
}
public Criteria andBookCatIdNotBetween(Integer value1, Integer value2) {
addCriterion("book_cat_id not between", value1, value2, "bookCatId");
return (Criteria) this;
}
public Criteria andLastUpdateTimeIsNull() {
addCriterion("last_update_time is null");
return (Criteria) this;
}
public Criteria andLastUpdateTimeIsNotNull() {
addCriterion("last_update_time is not null");
return (Criteria) this;
}
public Criteria andLastUpdateTimeEqualTo(Date value) {
addCriterion("last_update_time =", value, "lastUpdateTime");
return (Criteria) this;
}
public Criteria andLastUpdateTimeNotEqualTo(Date value) {
addCriterion("last_update_time <>", value, "lastUpdateTime");
return (Criteria) this;
}
public Criteria andLastUpdateTimeGreaterThan(Date value) {
addCriterion("last_update_time >", value, "lastUpdateTime");
return (Criteria) this;
}
public Criteria andLastUpdateTimeGreaterThanOrEqualTo(Date value) {
addCriterion("last_update_time >=", value, "lastUpdateTime");
return (Criteria) this;
}
public Criteria andLastUpdateTimeLessThan(Date value) {
addCriterion("last_update_time <", value, "lastUpdateTime");
return (Criteria) this;
}
public Criteria andLastUpdateTimeLessThanOrEqualTo(Date value) {
addCriterion("last_update_time <=", value, "lastUpdateTime");
return (Criteria) this;
}
public Criteria andLastUpdateTimeIn(List<Date> values) {
addCriterion("last_update_time in", values, "lastUpdateTime");
return (Criteria) this;
}
public Criteria andLastUpdateTimeNotIn(List<Date> values) {
addCriterion("last_update_time not in", values, "lastUpdateTime");
return (Criteria) this;
}
public Criteria andLastUpdateTimeBetween(Date value1, Date value2) {
addCriterion("last_update_time between", value1, value2, "lastUpdateTime");
return (Criteria) this;
}
public Criteria andLastUpdateTimeNotBetween(Date value1, Date value2) {
addCriterion("last_update_time not between", value1, value2, "lastUpdateTime");
return (Criteria) this;
}
}
public static class Criteria extends GeneratedCriteria {
protected Criteria() {
super();
}
}
public static class Criterion {
private String condition;
private Object value;
private Object secondValue;
private boolean noValue;
private boolean singleValue;
private boolean betweenValue;
private boolean listValue;
private String typeHandler;
public String getCondition() {
return condition;
}
public Object getValue() {
return value;
}
public Object getSecondValue() {
return secondValue;
}
public boolean isNoValue() {
return noValue;
}
public boolean isSingleValue() {
return singleValue;
}
public boolean isBetweenValue() {
return betweenValue;
}
public boolean isListValue() {
return listValue;
}
public String getTypeHandler() {
return typeHandler;
}
protected Criterion(String condition) {
super();
this.condition = condition;
this.typeHandler = null;
this.noValue = true;
}
protected Criterion(String condition, Object value, String typeHandler) {
super();
this.condition = condition;
this.value = value;
this.typeHandler = typeHandler;
if (value instanceof List<?>) {
this.listValue = true;
} else {
this.singleValue = true;
}
}
protected Criterion(String condition, Object value) {
this(condition, value, null);
}
protected Criterion(String condition, Object value, Object secondValue, String typeHandler) {
super();
this.condition = condition;
this.value = value;
this.secondValue = secondValue;
this.typeHandler = typeHandler;
this.betweenValue = true;
}
protected Criterion(String condition, Object value, Object secondValue) {
this(condition, value, secondValue, null);
}
}
}

View File

@ -3,30 +3,21 @@ package xyz.zinglizingli.books.service;
import com.github.pagehelper.PageHelper; import com.github.pagehelper.PageHelper;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.Charsets;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.apache.http.client.utils.DateUtils;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.Resource; import org.springframework.scheduling.annotation.Async;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.orderbyhelper.OrderByHelper; import tk.mybatis.orderbyhelper.OrderByHelper;
import xyz.zinglizingli.books.core.constant.CacheKeyConstans; import xyz.zinglizingli.books.core.constant.CacheKeyConstans;
import xyz.zinglizingli.books.core.enums.PicSaveType; import xyz.zinglizingli.books.core.enums.PicSaveType;
import xyz.zinglizingli.books.core.utils.Constants;
import xyz.zinglizingli.books.mapper.*; import xyz.zinglizingli.books.mapper.*;
import xyz.zinglizingli.books.po.*; import xyz.zinglizingli.books.po.*;
import xyz.zinglizingli.books.core.utils.Constants; import xyz.zinglizingli.common.cache.CommonCacheUtil;
import xyz.zinglizingli.common.utils.FileUtil; import xyz.zinglizingli.common.utils.FileUtil;
import xyz.zinglizingli.common.utils.SpringUtil; import xyz.zinglizingli.common.utils.SpringUtil;
import xyz.zinglizingli.common.utils.UUIDUtils;
import xyz.zinglizingli.common.cache.CommonCacheUtil;
import xyz.zinglizingli.common.utils.RestTemplateUtil;
import java.io.*;
import java.util.*; import java.util.*;
import java.util.function.Function; import java.util.function.Function;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ -51,6 +42,8 @@ public class BookService {
private final BookParseLogMapper bookParseLogMapper; private final BookParseLogMapper bookParseLogMapper;
private final BookUpdateTimeLogMapper bookUpdateTimeLogMapper;
private final CommonCacheUtil cacheUtil; private final CommonCacheUtil cacheUtil;
@ -61,11 +54,10 @@ public class BookService {
private String picSavePath; private String picSavePath;
/** /**
* 保存章节目录和内容 * 保存章节目录和内容
* */ */
public void saveBookAndIndexAndContent(Book book, List<BookIndex> bookIndex, List<BookContent> bookContent){ public void saveBookAndIndexAndContent(Book book, List<BookIndex> bookIndex, List<BookContent> bookContent) {
//解决内部调用事物不生效的问题 //解决内部调用事物不生效的问题
BookService bookService = SpringUtil.getBean(BookService.class); BookService bookService = SpringUtil.getBean(BookService.class);
@ -79,7 +71,7 @@ public class BookService {
if (books.size() > 0) { if (books.size() > 0) {
//更新 //更新
bookId = books.get(0).getId(); bookId = books.get(0).getId();
if(picSaveType == PicSaveType.LOCAL.getValue() && books.get(0).getPicUrl().startsWith(Constants.LOCAL_PIC_PREFIX)){ if (picSaveType == PicSaveType.LOCAL.getValue() && books.get(0).getPicUrl().startsWith(Constants.LOCAL_PIC_PREFIX)) {
book.setPicUrl(null); book.setPicUrl(null);
} }
updateBook(book, bookId); updateBook(book, bookId);
@ -132,8 +124,6 @@ public class BookService {
bookService.insertIndexListAndContentList(newBookIndexList, newContentList); bookService.insertIndexListAndContentList(newBookIndexList, newContentList);
} }
cacheUtil.del(CacheKeyConstans.NEWST_BOOK_LIST_KEY);
} }
@ -142,31 +132,45 @@ public class BookService {
/** /**
* 更新书籍 * 更新书籍
* */ */
public void updateBook(Book book, Long bookId) { public void updateBook(Book book, Long bookId) {
book.setId(bookId); book.setId(bookId);
String picSrc = book.getPicUrl(); String picSrc = book.getPicUrl();
if(picSaveType == PicSaveType.LOCAL.getValue() && StringUtils.isNotBlank(picSrc)){ if (picSaveType == PicSaveType.LOCAL.getValue() && StringUtils.isNotBlank(picSrc)) {
try { try {
picSrc = FileUtil.network2Local(picSrc,picSavePath); picSrc = FileUtil.network2Local(picSrc, picSavePath);
book.setPicUrl(picSrc); book.setPicUrl(picSrc);
}catch (Exception e){ } catch (Exception e) {
log.error(e.getMessage(),e); log.error(e.getMessage(), e);
} }
} }
bookMapper.updateByPrimaryKeySelective(book); bookMapper.updateByPrimaryKeySelective(book);
} }
/**
* 网络图片转本地
*
* @param book
*/
public void networkPicToLocal(Book book) {
try {
book.setPicUrl(FileUtil.network2Local(book.getPicUrl(), picSavePath));
bookMapper.updateByPrimaryKeySelective(book);
} catch (Exception e) {
log.error(e.getMessage(), e);
}
}
/** /**
* 批量插入章节目录表和章节内容表(自动修复错误章节) * 批量插入章节目录表和章节内容表(自动修复错误章节)
* */ */
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void insertIndexListAndContentList(List<BookIndex> newBookIndexList, List<BookContent> newContentList) { public void insertIndexListAndContentList(List<BookIndex> newBookIndexList, List<BookContent> newContentList) {
long start = System.currentTimeMillis(); long start = System.currentTimeMillis();
if(newBookIndexList.size() > 0) { if (newBookIndexList.size() > 0) {
//删除已存在的错误章节 //删除已存在的错误章节
List<Integer> indexNumberList = newBookIndexList.stream().map(BookIndex::getIndexNum).collect(Collectors.toList()); List<Integer> indexNumberList = newBookIndexList.stream().map(BookIndex::getIndexNum).collect(Collectors.toList());
Long bookId = newBookIndexList.get(0).getBookId(); Long bookId = newBookIndexList.get(0).getBookId();
@ -181,15 +185,15 @@ public class BookService {
bookIndexMapper.insertBatch(newBookIndexList); bookIndexMapper.insertBatch(newBookIndexList);
bookContentMapper.insertBatch(newContentList); bookContentMapper.insertBatch(newContentList);
} }
log.info("更新章节耗时:"+(System.currentTimeMillis()-start)); log.info("更新章节耗时:" + (System.currentTimeMillis() - start));
} }
/** /**
* 生成随机访问次数 * 生成随机访问次数
* */ */
private Long generateVisitCount(Float score) { private Long generateVisitCount(Float score) {
int baseNum = (int)(score * 100); int baseNum = (int) (score * 100);
return Long.parseLong(baseNum + new Random().nextInt(1000) + ""); return Long.parseLong(baseNum + new Random().nextInt(1000) + "");
} }
@ -214,10 +218,9 @@ public class BookService {
} }
/** /**
* 查询书籍的基础数据 * 查询书籍的基础数据
* */ */
public Book queryBaseInfo(Long bookId) { public Book queryBaseInfo(Long bookId) {
return bookMapper.selectByPrimaryKey(bookId); return bookMapper.selectByPrimaryKey(bookId);
@ -225,7 +228,7 @@ public class BookService {
/** /**
* 查询最新更新的书籍列表 * 查询最新更新的书籍列表
* */ */
public List<BookIndex> queryNewIndexList(Long bookId) { public List<BookIndex> queryNewIndexList(Long bookId) {
PageHelper.startPage(1, 15); PageHelper.startPage(1, 15);
BookIndexExample example = new BookIndexExample(); BookIndexExample example = new BookIndexExample();
@ -237,7 +240,7 @@ public class BookService {
/** /**
* 查询书籍目录列表 * 查询书籍目录列表
* */ */
public List<BookIndex> queryAllIndexList(Long bookId) { public List<BookIndex> queryAllIndexList(Long bookId) {
BookIndexExample example = new BookIndexExample(); BookIndexExample example = new BookIndexExample();
example.createCriteria().andBookIdEqualTo(bookId); example.createCriteria().andBookIdEqualTo(bookId);
@ -247,7 +250,7 @@ public class BookService {
/** /**
* 查询书籍章节内容 * 查询书籍章节内容
* */ */
public BookContent queryBookContent(Long bookId, Integer indexNum) { public BookContent queryBookContent(Long bookId, Integer indexNum) {
BookContent content = (BookContent) cacheUtil.getObject(CacheKeyConstans.BOOK_CONTENT_KEY_PREFIX + "_" + bookId + "_" + indexNum); BookContent content = (BookContent) cacheUtil.getObject(CacheKeyConstans.BOOK_CONTENT_KEY_PREFIX + "_" + bookId + "_" + indexNum);
if (content == null) { if (content == null) {
@ -255,7 +258,7 @@ public class BookService {
example.createCriteria().andBookIdEqualTo(bookId).andIndexNumEqualTo(indexNum); example.createCriteria().andBookIdEqualTo(bookId).andIndexNumEqualTo(indexNum);
List<BookContent> bookContents = bookContentMapper.selectByExample(example); List<BookContent> bookContents = bookContentMapper.selectByExample(example);
content = bookContents.size() > 0 ? bookContents.get(0) : null; content = bookContents.size() > 0 ? bookContents.get(0) : null;
cacheUtil.setObject(CacheKeyConstans.BOOK_CONTENT_KEY_PREFIX + "_" + bookId + "_" + indexNum, content, 60 * 60 * 24); cacheUtil.setObject(CacheKeyConstans.BOOK_CONTENT_KEY_PREFIX + "_" + bookId + "_" + indexNum, content, 60 * 10);
} }
return content; return content;
@ -264,12 +267,12 @@ public class BookService {
/** /**
* 增加访问次数 * 增加访问次数
* */ */
public void addVisitCount(Long bookId, String userId, Integer indexNum) { public void addVisitCount(Long bookId, String userId, Integer indexNum) {
bookMapper.addVisitCount(bookId); bookMapper.addVisitCount(bookId);
if(org.apache.commons.lang3.StringUtils.isNotBlank(userId)) { if (org.apache.commons.lang3.StringUtils.isNotBlank(userId)) {
userRefBookMapper.updateNewstIndex(bookId, userId, indexNum); userRefBookMapper.updateNewstIndex(bookId, userId, indexNum);
} }
@ -277,13 +280,13 @@ public class BookService {
/** /**
* 查询章节名 * 查询章节名
* */ */
public String queryIndexNameByBookIdAndIndexNum(Long bookId, Integer indexNum) { public String queryIndexNameByBookIdAndIndexNum(Long bookId, Integer indexNum) {
BookIndexExample example = new BookIndexExample(); BookIndexExample example = new BookIndexExample();
example.createCriteria().andBookIdEqualTo(bookId).andIndexNumEqualTo(indexNum); example.createCriteria().andBookIdEqualTo(bookId).andIndexNumEqualTo(indexNum);
List<BookIndex> indexList = bookIndexMapper.selectByExample(example); List<BookIndex> indexList = bookIndexMapper.selectByExample(example);
if(indexList != null && indexList.size() > 0 ) { if (indexList != null && indexList.size() > 0) {
return indexList.get(0).getIndexName(); return indexList.get(0).getIndexName();
} }
return null; return null;
@ -291,7 +294,7 @@ public class BookService {
/** /**
* 查询最大和最小章节号 * 查询最大和最小章节号
* */ */
public List<Integer> queryMaxAndMinIndexNum(Long bookId) { public List<Integer> queryMaxAndMinIndexNum(Long bookId) {
List<Integer> result = new ArrayList<>(); List<Integer> result = new ArrayList<>();
BookIndexExample example = new BookIndexExample(); BookIndexExample example = new BookIndexExample();
@ -308,7 +311,7 @@ public class BookService {
/** /**
* 查询该书籍已存在目录号 * 查询该书籍已存在目录号
*/ */
public Map<Integer,BookIndex> queryIndexByBookNameAndAuthor(String bookName, String author) { public Map<Integer, BookIndex> queryIndexByBookNameAndAuthor(String bookName, String author) {
BookExample example = new BookExample(); BookExample example = new BookExample();
example.createCriteria().andBookNameEqualTo(bookName).andAuthorEqualTo(author); example.createCriteria().andBookNameEqualTo(bookName).andAuthorEqualTo(author);
List<Book> books = bookMapper.selectByExample(example); List<Book> books = bookMapper.selectByExample(example);
@ -318,7 +321,7 @@ public class BookService {
BookIndexExample bookIndexExample = new BookIndexExample(); BookIndexExample bookIndexExample = new BookIndexExample();
bookIndexExample.createCriteria().andBookIdEqualTo(bookId); bookIndexExample.createCriteria().andBookIdEqualTo(bookId);
List<BookIndex> bookIndices = bookIndexMapper.selectByExample(bookIndexExample); List<BookIndex> bookIndices = bookIndexMapper.selectByExample(bookIndexExample);
if(bookIndices.size() > 0) { if (bookIndices.size() > 0) {
return bookIndices.stream().collect(Collectors.toMap(BookIndex::getIndexNum, Function.identity())); return bookIndices.stream().collect(Collectors.toMap(BookIndex::getIndexNum, Function.identity()));
} }
@ -329,11 +332,9 @@ public class BookService {
} }
/** /**
* 保存弹幕 * 保存弹幕
* */ */
public void sendBullet(Long contentId, String bullet) { public void sendBullet(Long contentId, String bullet) {
ScreenBullet screenBullet = new ScreenBullet(); ScreenBullet screenBullet = new ScreenBullet();
@ -346,7 +347,7 @@ public class BookService {
/** /**
* 查询弹幕 * 查询弹幕
* */ */
public List<ScreenBullet> queryBullet(Long contentId) { public List<ScreenBullet> queryBullet(Long contentId) {
ScreenBulletExample example = new ScreenBulletExample(); ScreenBulletExample example = new ScreenBulletExample();
@ -359,7 +360,7 @@ public class BookService {
/** /**
* 查询章节内容 * 查询章节内容
* */ */
public String queryContentList(Long bookId, int count) { public String queryContentList(Long bookId, int count) {
BookContentExample example = new BookContentExample(); BookContentExample example = new BookContentExample();
example.createCriteria().andBookIdEqualTo(bookId).andIndexNumEqualTo(count); example.createCriteria().andBookIdEqualTo(bookId).andIndexNumEqualTo(count);
@ -368,7 +369,7 @@ public class BookService {
/** /**
* 查询章节数 * 查询章节数
* */ */
public int countIndex(Long bookId) { public int countIndex(Long bookId) {
BookIndexExample example = new BookIndexExample(); BookIndexExample example = new BookIndexExample();
example.createCriteria().andBookIdEqualTo(bookId); example.createCriteria().andBookIdEqualTo(bookId);
@ -376,11 +377,9 @@ public class BookService {
} }
/** /**
* 查询前一章节和后一章节号 * 查询前一章节和后一章节号
* */ */
public List<Integer> queryPreAndNextIndexNum(Long bookId, Integer indexNum) { public List<Integer> queryPreAndNextIndexNum(Long bookId, Integer indexNum) {
List<Integer> result = new ArrayList<>(); List<Integer> result = new ArrayList<>();
BookIndexExample example = new BookIndexExample(); BookIndexExample example = new BookIndexExample();
@ -407,14 +406,14 @@ public class BookService {
/** /**
* 查询推荐书籍数据 * 查询推荐书籍数据
* */ */
public List<Book> queryRecBooks(List<Map<String, String>> configMap) { public List<Book> queryRecBooks(List<Map<String, String>> configMap) {
return bookMapper.queryRecBooks(configMap); return bookMapper.queryRecBooks(configMap);
} }
/** /**
* 清理数据库中无效数据 * 清理数据库中无效数据
* */ */
public void clearInvilidData() { public void clearInvilidData() {
//清除无效内容 //清除无效内容
@ -431,31 +430,33 @@ public class BookService {
* 查询网络图片的小说 * 查询网络图片的小说
* *
* @param limit * @param limit
* @param offset*/ * @param offset
*/
public List<Book> queryNetworkPicBooks(Integer limit, Integer offset) { public List<Book> queryNetworkPicBooks(Integer limit, Integer offset) {
return bookMapper.queryNetworkPicBooks(limit,offset); return bookMapper.queryNetworkPicBooks(limit, offset);
} }
/** /**
* 通过图片名查询小说数量 * 通过图片名查询小说数量
* */ */
public int countByPicName(String fileName) { public int countByPicName(String fileName) {
BookExample bookExample = new BookExample(); BookExample bookExample = new BookExample();
bookExample.createCriteria().andPicUrlLike('%'+fileName+'%'); bookExample.createCriteria().andPicUrlLike('%' + fileName + '%');
return bookMapper.countByExample(bookExample); return bookMapper.countByExample(bookExample);
} }
/** /**
* 添加解析日志 * 添加解析日志
* */ */
public void addBookParseLog(String bookUrl, String bookName, Float score) { public void addBookParseLog(String bookUrl, String bookName, Float score, Byte priority) {
BookParseLogExample example = new BookParseLogExample(); BookParseLogExample example = new BookParseLogExample();
example.createCriteria().andBookUrlEqualTo(bookUrl); example.createCriteria().andBookUrlEqualTo(bookUrl).andCreateTimeGreaterThan(new Date(System.currentTimeMillis() - 1000 * 60 * 60));
if(bookParseLogMapper.countByExample(example)==0) { if (bookParseLogMapper.countByExample(example) == 0) {
BookParseLog bookParseLog = new BookParseLog(); BookParseLog bookParseLog = new BookParseLog();
bookParseLog.setBookUrl(bookUrl); bookParseLog.setBookUrl(bookUrl);
bookParseLog.setBookName(bookName); bookParseLog.setBookName(bookName);
bookParseLog.setScore(score); bookParseLog.setScore(score);
bookParseLog.setPriority(priority);
bookParseLog.setCreateTime(new Date()); bookParseLog.setCreateTime(new Date());
bookParseLogMapper.insertSelective(bookParseLog); bookParseLogMapper.insertSelective(bookParseLog);
} }
@ -463,20 +464,28 @@ public class BookService {
/** /**
* 查询解析日志 * 查询解析日志
* */ */
public List<BookParseLog> queryBookParseLogs() { public List<BookParseLog> queryBookParseLogs() {
PageHelper.startPage(1,100); List<BookParseLog> logs = bookParseLogMapper.queryBookParseLogs();
BookParseLogExample example = new BookParseLogExample(); if(logs.size()>0) {
example.setOrderByClause("create_time desc"); SpringUtil.getBean(BookService.class).addBookUpdateCount(logs);
List<BookParseLog> logs = bookParseLogMapper.selectByExample(example); }
return logs; return logs;
} }
/**
* 增加小说更新次数
*/
@Async
public void addBookUpdateCount(List<BookParseLog> logs) {
bookParseLogMapper.addBookUpdateCount(logs);
}
/** /**
* 删除已经成功更新的解析日志 * 删除已经成功更新的解析日志
* */ */
public void deleteBookParseLogs(List<Long> successLogIds) { public void deleteBookParseLogs(List<Long> successLogIds) {
if(successLogIds.size()>0) { if (successLogIds.size() > 0) {
BookParseLogExample example = new BookParseLogExample(); BookParseLogExample example = new BookParseLogExample();
example.createCriteria().andIdIn(successLogIds); example.createCriteria().andIdIn(successLogIds);
bookParseLogMapper.deleteByExample(example); bookParseLogMapper.deleteByExample(example);
@ -485,10 +494,58 @@ public class BookService {
/** /**
* 查询书籍是否存在 * 查询书籍是否存在
* */ */
public Boolean hasBook(String bookName, String author) { public Boolean hasBook(String bookName, String author) {
BookExample example = new BookExample(); BookExample example = new BookExample();
example.createCriteria().andBookNameEqualTo(bookName).andAuthorEqualTo(author); example.createCriteria().andBookNameEqualTo(bookName).andAuthorEqualTo(author);
return bookMapper.countByExample(example)>0; return bookMapper.countByExample(example) > 0;
}
/**
* 查询分类更新时间映射信息
*/
public Map<Integer, Date> queryLastUpdateTime() {
List<BookUpdateTimeLog> list = bookUpdateTimeLogMapper.selectByExample(new BookUpdateTimeLogExample());
return list.stream().collect(Collectors.toMap(BookUpdateTimeLog::getBookCatId, BookUpdateTimeLog::getLastUpdateTime, (key1, key2) -> key2));
}
/**
* 更新分类时间日志
*/
public void updateBookUpdateTimeLog(Map<Integer, Date> cat2Date) {
if (cat2Date.size() > 0) {
Set<Map.Entry<Integer, Date>> entries = cat2Date.entrySet();
for (Map.Entry<Integer, Date> entry : entries) {
BookUpdateTimeLogExample example = new BookUpdateTimeLogExample();
example.createCriteria().andBookCatIdEqualTo(entry.getKey());
BookUpdateTimeLog entity = new BookUpdateTimeLog();
entity.setLastUpdateTime(entry.getValue());
bookUpdateTimeLogMapper.updateByExampleSelective(entity, example);
}
}
}
/**
* 删除已经成功更新的解析日志
*/
public void deleteBookParseLog(Long id) {
bookParseLogMapper.deleteByPrimaryKey(id);
}
/**
* 查询数据库书籍数量
*/
public int queryBookNumber() {
Integer bookNumber = (Integer) cacheUtil.getObject(CacheKeyConstans.BOOK_NUMBER_KEY);
if (bookNumber == null) {
bookNumber = bookMapper.countByExample(new BookExample());
cacheUtil.setObject(CacheKeyConstans.BOOK_NUMBER_KEY, bookNumber, 60 * 5);
}
return bookNumber;
} }
} }

View File

@ -8,15 +8,9 @@ import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap; import org.springframework.ui.ModelMap;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import xyz.zinglizingli.books.core.config.SeoConfig; import xyz.zinglizingli.books.core.config.SeoConfig;
import xyz.zinglizingli.books.po.Book; import xyz.zinglizingli.books.po.*;
import xyz.zinglizingli.books.po.BookContent;
import xyz.zinglizingli.books.po.BookIndex;
import xyz.zinglizingli.books.po.ScreenBullet;
import xyz.zinglizingli.books.service.BookService; import xyz.zinglizingli.books.service.BookService;
import xyz.zinglizingli.books.service.UserService; import xyz.zinglizingli.books.service.UserService;
import xyz.zinglizingli.books.vo.BookVO; import xyz.zinglizingli.books.vo.BookVO;
@ -50,6 +44,27 @@ public class BookController {
private final CommonCacheUtil commonCacheUtil; private final CommonCacheUtil commonCacheUtil;
/**
* 单本小说提交页
* */
@RequestMapping("submit.html")
public String bookSubmitPage(){
return "books/book_submit";
}
/**
* 单本小说提交
* */
@RequestMapping(method = RequestMethod.POST,value = "submit")
@ResponseBody
public Map<String, Object> bookSubmit(String bookUrl, String bookName, Float score){
Map<String, Object> result = new HashMap<>(2);
bookService.addBookParseLog(bookUrl, bookName, score, (byte) 5);
result.put("code", 1);
return result;
}
/** /**
* 精品小说搜索页 * 精品小说搜索页
@ -306,7 +321,7 @@ public class BookController {
@ResponseBody @ResponseBody
public Map<String, Object> sendBullet(@RequestParam("contentId") Long contentId, @RequestParam("bullet") String bullet) { public Map<String, Object> sendBullet(@RequestParam("contentId") Long contentId, @RequestParam("bullet") String bullet) {
Map<String, Object> result = new HashMap<>(2); Map<String, Object> result = new HashMap<>(2);
bookService.sendBullet(contentId, bullet); bookService.sendBullet(contentId, bullet.replaceAll("<", "&lt;").replaceAll(">", "&gt;"));
result.put("code", 1); result.put("code", 1);
result.put("desc", "ok"); result.put("desc", "ok");
return result; return result;

View File

@ -54,6 +54,23 @@ dingdian:
catalog-url-pattern: <a\s+href="(/ddk\d+/all.html)">查看完整目录</a> catalog-url-pattern: <a\s+href="(/ddk\d+/all.html)">查看完整目录</a>
catalog-pattern: <a\s+style=""\s+href="(/ddk\d+/\d+\.html)">([^/]+)</a> catalog-pattern: <a\s+style=""\s+href="(/ddk\d+/\d+\.html)">([^/]+)</a>
baishuzhai:
crawlsource:
index-url: https://m.baishuzhai.com
list-page-url: https://m.baishuzhai.com/sort/{0}/{1}.html
book-url-pattern: href="/(ibook/\d+/\d+)/"
score-pattern: <div\s+class="score">(\d+\.\d+)分</div>
book-name-pattern: <p class="title">([^/]+)</p>
author-pattern: 作者:([^/]+)<
status-pattern: 状态:([^/]+)</li>
cat-pattern: 类别:([^/]+)</li>
update-time-pattern: 更新:(\d+-\d+-\d+)</li>
pic-pattern: <img src="([^>]+)"\s+onerror="this.src=
intro-pattern: class="review">([^/]+)</p>
catalog-url-pattern: <a\s+href="(/ibook/\d+/\d+/all\.html)">查看完整目录</a>
catalog-pattern: <a\s+style=""\s+href="(/ibook/\d+/\d+/\d+\.html)">([^/]+)</a>
biquge: biquge:
crawlsource: crawlsource:
index-url: http://m.biquge.info index-url: http://m.biquge.info
@ -69,3 +86,20 @@ biquge:
intro-pattern: class="review">([^/]+)</p> intro-pattern: class="review">([^/]+)</p>
catalog-url-pattern: <a\s+href="(/ddk\d+/all.html)">查看完整目录</a> catalog-url-pattern: <a\s+href="(/ddk\d+/all.html)">查看完整目录</a>
catalog-pattern: <dd>\s*<a\s+href="(\d+\.html)"\s+title="([^"]+)">([^<]+)</a>\s*</dd> catalog-pattern: <dd>\s*<a\s+href="(\d+\.html)"\s+title="([^"]+)">([^<]+)</a>\s*</dd>
biquwo:
crawlsource:
index-url: http://m.biquwo.net
list-page-url: http://m.biquwo.net/sort{0}/0/{1}.html
book-url-pattern: href="/(dudu/\d+/\d+)/"
score-pattern: <div\s+class="score">(\d+\.\d+)分</div>
book-name-pattern: <p class="title">([^/]+)</p>
author-pattern: 作者:([^/]+)<
status-pattern: 状态:([^/]+)</li>
cat-pattern: 类别:([^/]+)</li>
update-time-pattern: 更新:(\d+-\d+-\d+\s\d+:\d+:\d+)</a>
pic-pattern: <img src="([^>]+)"\s+onerror="this.src=
intro-pattern: class="review">([^<]+)</p>
catalog-url-pattern: <a\s+href="(/dudu/\d+/\d+/all\.html)">查看完整目录</a>
catalog-pattern: <a\s+style=""\s+href="(/dudu/\d+/\d+/\d+\.html)">([^/]+)</a>

View File

@ -1,7 +1,7 @@
#网站配置 #网站配置
website: website:
#网站名 #网站名
name: 小说精品屋 name: 精品小说楼
#域名 #域名
domain: https://www.xinshumen.com domain: https://www.xinshumen.com
#页面配置 #页面配置

View File

@ -45,6 +45,19 @@ spring:
resources:
cache:
# 资源缓存时间,单位秒
period: 604800
# 开启gzip压缩
chain:
gzipped: true
# 启用缓存
cache: true
# mvc: # mvc:
# static-path-pattern: /static/** #设定静态文件路径js,css等 # static-path-pattern: /static/** #设定静态文件路径js,css等
mybatis: mybatis:
@ -65,21 +78,25 @@ index:
mysql: mysql:
charset: utf8mb4 charset: utf8mb4
#爬取小说数据的最低评分
books: books:
#爬取小说数据的最低评分
lowestScore: 6.0 lowestScore: 6.0
#小说的更新间隔(分)
updatePeriod: 1
#爬取小说数量
maxNum: 300000
#爬取的网站名称类型 1笔趣岛 2笔趣塔,3:顶点小说 更多网站解析中,敬请期待 #爬取的网站名称类型 1笔趣岛 2笔趣塔,3:顶点小说 4百书斋,6: 笔趣窝 更多网站解析中,敬请期待
crawl: crawl:
website: website:
type: 2 type: 6
pic: pic:
save: save:
type: 1 #图片保存方式, 1不保存使用网络图片 2本地保存 type: 2 #图片保存方式, 1不保存使用网络图片 2本地保存
path: /var/pic #图片保存路径 path: /var/pic #图片保存路径

View File

@ -1,211 +1,268 @@
<?xml version="1.0" encoding="UTF-8" ?> <?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" > <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="xyz.zinglizingli.books.mapper.BookParseLogMapper" > <mapper namespace="xyz.zinglizingli.books.mapper.BookParseLogMapper">
<resultMap id="BaseResultMap" type="xyz.zinglizingli.books.po.BookParseLog" > <resultMap id="BaseResultMap" type="xyz.zinglizingli.books.po.BookParseLog">
<id column="id" property="id" jdbcType="BIGINT" /> <id column="id" property="id" jdbcType="BIGINT"/>
<result column="book_url" property="bookUrl" jdbcType="VARCHAR" /> <result column="book_url" property="bookUrl" jdbcType="VARCHAR"/>
<result column="book_name" property="bookName" jdbcType="VARCHAR" /> <result column="book_name" property="bookName" jdbcType="VARCHAR"/>
<result column="score" property="score" jdbcType="REAL" /> <result column="score" property="score" jdbcType="REAL"/>
<result column="create_time" property="createTime" jdbcType="TIMESTAMP" /> <result column="create_time" property="createTime" jdbcType="TIMESTAMP"/>
</resultMap> <result column="priority" property="priority" jdbcType="TINYINT"/>
<sql id="Example_Where_Clause" > <result column="update_count" property="updateCount" jdbcType="TINYINT"/>
<where > </resultMap>
<foreach collection="oredCriteria" item="criteria" separator="or" > <sql id="Example_Where_Clause">
<if test="criteria.valid" > <where>
<trim prefix="(" suffix=")" prefixOverrides="and" > <foreach collection="oredCriteria" item="criteria" separator="or">
<foreach collection="criteria.criteria" item="criterion" > <if test="criteria.valid">
<choose > <trim prefix="(" suffix=")" prefixOverrides="and">
<when test="criterion.noValue" > <foreach collection="criteria.criteria" item="criterion">
and ${criterion.condition} <choose>
</when> <when test="criterion.noValue">
<when test="criterion.singleValue" > and ${criterion.condition}
and ${criterion.condition} #{criterion.value} </when>
</when> <when test="criterion.singleValue">
<when test="criterion.betweenValue" > and ${criterion.condition} #{criterion.value}
and ${criterion.condition} #{criterion.value} and #{criterion.secondValue} </when>
</when> <when test="criterion.betweenValue">
<when test="criterion.listValue" > and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
and ${criterion.condition} </when>
<foreach collection="criterion.value" item="listItem" open="(" close=")" separator="," > <when test="criterion.listValue">
#{listItem} and ${criterion.condition}
</foreach> <foreach collection="criterion.value" item="listItem" open="(" close=")"
</when> separator=",">
</choose> #{listItem}
</foreach>
</when>
</choose>
</foreach>
</trim>
</if>
</foreach> </foreach>
</trim> </where>
</if> </sql>
</foreach> <sql id="Update_By_Example_Where_Clause">
</where> <where>
</sql> <foreach collection="example.oredCriteria" item="criteria" separator="or">
<sql id="Update_By_Example_Where_Clause" > <if test="criteria.valid">
<where > <trim prefix="(" suffix=")" prefixOverrides="and">
<foreach collection="example.oredCriteria" item="criteria" separator="or" > <foreach collection="criteria.criteria" item="criterion">
<if test="criteria.valid" > <choose>
<trim prefix="(" suffix=")" prefixOverrides="and" > <when test="criterion.noValue">
<foreach collection="criteria.criteria" item="criterion" > and ${criterion.condition}
<choose > </when>
<when test="criterion.noValue" > <when test="criterion.singleValue">
and ${criterion.condition} and ${criterion.condition} #{criterion.value}
</when> </when>
<when test="criterion.singleValue" > <when test="criterion.betweenValue">
and ${criterion.condition} #{criterion.value} and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
</when> </when>
<when test="criterion.betweenValue" > <when test="criterion.listValue">
and ${criterion.condition} #{criterion.value} and #{criterion.secondValue} and ${criterion.condition}
</when> <foreach collection="criterion.value" item="listItem" open="(" close=")"
<when test="criterion.listValue" > separator=",">
and ${criterion.condition} #{listItem}
<foreach collection="criterion.value" item="listItem" open="(" close=")" separator="," > </foreach>
#{listItem} </when>
</foreach> </choose>
</when> </foreach>
</choose> </trim>
</if>
</foreach> </foreach>
</trim> </where>
</sql>
<sql id="Base_Column_List">
id, book_url, book_name, score, create_time, priority, update_count
</sql>
<select id="selectByExample" resultMap="BaseResultMap"
parameterType="xyz.zinglizingli.books.po.BookParseLogExample">
select
<if test="distinct">
distinct
</if> </if>
</foreach> <include refid="Base_Column_List"/>
</where> from book_parse_log
</sql> <if test="_parameter != null">
<sql id="Base_Column_List" > <include refid="Example_Where_Clause"/>
id, book_url, book_name, score, create_time </if>
</sql> <if test="orderByClause != null">
<select id="selectByExample" resultMap="BaseResultMap" parameterType="xyz.zinglizingli.books.po.BookParseLogExample" > order by ${orderByClause}
select </if>
<if test="distinct" > </select>
distinct <select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterType="java.lang.Long">
</if> select
<include refid="Base_Column_List" /> <include refid="Base_Column_List"/>
from book_parse_log from book_parse_log
<if test="_parameter != null" > where id = #{id,jdbcType=BIGINT}
<include refid="Example_Where_Clause" /> </select>
</if> <delete id="deleteByPrimaryKey" parameterType="java.lang.Long">
<if test="orderByClause != null" >
order by ${orderByClause}
</if>
</select>
<select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterType="java.lang.Long" >
select
<include refid="Base_Column_List" />
from book_parse_log
where id = #{id,jdbcType=BIGINT}
</select>
<delete id="deleteByPrimaryKey" parameterType="java.lang.Long" >
delete from book_parse_log delete from book_parse_log
where id = #{id,jdbcType=BIGINT} where id = #{id,jdbcType=BIGINT}
</delete> </delete>
<delete id="deleteByExample" parameterType="xyz.zinglizingli.books.po.BookParseLogExample" > <delete id="deleteByExample" parameterType="xyz.zinglizingli.books.po.BookParseLogExample">
delete from book_parse_log delete from book_parse_log
<if test="_parameter != null" > <if test="_parameter != null">
<include refid="Example_Where_Clause" /> <include refid="Example_Where_Clause"/>
</if> </if>
</delete> </delete>
<insert id="insert" parameterType="xyz.zinglizingli.books.po.BookParseLog" > <insert id="insert" parameterType="xyz.zinglizingli.books.po.BookParseLog">
insert into book_parse_log (id, book_url, book_name, insert into book_parse_log (id, book_url, book_name,
score, create_time) score, create_time, priority,
update_count)
values (#{id,jdbcType=BIGINT}, #{bookUrl,jdbcType=VARCHAR}, #{bookName,jdbcType=VARCHAR}, values (#{id,jdbcType=BIGINT}, #{bookUrl,jdbcType=VARCHAR}, #{bookName,jdbcType=VARCHAR},
#{score,jdbcType=REAL}, #{createTime,jdbcType=TIMESTAMP}) #{score,jdbcType=REAL}, #{createTime,jdbcType=TIMESTAMP}, #{priority,jdbcType=TINYINT},
#{updateCount,jdbcType=TINYINT})
</insert> </insert>
<insert id="insertSelective" parameterType="xyz.zinglizingli.books.po.BookParseLog" > <insert id="insertSelective" parameterType="xyz.zinglizingli.books.po.BookParseLog">
insert into book_parse_log insert into book_parse_log
<trim prefix="(" suffix=")" suffixOverrides="," > <trim prefix="(" suffix=")" suffixOverrides=",">
<if test="id != null" > <if test="id != null">
id, id,
</if> </if>
<if test="bookUrl != null" > <if test="bookUrl != null">
book_url, book_url,
</if> </if>
<if test="bookName != null" > <if test="bookName != null">
book_name, book_name,
</if> </if>
<if test="score != null" > <if test="score != null">
score, score,
</if> </if>
<if test="createTime != null" > <if test="createTime != null">
create_time, create_time,
</if> </if>
</trim> <if test="priority != null">
<trim prefix="values (" suffix=")" suffixOverrides="," > priority,
<if test="id != null" > </if>
#{id,jdbcType=BIGINT}, <if test="updateCount != null">
</if> update_count,
<if test="bookUrl != null" > </if>
#{bookUrl,jdbcType=VARCHAR}, </trim>
</if> <trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="bookName != null" > <if test="id != null">
#{bookName,jdbcType=VARCHAR}, #{id,jdbcType=BIGINT},
</if> </if>
<if test="score != null" > <if test="bookUrl != null">
#{score,jdbcType=REAL}, #{bookUrl,jdbcType=VARCHAR},
</if> </if>
<if test="createTime != null" > <if test="bookName != null">
#{createTime,jdbcType=TIMESTAMP}, #{bookName,jdbcType=VARCHAR},
</if> </if>
</trim> <if test="score != null">
</insert> #{score,jdbcType=REAL},
<select id="countByExample" parameterType="xyz.zinglizingli.books.po.BookParseLogExample" resultType="java.lang.Integer" > </if>
select count(*) from book_parse_log <if test="createTime != null">
<if test="_parameter != null" > #{createTime,jdbcType=TIMESTAMP},
<include refid="Example_Where_Clause" /> </if>
</if> <if test="priority != null">
</select> #{priority,jdbcType=TINYINT},
<update id="updateByExampleSelective" parameterType="map" > </if>
update book_parse_log <if test="updateCount != null">
<set > #{updateCount,jdbcType=TINYINT},
<if test="record.id != null" > </if>
id = #{record.id,jdbcType=BIGINT}, </trim>
</if> </insert>
<if test="record.bookUrl != null" > <select id="countByExample" parameterType="xyz.zinglizingli.books.po.BookParseLogExample"
resultType="java.lang.Integer">
select count(*) from book_parse_log
<if test="_parameter != null">
<include refid="Example_Where_Clause"/>
</if>
</select>
<update id="updateByExampleSelective" parameterType="map">
update book_parse_log
<set>
<if test="record.id != null">
id = #{record.id,jdbcType=BIGINT},
</if>
<if test="record.bookUrl != null">
book_url = #{record.bookUrl,jdbcType=VARCHAR},
</if>
<if test="record.bookName != null">
book_name = #{record.bookName,jdbcType=VARCHAR},
</if>
<if test="record.score != null">
score = #{record.score,jdbcType=REAL},
</if>
<if test="record.createTime != null">
create_time = #{record.createTime,jdbcType=TIMESTAMP},
</if>
<if test="record.priority != null">
priority = #{record.priority,jdbcType=TINYINT},
</if>
<if test="record.updateCount != null">
update_count = #{record.updateCount,jdbcType=TINYINT},
</if>
</set>
<if test="_parameter != null">
<include refid="Update_By_Example_Where_Clause"/>
</if>
</update>
<update id="updateByExample" parameterType="map">
update book_parse_log
set id = #{record.id,jdbcType=BIGINT},
book_url = #{record.bookUrl,jdbcType=VARCHAR}, book_url = #{record.bookUrl,jdbcType=VARCHAR},
</if>
<if test="record.bookName != null" >
book_name = #{record.bookName,jdbcType=VARCHAR}, book_name = #{record.bookName,jdbcType=VARCHAR},
</if>
<if test="record.score != null" >
score = #{record.score,jdbcType=REAL}, score = #{record.score,jdbcType=REAL},
</if>
<if test="record.createTime != null" >
create_time = #{record.createTime,jdbcType=TIMESTAMP}, create_time = #{record.createTime,jdbcType=TIMESTAMP},
</if> priority = #{record.priority,jdbcType=TINYINT},
</set> update_count = #{record.updateCount,jdbcType=TINYINT}
<if test="_parameter != null" > <if test="_parameter != null">
<include refid="Update_By_Example_Where_Clause" /> <include refid="Update_By_Example_Where_Clause"/>
</if> </if>
</update> </update>
<update id="updateByExample" parameterType="map" > <update id="updateByPrimaryKeySelective" parameterType="xyz.zinglizingli.books.po.BookParseLog">
update book_parse_log update book_parse_log
set id = #{record.id,jdbcType=BIGINT}, <set>
book_url = #{record.bookUrl,jdbcType=VARCHAR}, <if test="bookUrl != null">
book_name = #{record.bookName,jdbcType=VARCHAR}, book_url = #{bookUrl,jdbcType=VARCHAR},
score = #{record.score,jdbcType=REAL}, </if>
create_time = #{record.createTime,jdbcType=TIMESTAMP} <if test="bookName != null">
<if test="_parameter != null" > book_name = #{bookName,jdbcType=VARCHAR},
<include refid="Update_By_Example_Where_Clause" /> </if>
</if> <if test="score != null">
</update> score = #{score,jdbcType=REAL},
<update id="updateByPrimaryKeySelective" parameterType="xyz.zinglizingli.books.po.BookParseLog" > </if>
update book_parse_log <if test="createTime != null">
<set > create_time = #{createTime,jdbcType=TIMESTAMP},
<if test="bookUrl != null" > </if>
book_url = #{bookUrl,jdbcType=VARCHAR}, <if test="priority != null">
</if> priority = #{priority,jdbcType=TINYINT},
<if test="bookName != null" > </if>
book_name = #{bookName,jdbcType=VARCHAR}, <if test="updateCount != null">
</if> update_count = #{updateCount,jdbcType=TINYINT},
<if test="score != null" > </if>
score = #{score,jdbcType=REAL}, </set>
</if> where id = #{id,jdbcType=BIGINT}
<if test="createTime != null" > </update>
create_time = #{createTime,jdbcType=TIMESTAMP}, <update id="updateByPrimaryKey" parameterType="xyz.zinglizingli.books.po.BookParseLog">
</if>
</set>
where id = #{id,jdbcType=BIGINT}
</update>
<update id="updateByPrimaryKey" parameterType="xyz.zinglizingli.books.po.BookParseLog" >
update book_parse_log update book_parse_log
set book_url = #{bookUrl,jdbcType=VARCHAR}, set book_url = #{bookUrl,jdbcType=VARCHAR},
book_name = #{bookName,jdbcType=VARCHAR}, book_name = #{bookName,jdbcType=VARCHAR},
score = #{score,jdbcType=REAL}, score = #{score,jdbcType=REAL},
create_time = #{createTime,jdbcType=TIMESTAMP} create_time = #{createTime,jdbcType=TIMESTAMP},
priority = #{priority,jdbcType=TINYINT},
update_count = #{updateCount,jdbcType=TINYINT}
where id = #{id,jdbcType=BIGINT} where id = #{id,jdbcType=BIGINT}
</update> </update>
<update id="addBookUpdateCount">
update book_parse_log set update_count = update_count + 1
where id in
<foreach collection="list" item="log" separator="," open="(" close=")">
#{log.id}
</foreach>
</update>
<select id="queryBookParseLogs" resultMap="BaseResultMap">
select
<include refid="Base_Column_List"/>
from book_parse_log
where update_count <![CDATA[ < ]]> 5
order by priority asc,create_time desc
limit 100
</select>
</mapper> </mapper>

View File

@ -0,0 +1,181 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="xyz.zinglizingli.books.mapper.BookUpdateTimeLogMapper" >
<resultMap id="BaseResultMap" type="xyz.zinglizingli.books.po.BookUpdateTimeLog" >
<id column="id" property="id" jdbcType="INTEGER" />
<result column="book_cat_id" property="bookCatId" jdbcType="INTEGER" />
<result column="last_update_time" property="lastUpdateTime" jdbcType="TIMESTAMP" />
</resultMap>
<sql id="Example_Where_Clause" >
<where >
<foreach collection="oredCriteria" item="criteria" separator="or" >
<if test="criteria.valid" >
<trim prefix="(" suffix=")" prefixOverrides="and" >
<foreach collection="criteria.criteria" item="criterion" >
<choose >
<when test="criterion.noValue" >
and ${criterion.condition}
</when>
<when test="criterion.singleValue" >
and ${criterion.condition} #{criterion.value}
</when>
<when test="criterion.betweenValue" >
and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
</when>
<when test="criterion.listValue" >
and ${criterion.condition}
<foreach collection="criterion.value" item="listItem" open="(" close=")" separator="," >
#{listItem}
</foreach>
</when>
</choose>
</foreach>
</trim>
</if>
</foreach>
</where>
</sql>
<sql id="Update_By_Example_Where_Clause" >
<where >
<foreach collection="example.oredCriteria" item="criteria" separator="or" >
<if test="criteria.valid" >
<trim prefix="(" suffix=")" prefixOverrides="and" >
<foreach collection="criteria.criteria" item="criterion" >
<choose >
<when test="criterion.noValue" >
and ${criterion.condition}
</when>
<when test="criterion.singleValue" >
and ${criterion.condition} #{criterion.value}
</when>
<when test="criterion.betweenValue" >
and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
</when>
<when test="criterion.listValue" >
and ${criterion.condition}
<foreach collection="criterion.value" item="listItem" open="(" close=")" separator="," >
#{listItem}
</foreach>
</when>
</choose>
</foreach>
</trim>
</if>
</foreach>
</where>
</sql>
<sql id="Base_Column_List" >
id, book_cat_id, last_update_time
</sql>
<select id="selectByExample" resultMap="BaseResultMap" parameterType="xyz.zinglizingli.books.po.BookUpdateTimeLogExample" >
select
<if test="distinct" >
distinct
</if>
<include refid="Base_Column_List" />
from book_update_time_log
<if test="_parameter != null" >
<include refid="Example_Where_Clause" />
</if>
<if test="orderByClause != null" >
order by ${orderByClause}
</if>
</select>
<select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterType="java.lang.Integer" >
select
<include refid="Base_Column_List" />
from book_update_time_log
where id = #{id,jdbcType=INTEGER}
</select>
<delete id="deleteByPrimaryKey" parameterType="java.lang.Integer" >
delete from book_update_time_log
where id = #{id,jdbcType=INTEGER}
</delete>
<delete id="deleteByExample" parameterType="xyz.zinglizingli.books.po.BookUpdateTimeLogExample" >
delete from book_update_time_log
<if test="_parameter != null" >
<include refid="Example_Where_Clause" />
</if>
</delete>
<insert id="insert" parameterType="xyz.zinglizingli.books.po.BookUpdateTimeLog" >
insert into book_update_time_log (id, book_cat_id, last_update_time
)
values (#{id,jdbcType=INTEGER}, #{bookCatId,jdbcType=INTEGER}, #{lastUpdateTime,jdbcType=TIMESTAMP}
)
</insert>
<insert id="insertSelective" parameterType="xyz.zinglizingli.books.po.BookUpdateTimeLog" >
insert into book_update_time_log
<trim prefix="(" suffix=")" suffixOverrides="," >
<if test="id != null" >
id,
</if>
<if test="bookCatId != null" >
book_cat_id,
</if>
<if test="lastUpdateTime != null" >
last_update_time,
</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides="," >
<if test="id != null" >
#{id,jdbcType=INTEGER},
</if>
<if test="bookCatId != null" >
#{bookCatId,jdbcType=INTEGER},
</if>
<if test="lastUpdateTime != null" >
#{lastUpdateTime,jdbcType=TIMESTAMP},
</if>
</trim>
</insert>
<select id="countByExample" parameterType="xyz.zinglizingli.books.po.BookUpdateTimeLogExample" resultType="java.lang.Integer" >
select count(*) from book_update_time_log
<if test="_parameter != null" >
<include refid="Example_Where_Clause" />
</if>
</select>
<update id="updateByExampleSelective" parameterType="map" >
update book_update_time_log
<set >
<if test="record.id != null" >
id = #{record.id,jdbcType=INTEGER},
</if>
<if test="record.bookCatId != null" >
book_cat_id = #{record.bookCatId,jdbcType=INTEGER},
</if>
<if test="record.lastUpdateTime != null" >
last_update_time = #{record.lastUpdateTime,jdbcType=TIMESTAMP},
</if>
</set>
<if test="_parameter != null" >
<include refid="Update_By_Example_Where_Clause" />
</if>
</update>
<update id="updateByExample" parameterType="map" >
update book_update_time_log
set id = #{record.id,jdbcType=INTEGER},
book_cat_id = #{record.bookCatId,jdbcType=INTEGER},
last_update_time = #{record.lastUpdateTime,jdbcType=TIMESTAMP}
<if test="_parameter != null" >
<include refid="Update_By_Example_Where_Clause" />
</if>
</update>
<update id="updateByPrimaryKeySelective" parameterType="xyz.zinglizingli.books.po.BookUpdateTimeLog" >
update book_update_time_log
<set >
<if test="bookCatId != null" >
book_cat_id = #{bookCatId,jdbcType=INTEGER},
</if>
<if test="lastUpdateTime != null" >
last_update_time = #{lastUpdateTime,jdbcType=TIMESTAMP},
</if>
</set>
where id = #{id,jdbcType=INTEGER}
</update>
<update id="updateByPrimaryKey" parameterType="xyz.zinglizingli.books.po.BookUpdateTimeLog" >
update book_update_time_log
set book_cat_id = #{bookCatId,jdbcType=INTEGER},
last_update_time = #{lastUpdateTime,jdbcType=TIMESTAMP}
where id = #{id,jdbcType=INTEGER}
</update>
</mapper>

View File

@ -19,17 +19,6 @@
<div th:include="common/css :: css"></div> <div th:include="common/css :: css"></div>
<script>
var _hmt = _hmt || [];
(function () {
var hm = document.createElement("script");
hm.src = "https://hm.baidu.com/hm.js?2cf01edbc2b27cd3a143e17948167d77";
var s = document.getElementsByTagName("script")[0];
s.parentNode.insertBefore(hm, s);
})();
</script>
<script type="text/javascript"> <script type="text/javascript">
function reinitIframe(){ function reinitIframe(){
@ -206,7 +195,7 @@
} }
//发送弹幕 //发送弹幕
function sendBullet(){ function sendBullet(){
var bullet = $("#screenBulletText").val(); var bullet = $("#screenBulletText").val().replace(/</g, "&lt;").replace(/>/g, "&gt;");
var contentId = $("#contentIdHidden").val(); var contentId = $("#contentIdHidden").val();
if (bullet && contentId) { if (bullet && contentId) {
if(bullet.length > 100){ if(bullet.length > 100){
@ -477,16 +466,6 @@
</script> </script>
<script> <script>
(function () { (function () {
var bp = document.createElement('script');
var curProtocol = window.location.protocol.split(':')[0];
if (curProtocol === 'https') {
bp.src = 'https://zz.bdstatic.com/linksubmit/push.js';
}
else {
bp.src = 'http://push.zhanzhang.baidu.com/push.js';
}
var s = document.getElementsByTagName("script")[0];
s.parentNode.insertBefore(bp, s);
$("#content").css("min-height",($(window).height()-60)+"px"); $("#content").css("min-height",($(window).height()-60)+"px");

View File

@ -115,30 +115,6 @@
</style> </style>
<script>
var _hmt = _hmt || [];
(function() {
var hm = document.createElement("script");
hm.src = "https://hm.baidu.com/hm.js?2cf01edbc2b27cd3a143e17948167d77";
var s = document.getElementsByTagName("script")[0];
s.parentNode.insertBefore(hm, s);
})();
</script>
<script>
(function(){
var bp = document.createElement('script');
var curProtocol = window.location.protocol.split(':')[0];
if (curProtocol === 'https') {
bp.src = 'https://zz.bdstatic.com/linksubmit/push.js';
}
else {
bp.src = 'http://push.zhanzhang.baidu.com/push.js';
}
var s = document.getElementsByTagName("script")[0];
s.parentNode.insertBefore(bp, s);
})();
</script>
<script src="/js/wap_collect.js"></script> <script src="/js/wap_collect.js"></script>
</head> </head>

View File

@ -39,29 +39,6 @@
</div> </div>
<script>
var _hmt = _hmt || [];
(function() {
var hm = document.createElement("script");
hm.src = "https://hm.baidu.com/hm.js?2cf01edbc2b27cd3a143e17948167d77";
var s = document.getElementsByTagName("script")[0];
s.parentNode.insertBefore(hm, s);
})();
</script>
<script>
(function(){
var bp = document.createElement('script');
var curProtocol = window.location.protocol.split(':')[0];
if (curProtocol === 'https') {
bp.src = 'https://zz.bdstatic.com/linksubmit/push.js';
}
else {
bp.src = 'http://push.zhanzhang.baidu.com/push.js';
}
var s = document.getElementsByTagName("script")[0];
s.parentNode.insertBefore(bp, s);
})();
</script>
</head> </head>
<body> <body>

View File

@ -15,15 +15,6 @@
<div th:include="common/css :: css"></div> <div th:include="common/css :: css"></div>
</div> </div>
<script>
var _hmt = _hmt || [];
(function () {
var hm = document.createElement("script");
hm.src = "https://hm.baidu.com/hm.js?2cf01edbc2b27cd3a143e17948167d77";
var s = document.getElementsByTagName("script")[0];
s.parentNode.insertBefore(hm, s);
})();
</script>
<style type="text/css"> <style type="text/css">
@ -236,18 +227,6 @@
</script> </script>
<script> <script>
(function(){
var bp = document.createElement('script');
var curProtocol = window.location.protocol.split(':')[0];
if (curProtocol === 'https') {
bp.src = 'https://zz.bdstatic.com/linksubmit/push.js';
}
else {
bp.src = 'http://push.zhanzhang.baidu.com/push.js';
}
var s = document.getElementsByTagName("script")[0];
s.parentNode.insertBefore(bp, s);
})();
function toMyCollect(){ function toMyCollect(){

View File

@ -0,0 +1,88 @@
<!DOCTYPE html>
<html lang="en">
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<title>小说提交</title>
<div th:include="common/css :: css"></div>
</head>
<body id="read" >
</div>
<div style="height: 50px;line-height: 50px;text-align: center" class="layui-header header header-doc layui-bg-cyan">
<div style="float: left;margin-left: 10px">
<a href="javascript:history.go(-1)">
<i style="font-size: 20px;color: #92B8B1;" class="layui-icon">&#xe65c;</i></a>
</div>
<b class="layui-icon">单本小说提交</b>
<div style="float: right;margin-right: 10px"><a href="/">
<i style="font-size: 20px;color: #92B8B1;" class="layui-icon">&#xe68e;</i>
</a>
</div>
</div>
<div style="height: 800px;padding: 20px;border: 1px solid #eee;">
<form class="layui-form" action="">
<div class="layui-form-item">
<label class="layui-form-label">详情页Url:</label>
<div class="layui-col-xs7 layui-col-sm6 layui-col-md3 layui-col-lg1" >
<input type="text" id="bookUrl" name="bookUrl" required lay-verify="required" placeholder="请输入源站小说详情页Url" autocomplete="off" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">小说名:</label>
<div class="layui-col-xs7 layui-col-sm6 layui-col-md3 layui-col-lg1" >
<input type="text" id="bookName" name="bookName" required lay-verify="required" placeholder="请输入小说名" autocomplete="off" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">小说评分:</label>
<div class="layui-col-xs7 layui-col-sm6 layui-col-md3 layui-col-lg1">
<input type="number" id="score" name="score" required lay-verify="required" placeholder="请输入小说评分" autocomplete="off" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<div class="layui-input-block">
<button class="layui-btn" lay-submit lay-filter="formDemo">提交</button>
<button type="reset" class="layui-btn layui-btn-primary">重置</button>
</div>
</div>
</form>
</div>
<div th:replace="common/footer :: footer">
</div>
<a name="buttom"></a>
</body>
<div th:replace="common/js :: js"></div>
<script>
//Demo
layui.use('form', function(){
var form = layui.form;
//监听提交
form.on('submit(formDemo)', function(){
$.post("/book/submit",{"bookUrl":$("#bookUrl").val(),"bookName":$("#bookName").val(),"score":$("#score").val()},function (data) {
if(data.code == 1 ){
layer.alert("提交成功任务排队中请过一段时间后再搜索查看");
}else{
layer.alert("提交失败");
}
});
return false;
});
});
</script>
</html>

View File

@ -0,0 +1,283 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<title>精品小说楼</title>
<meta name="keywords" content="精品小说楼,精品小说,弹幕网站,弹幕,弹幕小说网站,免费小说,小说阅读,小说排行,轻小说,txt小说下载,电子书下载,动漫轻小说,日本轻小说">
<meta name="description"
content="精品小说楼是国内优秀的小说弹幕网站,精品小说楼提供海量热门网络小说,日本轻小说,国产轻小说,动漫小说,轻小说在线阅读和TXT小说下载,致力于网络精品小说的收集,智能计算小说评分,打造小说精品排行榜,致力于无广告无弹窗的小说阅读环境。">
<meta property="og:type" content="novel_index"/>
<meta property="og:title" content="精品小说楼"/>
<meta property="og:description"
content="精品小说楼是国内优秀的小说弹幕网站,精品小说楼提供海量热门网络小说,日本轻小说,国产轻小说,动漫小说,轻小说在线阅读和TXT小说下载,致力于网络精品小说的收集,智能计算小说评分,打造小说精品排行榜,致力于无广告无弹窗的小说阅读环境。"/>
<div th:include="common/css :: css"></div>
<style>
.line-limit-length {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.layui-nav .layui-nav-item {
position: relative;
display: inline-block;
vertical-align: middle;
line-height: 50px;
}
body ul.layui-nav li.layui-nav-item a {
display: block;
transition: all .3s;
-webkit-transition: all .3s;
}
</style>
<script>
var _hmt = _hmt || [];
(function () {
var hm = document.createElement("script");
hm.src = "https://hm.baidu.com/hm.js?2cf01edbc2b27cd3a143e17948167d77";
var s = document.getElementsByTagName("script")[0];
s.parentNode.insertBefore(hm, s);
})();
</script>
</head>
<body>
<!-- 你的HTML代码 -->
<a name="top"></a>
<ul class="layui-nav" lay-filter="" style="padding:0 36px;text-align: center">
<li class="layui-nav-item"><a href="/book/search?catId=1">玄幻小说</a></li>
<li class="layui-nav-item"><a href="/book/search?catId=2">修真小说</a></li>
<li class="layui-nav-item"><a href="/book/search?catId=3">都市小说</a></li>
<li class="layui-nav-item"><a href="/book/search?catId=4">历史小说</a></li>
<li class="layui-nav-item"><a href="/book/search?catId=6">网游小说</a></li>
<li class="layui-nav-item"><a href="/book/search?catId=5">科幻小说</a></li>
<li class="layui-nav-item"><a href="/book/search?catId=7">女频小说</a></li>
<li class="layui-nav-item"><a>完本小说</a>
<dl class="layui-nav-child"> <!-- 二级菜单 -->
<dd><a href="/book/search?bookStatus=完成">全部小说</a></dd>
<dd><a href="/book/search?bookStatus=完成&catId=1">玄幻小说</a></dd>
<dd><a href="/book/search?bookStatus=完成&catId=2">修真小说</a></dd>
<dd><a href="/book/search?bookStatus=完成&catId=3">都市小说</a></dd>
<dd><a href="/book/search?bookStatus=完成&catId=4">历史小说</a></dd>
<dd><a href="/book/search?bookStatus=完成&catId=6">网游小说</a></dd>
<dd><a href="/book/search?bookStatus=完成&catId=5">科幻小说</a></dd>
<dd><a href="/book/search?bookStatus=完成&catId=7">女频小说</a></dd>
</dl>
</li>
<li class="layui-nav-item"><a>小说排行</a>
<dl class="layui-nav-child"> <!-- 二级菜单 -->
<dd><a href="/book/search?sortBy=score">全部小说</a></dd>
<dd><a href="/book/search?sortBy=score&catId=1">玄幻小说</a></dd>
<dd><a href="/book/search?sortBy=score&catId=2">修真小说</a></dd>
<dd><a href="/book/search?sortBy=score&catId=3">都市小说</a></dd>
<dd><a href="/book/search?sortBy=score&catId=4">历史小说</a></dd>
<dd><a href="/book/search?sortBy=score&catId=6">网游小说</a></dd>
<dd><a href="/book/search?sortBy=score&catId=5">科幻小说</a></dd>
<dd><a href="/book/search?sortBy=score&catId=7">女频小说</a></dd>
</dl>
</li>
</ul>
<div class="layui-container">
<div class="layui-row">
<div class="layui-col-xs10 layui-col-sm10 layui-col-md11 layui-col-lg11" style="padding-top:1%">
<input id="title" type="text" name="title" required lay-verify="required" placeholder="请输入书名·作者"
autocomplete="off"
class="layui-input">
</div>
<div class="layui-col-xs1" style="padding: 1%">
<button onclick="searchBooks()" class="layui-btn" lay-submit lay-filter="formDemo">搜索</button>
</div>
</div>
</div>
<div class="layui-collapse">
<div class="layui-colla-item">
<h2 class="layui-colla-title">本站推荐</h2>
<div class="layui-colla-content layui-show">
<div class="layui-container" style="padding: 0px">
<div class="layui-row" style="text-align: center">
<span th:each="recBook : ${recBooks}">
<a th:href="'/book/' + ${recBook.id} + '.html'">
<div style="padding: 1%" class="layui-col-xs4 layui-col-sm4 layui-col-md4 layui-col-lg4">
<img style=" width:80%; height:auto; max-width:100%; max-height:100%;"
th:src="${recBook.picUrl}"/>
<br/>
<span th:text="${recBook.bookName}"></span>
</div>
</a>
</span>
</div>
</div>
</div>
</div>
<div class="layui-colla-item">
<h2 class="layui-colla-title">热门小说推荐</h2>
<div class="layui-colla-content layui-show">
<div class="layui-container">
<div class="layui-row">
<div style="margin-bottom: 5px" class="layui-col-xs12 layui-col-sm6 layui-col-md4 layui-col-lg4"
th:each="hotBook : ${hotBooks}">
<a th:href="'/book/' + ${hotBook.id} + '.html'">
<div class="layui-col-xs5 layui-col-sm4 layui-col-md4 layui-col-lg4">
<img style=" width:100px; height:125px;"
th:src="${hotBook.picUrl}"/>
</div>
<div class="layui-col-xs5 layui-col-sm6 layui-col-md6 layui-col-lg6">
<ul>
<li class="line-limit-length" style="font-weight: bold"
th:text="${hotBook.bookName}"></li>
<li th:text="'作者'+ ${hotBook.author}"></li>
<li style="width: 180px;height:40px;overflow: hidden"
th:text="'简介'+ ${hotBook.bookDesc}"></li>
</ul>
</div>
<div style="font-style: italic;color: red"
class="layui-col-xs2 layui-col-sm2 layui-col-md2 layui-col-lg2"
th:text="${hotBook.score} + '分'"></div>
</a>
</div>
<!--<div th:each="hotBook : ${hotBooks}" style="margin-top: 1%"
class="layui-col-xs12 layui-col-sm6 layui-col-md6 layui-col-lg6">
<a th:href="'/book/'+${hotBook.id}+'.html'">
<div class="layui-col-xs5 layui-col-sm3 layui-col-md3 layui-col-lg3">
<img style=" width:100px; height:125px;"
th:src="${hotBook.picUrl}"/>
</div>
<div class="layui-col-xs7 layui-col-sm6 layui-col-md7 layui-col-lg7"
style="float: left;padding-right: 10px">
<div><b th:text="${hotBook.bookName}"></b></div>
<div class="layui-col-xs8 layui-col-sm9 layui-col-md10 layui-col-lg10"
th:text="'作者'+ ${hotBook.author}"></div>
<div class="layui-col-xs3 layui-col-sm2 layui-col-md1 layui-col-lg1" style="text-align: right;">
<b><i style="color: red"
th:text="${hotBook.score} + '分'"></i></b></div>
</div>
<div class="layui-elip layui-col-xs12 layui-col-sm9 layui-col-md10 layui-col-lg10 layui-col-sm9 layui-col-md10 layui-col-lg10"
th:text="${hotBook.bookDesc}">
</div>
</a>
</div>-->
</div>
</div>
</div>
</div>
</div>
</div>
<div class="layui-colla-item"><a href="javascript:moreNewBooks()">
<h2 class="layui-colla-title">最近更新小说
<div style="float: right; margin-right: 20px"><i style="font-size: 14px;"
class="layui-icon">更多&#xe65b;</i>
</div>
</h2>
</a>
<div class="layui-colla-content layui-show">
<div class="layui-container" style="padding-left: 2px;padding-right: 5px">
<div class="layui-row">
<div th:each="newBook,bookStat : ${newBooks}" style="padding-bottom: 30px"
class="layui-col-xs12 layui-col-sm6 layui-col-md6 layui-col-lg6">
<a th:href="'/book/'+${newBook.id}+'.html'">
<div class="line-limit-length layui-col-xs8 layui-col-sm6 layui-col-md6 layui-col-lg6"><b
th:text="${bookStat.index}+1+'.'+${newBook.bookName}"></b> - <span class="layui-elip"
th:text="${newBook.author}"></span>
</div>
<div class="layui-col-sm3 layui-col-md3 layui-col-lg3"
style="color: #FF5722;float: right;margin-right:5px"><i
th:text="${#dates.format(newBook.updateTime, 'MM-dd HH:mm')}"></i></div>
<div style="clear: both"></div>
<div style="padding-left: 5px;padding-top: 5px"
class="layui-elip layui-col-md11 layui-col-sm11 layui-col-lg11"
th:text="'简介'+ ${newBook.bookDesc}">
</div>
</a>
</div>
</div>
</div>
</div>
</div>
</div>
<div th:replace="common/footer :: footer">
</div>
<div th:replace="common/js :: js">
</div>
<script src="/js/wap_collect.js"></script>
<script>
(function () {
var bp = document.createElement('script');
var curProtocol = window.location.protocol.split(':')[0];
if (curProtocol === 'https') {
bp.src = 'https://zz.bdstatic.com/linksubmit/push.js';
} else {
bp.src = 'http://push.zhanzhang.baidu.com/push.js';
}
var s = document.getElementsByTagName("script")[0];
s.parentNode.insertBefore(bp, s);
})();
</script>
<script>
function moreNewBooks(event) {
window.location.href = "/book/search";
}
function searchBooks() {
var keywords = $("#title").val();
window.location.href = "/book/search?keyword=" + encodeURI(keywords);
}
function toMyCollect() {
var token = localStorage.getItem("token");
if (token) {
window.location.href = "/book/search?token=" + token;
} else {
window.location.href = "/user/login.html";
}
}
</script>
</body>
</html>

View File

@ -46,15 +46,6 @@
</style> </style>
<script>
var _hmt = _hmt || [];
(function () {
var hm = document.createElement("script");
hm.src = "https://hm.baidu.com/hm.js?2cf01edbc2b27cd3a143e17948167d77";
var s = document.getElementsByTagName("script")[0];
s.parentNode.insertBefore(hm, s);
})();
</script>
</head> </head>
<body> <body>
@ -247,17 +238,6 @@
<script src="/js/wap_collect.js"></script> <script src="/js/wap_collect.js"></script>
<script> <script>
lazyload(); lazyload();
(function () {
var bp = document.createElement('script');
var curProtocol = window.location.protocol.split(':')[0];
if (curProtocol === 'https') {
bp.src = 'https://zz.bdstatic.com/linksubmit/push.js';
} else {
bp.src = 'http://push.zhanzhang.baidu.com/push.js';
}
var s = document.getElementsByTagName("script")[0];
s.parentNode.insertBefore(bp, s);
})();
</script> </script>

View File

@ -46,15 +46,6 @@
</style> </style>
<script>
var _hmt = _hmt || [];
(function () {
var hm = document.createElement("script");
hm.src = "https://hm.baidu.com/hm.js?2cf01edbc2b27cd3a143e17948167d77";
var s = document.getElementsByTagName("script")[0];
s.parentNode.insertBefore(hm, s);
})();
</script>
</head> </head>
<body> <body>
@ -293,17 +284,6 @@
<script src="/js/wap_collect.js"></script> <script src="/js/wap_collect.js"></script>
<script> <script>
lazyload(); lazyload();
(function () {
var bp = document.createElement('script');
var curProtocol = window.location.protocol.split(':')[0];
if (curProtocol === 'https') {
bp.src = 'https://zz.bdstatic.com/linksubmit/push.js';
} else {
bp.src = 'http://push.zhanzhang.baidu.com/push.js';
}
var s = document.getElementsByTagName("script")[0];
s.parentNode.insertBefore(bp, s);
})();
</script> </script>

View File

@ -15,15 +15,6 @@
<div th:include="common/css :: css"></div> <div th:include="common/css :: css"></div>
</div> </div>
<script>
var _hmt = _hmt || [];
(function () {
var hm = document.createElement("script");
hm.src = "https://hm.baidu.com/hm.js?2cf01edbc2b27cd3a143e17948167d77";
var s = document.getElementsByTagName("script")[0];
s.parentNode.insertBefore(hm, s);
})();
</script>
<style type="text/css"> <style type="text/css">
@ -247,16 +238,6 @@
</script> </script>
<script> <script>
(function(){ (function(){
var bp = document.createElement('script');
var curProtocol = window.location.protocol.split(':')[0];
if (curProtocol === 'https') {
bp.src = 'https://zz.bdstatic.com/linksubmit/push.js';
}
else {
bp.src = 'http://push.zhanzhang.baidu.com/push.js';
}
var s = document.getElementsByTagName("script")[0];
s.parentNode.insertBefore(bp, s);
var sortCat = $("#softCat").val(); var sortCat = $("#softCat").val();

View File

@ -15,15 +15,6 @@
<div th:include="common/css :: css"></div> <div th:include="common/css :: css"></div>
</div> </div>
<script>
var _hmt = _hmt || [];
(function () {
var hm = document.createElement("script");
hm.src = "https://hm.baidu.com/hm.js?2cf01edbc2b27cd3a143e17948167d77";
var s = document.getElementsByTagName("script")[0];
s.parentNode.insertBefore(hm, s);
})();
</script>
<style type="text/css"> <style type="text/css">
@ -272,16 +263,6 @@
</script> </script>
<script> <script>
(function () { (function () {
var bp = document.createElement('script');
var curProtocol = window.location.protocol.split(':')[0];
if (curProtocol === 'https') {
bp.src = 'https://zz.bdstatic.com/linksubmit/push.js';
}
else {
bp.src = 'http://push.zhanzhang.baidu.com/push.js';
}
var s = document.getElementsByTagName("script")[0];
s.parentNode.insertBefore(bp, s);
var sortCat = $("#softCat").val(); var sortCat = $("#softCat").val();

View File

@ -50,29 +50,6 @@
</style> </style>
<script language="javascript" type="text/javascript" src="/js/wap_collect.js"></script> <script language="javascript" type="text/javascript" src="/js/wap_collect.js"></script>
<script>
var _hmt = _hmt || [];
(function () {
var hm = document.createElement("script");
hm.src = "https://hm.baidu.com/hm.js?b3a84b2ec6cc52dd088d735565b49644";
var s = document.getElementsByTagName("script")[0];
s.parentNode.insertBefore(hm, s);
})();
</script>
<script>
(function () {
var bp = document.createElement('script');
var curProtocol = window.location.protocol.split(':')[0];
if (curProtocol === 'https') {
bp.src = 'https://zz.bdstatic.com/linksubmit/push.js';
}
else {
bp.src = 'http://push.zhanzhang.baidu.com/push.js';
}
var s = document.getElementsByTagName("script")[0];
s.parentNode.insertBefore(bp, s);
})();
</script>
<style id="tsbrowser_video_independent_player_style" type="text/css"> <style id="tsbrowser_video_independent_player_style" type="text/css">
[tsbrowser_force_max_size] { [tsbrowser_force_max_size] {
width: 100% !important; width: 100% !important;

View File

@ -10,17 +10,6 @@
<div th:include="common/css :: css"></div> <div th:include="common/css :: css"></div>
<script>
var _hmt = _hmt || [];
(function() {
var hm = document.createElement("script");
hm.src = "https://hm.baidu.com/hm.js?2cf01edbc2b27cd3a143e17948167d77";
var s = document.getElementsByTagName("script")[0];
s.parentNode.insertBefore(hm, s);
})();
</script>
</head> </head>
<body id="read" > <body id="read" >
@ -107,18 +96,6 @@
}); });
</script> </script>
<script> <script>
(function(){
var bp = document.createElement('script');
var curProtocol = window.location.protocol.split(':')[0];
if (curProtocol === 'https') {
bp.src = 'https://zz.bdstatic.com/linksubmit/push.js';
}
else {
bp.src = 'http://push.zhanzhang.baidu.com/push.js';
}
var s = document.getElementsByTagName("script")[0];
s.parentNode.insertBefore(bp, s);
})();

View File

@ -1,14 +1,16 @@
server: {port: 8083} server: {port: 8083}
spring: spring:
datasource: {url: 'jdbc:mysql://47.106.243.172:3306/novel?useUnicode=true&characterEncoding=utf-8&useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai', datasource: {url: 'jdbc:mysql://127.0.0.1:3306/books?useUnicode=true&characterEncoding=utf-8&useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai',
username: novel, password: novel!8888} username: root, password: test123456}
mybatis: mybatis:
mapper-locations: classpath:mybatis/mapping/*.xml mapper-locations: classpath:mybatis/mapping/*.xml
type-aliases-package: xyz.zinglizingli.books.po type-aliases-package: xyz.zinglizingli.books.po
configuration: {log-impl: org.apache.ibatis.logging.stdout.StdOutImpl} configuration: {log-impl: org.apache.ibatis.logging.stdout.StdOutImpl}
mysql: {charset: utf8mb4} mysql: {charset: utf8mb4}
books: {lowestScore: '9.0'} books: {lowestScore: 6.0}
crawl: crawl:
website: {type: '2'} patten: '1'
website: {type: 6}
soft-novel: '0' soft-novel: '0'
manhua: '0' manhua: '0'
logging: {config: 'classpath:logback-boot.xml'}

21
sql/2020-01-17.sql Normal file
View File

@ -0,0 +1,21 @@
DROP TABLE IF EXISTS `book_update_time_log`;
CREATE TABLE `book_update_time_log` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`book_cat_id` int(11) NOT NULL,
`last_update_time` datetime DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `uq_key_catid` (`book_cat_id`)
) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8mb4;
INSERT INTO `book_update_time_log` VALUES ('1', '1', NOW());
INSERT INTO `book_update_time_log` VALUES ('2', '2', NOW());
INSERT INTO `book_update_time_log` VALUES ('3', '3', NOW());
INSERT INTO `book_update_time_log` VALUES ('4', '4', NOW());
INSERT INTO `book_update_time_log` VALUES ('5', '5', NOW());
INSERT INTO `book_update_time_log` VALUES ('6', '6', NOW());
INSERT INTO `book_update_time_log` VALUES ('7', '7', NOW());
ALTER TABLE book_parse_log drop INDEX uq_key_bookurl;

1
sql/2020-04-21.sql Normal file
View File

@ -0,0 +1 @@
alter table book_parse_log add column `priority` TINYINT(2) not null default 10 ;

1
sql/2020-04-22.sql Normal file
View File

@ -0,0 +1 @@
alter table book_parse_log add column `update_count` TINYINT(2) not null default 0 ;

View File

@ -1,23 +1,4 @@
/*
Navicat MySQL Data Transfer
Source Server : aliyun_books
Source Server Version : 80018
Source Host : 47.106.243.172:3306
Source Database : books
Target Server Type : MYSQL
Target Server Version : 80018
File Encoding : 65001
Date: 2019-11-15 06:10:36
*/
-- ----------------------------
-- Table structure for `book`
-- ----------------------------
DROP TABLE IF EXISTS `book`; DROP TABLE IF EXISTS `book`;
CREATE TABLE `book` ( CREATE TABLE `book` (
`id` bigint(20) NOT NULL AUTO_INCREMENT, `id` bigint(20) NOT NULL AUTO_INCREMENT,
@ -1024,3 +1005,26 @@ CREATE TABLE `book_parse_log` (
UNIQUE KEY `uq_key_bookurl` (`book_url`) UNIQUE KEY `uq_key_bookurl` (`book_url`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
DROP TABLE IF EXISTS `book_update_time_log`;
CREATE TABLE `book_update_time_log` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`book_cat_id` int(11) NOT NULL,
`last_update_time` datetime DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `uq_key_catid` (`book_cat_id`)
) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8mb4;
INSERT INTO `book_update_time_log` VALUES ('1', '1', NOW());
INSERT INTO `book_update_time_log` VALUES ('2', '2', NOW());
INSERT INTO `book_update_time_log` VALUES ('3', '3', NOW());
INSERT INTO `book_update_time_log` VALUES ('4', '4', NOW());
INSERT INTO `book_update_time_log` VALUES ('5', '5', NOW());
INSERT INTO `book_update_time_log` VALUES ('6', '6', NOW());
INSERT INTO `book_update_time_log` VALUES ('7', '7', NOW());
ALTER TABLE book_parse_log drop INDEX uq_key_bookurl;
alter table book_parse_log add column `priority` TINYINT(2) not null default 10 ;
alter table book_parse_log add column `update_count` TINYINT(2) not null default 0 ;