Compare commits

..

31 Commits

Author SHA1 Message Date
80b393fdda v3.6.0发布 2021-08-17 21:14:15 +08:00
e7897c988a 更新文档 2021-08-17 20:00:53 +08:00
750c8dee02 增加小说内容TXT文本存储方案(一行配置切换) 2021-08-17 19:55:24 +08:00
cbfd0b049f 爬虫部分代码重构,准备适配TXT文本存储方案 2021-08-17 11:08:51 +08:00
7f0331e095 解决爬虫运行时的UnrecognizedPropertyException 2021-08-16 15:58:32 +08:00
3520200a87 部分代码重构 2021-08-16 15:42:56 +08:00
4939bcf418 模版更新 2021-08-09 19:46:32 +08:00
1cffbae495 增加新闻阅读数 2021-07-26 19:06:57 +08:00
b99b6ae4f2 新闻详情时间显示 2021-07-24 17:52:25 +08:00
2e2a58c84b Merge pull request #41 from 201206030/dependabot/maven/novel-admin/org.apache.shiro-shiro-spring-1.7.0
Bump shiro-spring from 1.3.2 to 1.7.0 in /novel-admin
2021-07-24 16:54:19 +08:00
4fe36a8f4f 部分爬虫代码优化 2021-07-24 15:51:54 +08:00
b5df86d5c7 perf(index.html): orange模版更新 2021-07-03 12:00:17 +08:00
9b3ba1d8c1 perf(index): 首页优化 2021-07-03 11:51:47 +08:00
c4db754d23 docs(readme): 更新官网地址 2021-06-10 09:42:07 +08:00
8d3ce53dba build(pom): v3.5.4发布 2021-06-01 23:14:35 +08:00
d32d9d8410 perf(html): 模版更新 2021-06-01 23:13:18 +08:00
05ae012e05 fix(yml): Public Key Retrieval is not allowed 2021-06-01 23:03:15 +08:00
b60a0c9b40 perf(监控): 设置druid监控信息登陆后查看 2021-06-01 22:49:23 +08:00
3efaf8ce5f perf(评论): 优化评论显示 2021-06-01 22:01:05 +08:00
ebc4210774 fix(章节更新): xss 2021-06-01 21:44:18 +08:00
655ec90906 fix(data submit): Xss攻击 2021-06-01 20:58:06 +08:00
f28dd867ef v3.5.3发布 2021-05-28 20:32:08 +08:00
8e6842a495 模版更新 2021-05-28 20:08:45 +08:00
928cb2417f 小说详情页优化 2021-05-28 20:04:52 +08:00
625694ba1e Merge branch 'release_3.5.3' into develop_xxy 2021-05-28 11:54:24 +08:00
d6c0337c09 首页SEO优化 2021-05-28 11:51:11 +08:00
689efc0807 style(novel-common/bean): ResultBean更新
代码格式化,去除多余分号
2021-05-16 10:54:25 +08:00
4540c3781e 模版更新 2021-05-16 09:49:35 +08:00
9d2c453bb0 图片上传流程优化 2021-05-16 09:47:23 +08:00
xxy
9de47ce697 update README.md. 2021-04-25 07:39:56 +08:00
e83494cb17 Bump shiro-spring from 1.3.2 to 1.7.0 in /novel-admin
Bumps shiro-spring from 1.3.2 to 1.7.0.

Signed-off-by: dependabot[bot] <support@github.com>
2021-04-22 17:07:42 +00:00
179 changed files with 1591 additions and 7399 deletions

1
.gitignore vendored
View File

@ -3,4 +3,5 @@
**/cachedata **/cachedata
**/target **/target
**/*.iml **/*.iml
**/.DS_Store

View File

@ -9,7 +9,7 @@
#### 官网 #### 官网
https://xiongxyang.gitee.io https://201206030.github.io
#### 新项目小说精品屋-微服务版 #### 新项目小说精品屋-微服务版
@ -35,6 +35,7 @@ Gitee仓库地址 https://gitee.com/novel_dev_team/novel-cloud
- [x] 移动站与PC站站点分离浏览器自动识别跳转 - [x] 移动站与PC站站点分离浏览器自动识别跳转
- [x] PC站UI更新 - [x] PC站UI更新
- [x] 支持前端模版自定义内置多套模版 - [x] 支持前端模版自定义内置多套模版
- [x] 可拓展的多种方式存储小说内容内置数据库分表存储和TXT文本存储
- [x] 新闻模块 - [x] 新闻模块
- [x] 排行榜 - [x] 排行榜
- [x] 小说评论模块 - [x] 小说评论模块
@ -262,7 +263,7 @@ novel-plus -- 父工程
**喜欢此项目的可以给我的GitHub和Gitee加个Star支持一下 ** **喜欢此项目的可以给我的GitHub和Gitee加个Star支持一下 **
#### 其他安装教程 #### 其他安装教程如果链接打不开可关注公众号获取
##### version>=3.5.0版本 ##### version>=3.5.0版本

1
doc/sql/20210726.sql Normal file
View File

@ -0,0 +1 @@
alter table news add column `read_count` BIGINT NOT NULL DEFAULT '0' COMMENT '阅读量' after content;

View File

@ -1838,4 +1838,6 @@ INSERT INTO `sys_role_menu`(`id`, `role_id`, `menu_id`) VALUES (4888, 1, 234);
delete from sys_menu where menu_id = 202; delete from sys_menu where menu_id = 202;
INSERT INTO crawl_source(`id`, `source_name`, `crawl_rule`, `source_status`, `create_time`, `update_time`) VALUES (16, 'i笔趣阁', '{\"bookListUrl\":\"http://m.ibiquge.net/xclass/{catId}/{page}.html\",\"catIdRule\":{\"catId1\":\"1\",\"catId2\":\"2\",\"catId3\":\"3\",\"catId4\":\"4\",\"catId5\":\"6\",\"catId6\":\"5\",\"catId7\":\"7\"},\"bookIdPatten\":\"href=\\\"/(\\\\d+_\\\\d+)/\\\"\",\"pagePatten\":\"value=\\\"(\\\\d+)/\\\\d+\\\"\",\"totalPagePatten\":\"value=\\\"\\\\d+/(\\\\d+)\\\"\",\"bookDetailUrl\":\"http://m.ibiquge.net/{bookId}/\",\"bookNamePatten\":\"<span class=\\\"title\\\">([^/]+)</span>\",\"authorNamePatten\":\"<a href=\\\"/author/\\\\d+/\\\">([^/]+)</a>\",\"picUrlPatten\":\"<img src=\\\"([^>]+)\\\"\\\\s+onerror=\\\"this.src=\",\"picUrlPrefix\":\"http://m.ibiquge.net\",\"statusPatten\":\">状态:([^/]+)</li>\",\"bookStatusRule\":{\"连载\":0,\"完结\":1},\"visitCountPatten\":\">点击:(\\\\d+)</li>\",\"descStart\":\"<p class=\\\"review\\\">\",\"descEnd\":\"</p>\",\"bookIndexUrl\":\"http://www.ibiquge.net/{bookId}/\",\"bookIndexStart\":\"正文</dt>\",\"indexIdPatten\":\"<a\\\\s+style=\\\"\\\"\\\\s+href=\\\"/\\\\d+_\\\\d+/(\\\\d+)\\\\.html\\\">[^/]+</a>\",\"indexNamePatten\":\"<a\\\\s+style=\\\"\\\"\\\\s+href=\\\"/\\\\d+_\\\\d+/\\\\d+\\\\.html\\\">([^/]+)</a>\",\"bookContentUrl\":\"http://www.ibiquge.net/{bookId}/{indexId}.html\",\"contentStart\":\"</p>\",\"contentEnd\":\"<div align=\\\"center\\\">\"}', 0, '2021-02-04 21:31:23', '2021-02-04 21:31:23'); INSERT INTO crawl_source(`id`, `source_name`, `crawl_rule`, `source_status`, `create_time`, `update_time`) VALUES (16, 'i笔趣阁', '{\"bookListUrl\":\"http://m.ibiquge.net/xclass/{catId}/{page}.html\",\"catIdRule\":{\"catId1\":\"1\",\"catId2\":\"2\",\"catId3\":\"3\",\"catId4\":\"4\",\"catId5\":\"6\",\"catId6\":\"5\",\"catId7\":\"7\"},\"bookIdPatten\":\"href=\\\"/(\\\\d+_\\\\d+)/\\\"\",\"pagePatten\":\"value=\\\"(\\\\d+)/\\\\d+\\\"\",\"totalPagePatten\":\"value=\\\"\\\\d+/(\\\\d+)\\\"\",\"bookDetailUrl\":\"http://m.ibiquge.net/{bookId}/\",\"bookNamePatten\":\"<span class=\\\"title\\\">([^/]+)</span>\",\"authorNamePatten\":\"<a href=\\\"/author/\\\\d+/\\\">([^/]+)</a>\",\"picUrlPatten\":\"<img src=\\\"([^>]+)\\\"\\\\s+onerror=\\\"this.src=\",\"picUrlPrefix\":\"http://m.ibiquge.net\",\"statusPatten\":\">状态:([^/]+)</li>\",\"bookStatusRule\":{\"连载\":0,\"完结\":1},\"visitCountPatten\":\">点击:(\\\\d+)</li>\",\"descStart\":\"<p class=\\\"review\\\">\",\"descEnd\":\"</p>\",\"bookIndexUrl\":\"http://www.ibiquge.net/{bookId}/\",\"bookIndexStart\":\"正文</dt>\",\"indexIdPatten\":\"<a\\\\s+style=\\\"\\\"\\\\s+href=\\\"/\\\\d+_\\\\d+/(\\\\d+)\\\\.html\\\">[^/]+</a>\",\"indexNamePatten\":\"<a\\\\s+style=\\\"\\\"\\\\s+href=\\\"/\\\\d+_\\\\d+/\\\\d+\\\\.html\\\">([^/]+)</a>\",\"bookContentUrl\":\"http://www.ibiquge.net/{bookId}/{indexId}.html\",\"contentStart\":\"</p>\",\"contentEnd\":\"<div align=\\\"center\\\">\"}', 0, '2021-02-04 21:31:23', '2021-02-04 21:31:23');
alter table news add column `read_count` BIGINT NOT NULL DEFAULT '0' COMMENT '阅读量' after content;

View File

@ -5,7 +5,7 @@
<groupId>com.java2nb</groupId> <groupId>com.java2nb</groupId>
<artifactId>novel-admin</artifactId> <artifactId>novel-admin</artifactId>
<version>3.5.2</version> <version>3.6.0</version>
<packaging>jar</packaging> <packaging>jar</packaging>
<name>novel-admin</name> <name>novel-admin</name>

View File

@ -75,7 +75,6 @@ public class ShiroConfig {
filterChainDefinitionMap.put("/img/**", "anon"); filterChainDefinitionMap.put("/img/**", "anon");
filterChainDefinitionMap.put("/docs/**", "anon"); filterChainDefinitionMap.put("/docs/**", "anon");
filterChainDefinitionMap.put("/layuimini/**", "anon"); filterChainDefinitionMap.put("/layuimini/**", "anon");
filterChainDefinitionMap.put("/druid/**", "anon");
filterChainDefinitionMap.put("/upload/**", "anon"); filterChainDefinitionMap.put("/upload/**", "anon");
filterChainDefinitionMap.put("/files/**", "anon"); filterChainDefinitionMap.put("/files/**", "anon");
filterChainDefinitionMap.put("/logout", "logout"); filterChainDefinitionMap.put("/logout", "logout");

View File

@ -10,7 +10,7 @@ spring:
datasource: datasource:
type: com.alibaba.druid.pool.DruidDataSource type: com.alibaba.druid.pool.DruidDataSource
driverClassName: com.mysql.cj.jdbc.Driver driverClassName: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai url: jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
username: root username: root
password: test123456 password: test123456
#password: #password:

View File

@ -10,7 +10,7 @@ spring:
datasource: datasource:
type: com.alibaba.druid.pool.DruidDataSource type: com.alibaba.druid.pool.DruidDataSource
driverClassName: com.mysql.cj.jdbc.Driver driverClassName: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai url: jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
username: root username: root
password: test123456 password: test123456
#password: #password:

View File

@ -5,7 +5,7 @@
<parent> <parent>
<artifactId>novel</artifactId> <artifactId>novel</artifactId>
<groupId>com.java2nb</groupId> <groupId>com.java2nb</groupId>
<version>3.5.2</version> <version>3.6.0</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

View File

@ -8,8 +8,9 @@ import java.io.Serializable;
/** /**
* 自定义响应结构 * 自定义响应结构
* @author 11797 *
* @param <T> * @param <T>
* @author 11797
*/ */
@Data @Data
public class ResultBean<T> implements Serializable { public class ResultBean<T> implements Serializable {
@ -19,20 +20,20 @@ public class ResultBean<T> implements Serializable {
/** /**
* 响应消息 * 响应消息
* */ */
private String msg = ResponseStatus.OK.getMsg(); private String msg = ResponseStatus.OK.getMsg();
/** /**
* 响应中的数据 * 响应中的数据
* */ */
private T data; private T data;
private ResultBean() { private ResultBean() {
} }
private ResultBean(ResponseStatus ResponseStatus) { private ResultBean(ResponseStatus responseStatus) {
this.code = ResponseStatus.getCode();; this.code = responseStatus.getCode();
this.msg = ResponseStatus.getMsg(); this.msg = responseStatus.getMsg();
} }
private ResultBean(T data) { private ResultBean(T data) {
@ -40,34 +41,33 @@ public class ResultBean<T> implements Serializable {
} }
/** /**
* 业务处理成功,无数据返回 * 业务处理成功,无数据返回
* */ */
public static ResultBean ok() { public static ResultBean<Void> ok() {
return new ResultBean(); return new ResultBean<>();
} }
/** /**
* 业务处理成功,有数据返回 * 业务处理成功,有数据返回
* */ */
public static <T> ResultBean ok(T data) { public static <T> ResultBean<T> ok(T data) {
return new ResultBean(data); return new ResultBean<>(data);
} }
/** /**
* 业务处理失败 * 业务处理失败
* */ */
public static ResultBean fail(ResponseStatus ResponseStatus) { public static ResultBean<Void> fail(ResponseStatus responseStatus) {
return new ResultBean(ResponseStatus); return new ResultBean<>(responseStatus);
} }
/** /**
* 系统错误 * 系统错误
* */ */
public static ResultBean error() { public static ResultBean<Void> error() {
return new ResultBean(ResponseStatus.ERROR); return new ResultBean<>(ResponseStatus.ERROR);
} }
} }

View File

@ -16,108 +16,107 @@ import org.springframework.stereotype.Service;
@RequiredArgsConstructor @RequiredArgsConstructor
@Service @Service
public class EhCacheServiceImpl implements CacheService { public class EhCacheServiceImpl implements CacheService {
private final CacheManager cacheManager ;
/** private final CacheManager cacheManager;
* 获得一个Cache没有则创建一个。
* @return
*/
private Cache getCache(){
Cache cache = cacheManager.getCache("util_cache");
return cache;
}
@Override
public String get(String key) {
Element element = getCache().get(key);
return element==null?null:(String)element.getObjectValue();
}
@Override
public void set(String key, String value) {
Element element = new Element(key, value);
Cache cache = getCache();
//不过期
cache.getCacheConfiguration().setEternal(true);
cache.put(element);
}
@Override
public void set(String key, String value, long timeout) {
Element element = new Element(key, value);
element.setTimeToLive((int) timeout);
Cache cache = getCache();
cache.put(element);
}
@Override
public void del(String key) {
getCache().remove(key);
} /**
* 获得一个Cache没有则创建一个。
*
* @return
*/
private Cache getCache() {
@Override Cache cache = cacheManager.getCache("util_cache");
public boolean contains(String key) { return cache;
return getCache().isKeyInCache(key); }
}
@Override
public void expire(String key, long timeout) {
Element element = getCache().get(key);
if (element != null) {
Object value = element.getValue();
element = new Element(key, value);
element.setTimeToLive((int)timeout);
Cache cache = getCache();
cache.put(element);
}
}
/** @Override
* 根据key获取缓存的Object类型数据 public String get(String key) {
*/ Element element = getCache().get(key);
@Override return element == null ? null : (String) element.getObjectValue();
public Object getObject(String key) { }
Element element = getCache().get(key);
return element==null?null:element.getObjectValue(); @Override
} public void set(String key, String value) {
Element element = new Element(key, value);
Cache cache = getCache();
//不过期
cache.getCacheConfiguration().setEternal(true);
cache.put(element);
}
@Override
public void set(String key, String value, long timeout) {
Element element = new Element(key, value);
element.setTimeToLive((int) timeout);
Cache cache = getCache();
cache.put(element);
}
@Override
public void del(String key) {
getCache().remove(key);
/** }
* 设置Object类型的缓存
*/ @Override
@Override public boolean contains(String key) {
public void setObject(String key, Object value) { return getCache().isKeyInCache(key);
Element element = new Element(key, value); }
Cache cache = getCache();
//不过期 @Override
cache.getCacheConfiguration().setEternal(true); public void expire(String key, long timeout) {
cache.put(element); Element element = getCache().get(key);
if (element != null) {
} Object value = element.getValue();
element = new Element(key, value);
element.setTimeToLive((int) timeout);
Cache cache = getCache();
cache.put(element);
}
}
/** /**
* 设置一个有过期时间的Object类型的缓存,单位秒 * 根据key获取缓存的Object类型数据
*/ */
@Override @Override
public void setObject(String key, Object value, long timeout) { public Object getObject(String key) {
Element element = new Element(key, value); Element element = getCache().get(key);
element.setTimeToLive((int) timeout); return element == null ? null : element.getObjectValue();
Cache cache = getCache(); }
cache.put(element);
}
/**
* 设置Object类型的缓存
*/
@Override
public void setObject(String key, Object value) {
Element element = new Element(key, value);
Cache cache = getCache();
//不过期
cache.getCacheConfiguration().setEternal(true);
cache.put(element);
}
/**
* 设置一个有过期时间的Object类型的缓存,单位秒
*/
@Override
public void setObject(String key, Object value, long timeout) {
Element element = new Element(key, value);
element.setTimeToLive((int) timeout);
Cache cache = getCache();
cache.put(element);
}
} }

View File

@ -68,6 +68,12 @@ public enum ResponseStatus {
* */ * */
ES_SEARCH_FAIL(9001,"搜索引擎查询错误!"), ES_SEARCH_FAIL(9001,"搜索引擎查询错误!"),
/**
* 文件相关错误
* */
FILE_DIR_MAKE_FAIL(10001,"目录创建失败"),
FILE_NOT_IMAGE(10002,"请上传图片类型的文件"),
FILE_SIZE_LIMIT(10003,"文件大小超出限制"),
/** /**
* 其他通用错误 * 其他通用错误

View File

@ -19,7 +19,7 @@ public class BeanUtil {
* @return 新集合 * @return 新集合
* */ * */
@SneakyThrows @SneakyThrows
public static <T> List<T> copyList(List source,Class<T> targetClass){ public static <T> List<T> copyList(List<? super T> source,Class<T> targetClass){
List<T> target = new ArrayList<>(source.size()); List<T> target = new ArrayList<>(source.size());
for( int i = 0 ; i < source.size() ; i++){ for( int i = 0 ; i < source.size() ; i++){
Object sourceItem = source.get(i); Object sourceItem = source.get(i);

View File

@ -1,6 +1,7 @@
package com.java2nb.novel.core.utils; package com.java2nb.novel.core.utils;
import lombok.SneakyThrows; import lombok.SneakyThrows;
import lombok.experimental.UtilityClass;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.Charsets; import org.apache.commons.codec.Charsets;
import org.apache.http.client.utils.DateUtils; import org.apache.http.client.utils.DateUtils;
@ -11,21 +12,24 @@ import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import javax.imageio.ImageIO; import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.*; import java.io.*;
import java.util.Date; import java.util.Date;
import java.util.Objects; import java.util.Objects;
/** /**
* 文件操作工具类 * 文件操作工具类
*
* @author 11797 * @author 11797
*/ */
@UtilityClass
@Slf4j @Slf4j
public class FileUtil { public class FileUtil {
/** /**
* 网络图片转本地 * 网络图片转本地
* */ */
public static String network2Local(String picSrc,String picSavePath,String visitPrefix) { public String network2Local(String picSrc, String picSavePath, String visitPrefix) {
InputStream input = null; InputStream input = null;
OutputStream out = null; OutputStream out = null;
try { try {
@ -50,37 +54,70 @@ public class FileUtil {
} }
out.flush(); out.flush();
if( ImageIO.read(picFile) == null){ if (ImageIO.read(picFile) == null) {
picSrc = "/images/default.gif"; picSrc = "/images/default.gif";
} }
}catch (Exception e){ } catch (Exception e) {
log.error(e.getMessage(),e); log.error(e.getMessage(), e);
picSrc = "/images/default.gif"; picSrc = "/images/default.gif";
}finally { } finally {
if(input != null){ closeStream(input, out);
try {
input.close();
} catch (IOException e) {
log.error(e.getMessage(),e);
}finally {
if(out != null){
try {
out.close();
} catch (IOException e) {
log.error(e.getMessage(),e);
}
}
}
}
} }
return picSrc; return picSrc;
} }
@SneakyThrows
private void closeStream(InputStream input, OutputStream out) {
if (input != null) {
input.close();
}
if (out != null) {
out.close();
}
}
/**
* 判断文件是否为图片
*
* @param file 需要判断的文件
* @return true:是图片false:不是图片
*/
@SneakyThrows
public boolean isImage(File file) {
BufferedImage bi = ImageIO.read(file);
return bi != null;
}
public void writeContentToFile(String fileSavePath, String fileSrc, String content) {
OutputStream out = null;
try {
File file = new File(fileSavePath + fileSrc);
File parentFile = file.getParentFile();
if (!parentFile.exists()) {
parentFile.mkdirs();
}
out = new FileOutputStream(file);
out.write(content.getBytes());
byte[] b = new byte[4096];
out.flush();
} catch (Exception e) {
log.error(e.getMessage(), e);
throw new RuntimeException("文件写入失败");
} finally {
closeStream(null, out);
}
}
} }

View File

@ -1,11 +1,9 @@
package com.java2nb.novel.entity; package com.java2nb.novel.entity;
import javax.annotation.Generated;
import java.io.Serializable;
import java.util.Date; import java.util.Date;
import javax.annotation.Generated;
public class News implements Serializable { public class News {
@Generated("org.mybatis.generator.api.MyBatisGenerator") @Generated("org.mybatis.generator.api.MyBatisGenerator")
private Long id; private Long id;
@ -21,6 +19,9 @@ public class News implements Serializable {
@Generated("org.mybatis.generator.api.MyBatisGenerator") @Generated("org.mybatis.generator.api.MyBatisGenerator")
private String title; private String title;
@Generated("org.mybatis.generator.api.MyBatisGenerator")
private Long readCount;
@Generated("org.mybatis.generator.api.MyBatisGenerator") @Generated("org.mybatis.generator.api.MyBatisGenerator")
private Date createTime; private Date createTime;
@ -86,6 +87,16 @@ public class News implements Serializable {
this.title = title == null ? null : title.trim(); this.title = title == null ? null : title.trim();
} }
@Generated("org.mybatis.generator.api.MyBatisGenerator")
public Long getReadCount() {
return readCount;
}
@Generated("org.mybatis.generator.api.MyBatisGenerator")
public void setReadCount(Long readCount) {
this.readCount = readCount;
}
@Generated("org.mybatis.generator.api.MyBatisGenerator") @Generated("org.mybatis.generator.api.MyBatisGenerator")
public Date getCreateTime() { public Date getCreateTime() {
return createTime; return createTime;

View File

@ -25,6 +25,9 @@ public final class NewsDynamicSqlSupport {
@Generated("org.mybatis.generator.api.MyBatisGenerator") @Generated("org.mybatis.generator.api.MyBatisGenerator")
public static final SqlColumn<String> title = news.title; public static final SqlColumn<String> title = news.title;
@Generated("org.mybatis.generator.api.MyBatisGenerator")
public static final SqlColumn<Long> readCount = news.readCount;
@Generated("org.mybatis.generator.api.MyBatisGenerator") @Generated("org.mybatis.generator.api.MyBatisGenerator")
public static final SqlColumn<Date> createTime = news.createTime; public static final SqlColumn<Date> createTime = news.createTime;
@ -52,6 +55,8 @@ public final class NewsDynamicSqlSupport {
public final SqlColumn<String> title = column("title", JDBCType.VARCHAR); public final SqlColumn<String> title = column("title", JDBCType.VARCHAR);
public final SqlColumn<Long> readCount = column("read_count", JDBCType.BIGINT);
public final SqlColumn<Date> createTime = column("create_time", JDBCType.TIMESTAMP); public final SqlColumn<Date> createTime = column("create_time", JDBCType.TIMESTAMP);
public final SqlColumn<Long> createUserId = column("create_user_id", JDBCType.BIGINT); public final SqlColumn<Long> createUserId = column("create_user_id", JDBCType.BIGINT);

View File

@ -35,7 +35,7 @@ import org.mybatis.dynamic.sql.util.mybatis3.MyBatis3Utils;
@Mapper @Mapper
public interface NewsMapper { public interface NewsMapper {
@Generated("org.mybatis.generator.api.MyBatisGenerator") @Generated("org.mybatis.generator.api.MyBatisGenerator")
BasicColumn[] selectList = BasicColumn.columnList(id, catId, catName, sourceName, title, createTime, createUserId, updateTime, updateUserId, content); BasicColumn[] selectList = BasicColumn.columnList(id, catId, catName, sourceName, title, readCount, createTime, createUserId, updateTime, updateUserId, content);
@Generated("org.mybatis.generator.api.MyBatisGenerator") @Generated("org.mybatis.generator.api.MyBatisGenerator")
@SelectProvider(type=SqlProviderAdapter.class, method="select") @SelectProvider(type=SqlProviderAdapter.class, method="select")
@ -66,6 +66,7 @@ public interface NewsMapper {
@Result(column="cat_name", property="catName", jdbcType=JdbcType.VARCHAR), @Result(column="cat_name", property="catName", jdbcType=JdbcType.VARCHAR),
@Result(column="source_name", property="sourceName", jdbcType=JdbcType.VARCHAR), @Result(column="source_name", property="sourceName", jdbcType=JdbcType.VARCHAR),
@Result(column="title", property="title", jdbcType=JdbcType.VARCHAR), @Result(column="title", property="title", jdbcType=JdbcType.VARCHAR),
@Result(column="read_count", property="readCount", jdbcType=JdbcType.BIGINT),
@Result(column="create_time", property="createTime", jdbcType=JdbcType.TIMESTAMP), @Result(column="create_time", property="createTime", jdbcType=JdbcType.TIMESTAMP),
@Result(column="create_user_id", property="createUserId", jdbcType=JdbcType.BIGINT), @Result(column="create_user_id", property="createUserId", jdbcType=JdbcType.BIGINT),
@Result(column="update_time", property="updateTime", jdbcType=JdbcType.TIMESTAMP), @Result(column="update_time", property="updateTime", jdbcType=JdbcType.TIMESTAMP),
@ -103,6 +104,7 @@ public interface NewsMapper {
.map(catName).toProperty("catName") .map(catName).toProperty("catName")
.map(sourceName).toProperty("sourceName") .map(sourceName).toProperty("sourceName")
.map(title).toProperty("title") .map(title).toProperty("title")
.map(readCount).toProperty("readCount")
.map(createTime).toProperty("createTime") .map(createTime).toProperty("createTime")
.map(createUserId).toProperty("createUserId") .map(createUserId).toProperty("createUserId")
.map(updateTime).toProperty("updateTime") .map(updateTime).toProperty("updateTime")
@ -119,6 +121,7 @@ public interface NewsMapper {
.map(catName).toProperty("catName") .map(catName).toProperty("catName")
.map(sourceName).toProperty("sourceName") .map(sourceName).toProperty("sourceName")
.map(title).toProperty("title") .map(title).toProperty("title")
.map(readCount).toProperty("readCount")
.map(createTime).toProperty("createTime") .map(createTime).toProperty("createTime")
.map(createUserId).toProperty("createUserId") .map(createUserId).toProperty("createUserId")
.map(updateTime).toProperty("updateTime") .map(updateTime).toProperty("updateTime")
@ -135,6 +138,7 @@ public interface NewsMapper {
.map(catName).toPropertyWhenPresent("catName", record::getCatName) .map(catName).toPropertyWhenPresent("catName", record::getCatName)
.map(sourceName).toPropertyWhenPresent("sourceName", record::getSourceName) .map(sourceName).toPropertyWhenPresent("sourceName", record::getSourceName)
.map(title).toPropertyWhenPresent("title", record::getTitle) .map(title).toPropertyWhenPresent("title", record::getTitle)
.map(readCount).toPropertyWhenPresent("readCount", record::getReadCount)
.map(createTime).toPropertyWhenPresent("createTime", record::getCreateTime) .map(createTime).toPropertyWhenPresent("createTime", record::getCreateTime)
.map(createUserId).toPropertyWhenPresent("createUserId", record::getCreateUserId) .map(createUserId).toPropertyWhenPresent("createUserId", record::getCreateUserId)
.map(updateTime).toPropertyWhenPresent("updateTime", record::getUpdateTime) .map(updateTime).toPropertyWhenPresent("updateTime", record::getUpdateTime)
@ -177,6 +181,7 @@ public interface NewsMapper {
.set(catName).equalTo(record::getCatName) .set(catName).equalTo(record::getCatName)
.set(sourceName).equalTo(record::getSourceName) .set(sourceName).equalTo(record::getSourceName)
.set(title).equalTo(record::getTitle) .set(title).equalTo(record::getTitle)
.set(readCount).equalTo(record::getReadCount)
.set(createTime).equalTo(record::getCreateTime) .set(createTime).equalTo(record::getCreateTime)
.set(createUserId).equalTo(record::getCreateUserId) .set(createUserId).equalTo(record::getCreateUserId)
.set(updateTime).equalTo(record::getUpdateTime) .set(updateTime).equalTo(record::getUpdateTime)
@ -191,6 +196,7 @@ public interface NewsMapper {
.set(catName).equalToWhenPresent(record::getCatName) .set(catName).equalToWhenPresent(record::getCatName)
.set(sourceName).equalToWhenPresent(record::getSourceName) .set(sourceName).equalToWhenPresent(record::getSourceName)
.set(title).equalToWhenPresent(record::getTitle) .set(title).equalToWhenPresent(record::getTitle)
.set(readCount).equalToWhenPresent(record::getReadCount)
.set(createTime).equalToWhenPresent(record::getCreateTime) .set(createTime).equalToWhenPresent(record::getCreateTime)
.set(createUserId).equalToWhenPresent(record::getCreateUserId) .set(createUserId).equalToWhenPresent(record::getCreateUserId)
.set(updateTime).equalToWhenPresent(record::getUpdateTime) .set(updateTime).equalToWhenPresent(record::getUpdateTime)
@ -205,6 +211,7 @@ public interface NewsMapper {
.set(catName).equalTo(record::getCatName) .set(catName).equalTo(record::getCatName)
.set(sourceName).equalTo(record::getSourceName) .set(sourceName).equalTo(record::getSourceName)
.set(title).equalTo(record::getTitle) .set(title).equalTo(record::getTitle)
.set(readCount).equalTo(record::getReadCount)
.set(createTime).equalTo(record::getCreateTime) .set(createTime).equalTo(record::getCreateTime)
.set(createUserId).equalTo(record::getCreateUserId) .set(createUserId).equalTo(record::getCreateUserId)
.set(updateTime).equalTo(record::getUpdateTime) .set(updateTime).equalTo(record::getUpdateTime)
@ -221,6 +228,7 @@ public interface NewsMapper {
.set(catName).equalToWhenPresent(record::getCatName) .set(catName).equalToWhenPresent(record::getCatName)
.set(sourceName).equalToWhenPresent(record::getSourceName) .set(sourceName).equalToWhenPresent(record::getSourceName)
.set(title).equalToWhenPresent(record::getTitle) .set(title).equalToWhenPresent(record::getTitle)
.set(readCount).equalToWhenPresent(record::getReadCount)
.set(createTime).equalToWhenPresent(record::getCreateTime) .set(createTime).equalToWhenPresent(record::getCreateTime)
.set(createUserId).equalToWhenPresent(record::getCreateUserId) .set(createUserId).equalToWhenPresent(record::getCreateUserId)
.set(updateTime).equalToWhenPresent(record::getUpdateTime) .set(updateTime).equalToWhenPresent(record::getUpdateTime)

View File

@ -71,3 +71,7 @@ sharding:
txt:
save:
storage: db #存储介质db数据库filetxt文本
path: /Users/xiongxiaoyang/books #txt小说文本保存路径

View File

@ -74,7 +74,10 @@ logging:
txt:
save:
storage: db #存储介质db数据库filetxt文本
path: /Users/xiongxiaoyang/books #txt小说文本保存路径

View File

@ -11,6 +11,11 @@ spring:
generator: generator:
write-numbers-as-strings: true write-numbers-as-strings: true
#上传文件的最大值1M
servlet:
multipart:
max-file-size: 1048576
#缓存类型ehcache(默认)redis #缓存类型ehcache(默认)redis
cache: cache:
type: ehcache type: ehcache
@ -26,3 +31,5 @@ logging:
config: classpath:logback-boot.xml config: classpath:logback-boot.xml

View File

@ -44,7 +44,7 @@
</javaClientGenerator> </javaClientGenerator>
<!--生成全部表tableName设为%--> <!--生成全部表tableName设为%-->
<table tableName="book"/> <table tableName="book_index"/>
<!-- 指定数据库表 --> <!-- 指定数据库表 -->
<!--<table schema="jly" tableName="job_position" domainObjectName="JobPositionTest"/>--> <!--<table schema="jly" tableName="job_position" domainObjectName="JobPositionTest"/>-->

View File

@ -5,7 +5,7 @@
<parent> <parent>
<artifactId>novel</artifactId> <artifactId>novel</artifactId>
<groupId>com.java2nb</groupId> <groupId>com.java2nb</groupId>
<version>3.5.2</version> <version>3.6.0</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

View File

@ -1,13 +1,10 @@
package com.java2nb.novel.controller; package com.java2nb.novel.controller;
import com.github.pagehelper.PageInfo; import com.java2nb.novel.core.bean.PageBean;
import com.java2nb.novel.core.bean.ResultBean; import com.java2nb.novel.core.bean.ResultBean;
import com.java2nb.novel.core.utils.BeanUtil;
import com.java2nb.novel.entity.CrawlSingleTask; import com.java2nb.novel.entity.CrawlSingleTask;
import com.java2nb.novel.entity.CrawlSource; import com.java2nb.novel.entity.CrawlSource;
import com.java2nb.novel.service.CrawlService; import com.java2nb.novel.service.CrawlService;
import com.java2nb.novel.vo.CrawlSingleTaskVO;
import com.java2nb.novel.vo.CrawlSourceVO;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
@ -26,7 +23,7 @@ public class CrawlController {
* 新增爬虫源 * 新增爬虫源
* */ * */
@PostMapping("addCrawlSource") @PostMapping("addCrawlSource")
public ResultBean addCrawlSource(CrawlSource source){ public ResultBean<Void> addCrawlSource(CrawlSource source){
crawlService.addCrawlSource(source); crawlService.addCrawlSource(source);
return ResultBean.ok(); return ResultBean.ok();
@ -37,7 +34,7 @@ public class CrawlController {
* 爬虫源分页列表查询 * 爬虫源分页列表查询
* */ * */
@GetMapping("listCrawlByPage") @GetMapping("listCrawlByPage")
public ResultBean listCrawlByPage(@RequestParam(value = "curr", defaultValue = "1") int page, @RequestParam(value = "limit", defaultValue = "10") int pageSize){ public ResultBean<PageBean<CrawlSource>> listCrawlByPage(@RequestParam(value = "curr", defaultValue = "1") int page, @RequestParam(value = "limit", defaultValue = "10") int pageSize){
return ResultBean.ok(crawlService.listCrawlByPage(page,pageSize)); return ResultBean.ok(crawlService.listCrawlByPage(page,pageSize));
} }
@ -46,7 +43,7 @@ public class CrawlController {
* 开启或停止爬虫 * 开启或停止爬虫
* */ * */
@PostMapping("openOrCloseCrawl") @PostMapping("openOrCloseCrawl")
public ResultBean openOrCloseCrawl(Integer sourceId,Byte sourceStatus){ public ResultBean<Void> openOrCloseCrawl(Integer sourceId,Byte sourceStatus){
crawlService.openOrCloseCrawl(sourceId,sourceStatus); crawlService.openOrCloseCrawl(sourceId,sourceStatus);
@ -57,7 +54,7 @@ public class CrawlController {
* 新增单本采集任务 * 新增单本采集任务
* */ * */
@PostMapping("addCrawlSingleTask") @PostMapping("addCrawlSingleTask")
public ResultBean addCrawlSingleTask(CrawlSingleTask singleTask){ public ResultBean<Void> addCrawlSingleTask(CrawlSingleTask singleTask){
crawlService.addCrawlSingleTask(singleTask); crawlService.addCrawlSingleTask(singleTask);
return ResultBean.ok(); return ResultBean.ok();
@ -68,7 +65,7 @@ public class CrawlController {
* 单本采集任务分页列表查询 * 单本采集任务分页列表查询
* */ * */
@GetMapping("listCrawlSingleTaskByPage") @GetMapping("listCrawlSingleTaskByPage")
public ResultBean listCrawlSingleTaskByPage(@RequestParam(value = "curr", defaultValue = "1") int page, @RequestParam(value = "limit", defaultValue = "10") int pageSize){ public ResultBean<PageBean<CrawlSingleTask>> listCrawlSingleTaskByPage(@RequestParam(value = "curr", defaultValue = "1") int page, @RequestParam(value = "limit", defaultValue = "10") int pageSize){
return ResultBean.ok(crawlService.listCrawlSingleTaskByPage(page,pageSize)); return ResultBean.ok(crawlService.listCrawlSingleTaskByPage(page,pageSize));
} }
@ -77,7 +74,7 @@ public class CrawlController {
* 删除采集任务 * 删除采集任务
* */ * */
@DeleteMapping("delCrawlSingleTask/{id}") @DeleteMapping("delCrawlSingleTask/{id}")
public ResultBean delCrawlSingleTask(@PathVariable("id") Long id){ public ResultBean<Void> delCrawlSingleTask(@PathVariable("id") Long id){
crawlService.delCrawlSingleTask(id); crawlService.delCrawlSingleTask(id);

View File

@ -1,18 +1,11 @@
package com.java2nb.novel.controller; package com.java2nb.novel.controller;
import com.java2nb.novel.entity.Book;
import com.java2nb.novel.entity.BookContent;
import com.java2nb.novel.entity.BookIndex;
import com.java2nb.novel.entity.News;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import java.util.List;
/** /**
* @author 11797 * @author 11797
*/ */

View File

@ -0,0 +1,25 @@
package com.java2nb.novel.core.crawl;
import com.java2nb.novel.entity.BookContent;
import com.java2nb.novel.entity.BookIndex;
import lombok.Data;
import java.util.List;
/**
* 章节数据封装bean
* @author Administrator
*/
@Data
public class ChapterBean {
/**
* 章节索引集合
* */
List<BookIndex> bookIndexList;
/**
* 章节内容集合
* */
List<BookContent> bookContentList;
}

View File

@ -0,0 +1,12 @@
package com.java2nb.novel.core.crawl;
import com.java2nb.novel.entity.Book;
/**
* 爬虫小说章节内容处理器
* */
public interface CrawlBookChapterHandler {
void handle(ChapterBean chapterBean);
}

View File

@ -0,0 +1,12 @@
package com.java2nb.novel.core.crawl;
import com.java2nb.novel.entity.Book;
/**
* 爬虫小说处理器
* */
public interface CrawlBookHandler {
void handle(Book book);
}

View File

@ -26,18 +26,14 @@ import static java.util.regex.Pattern.compile;
@Slf4j @Slf4j
public class CrawlParser { public class CrawlParser {
private static IdWorker idWorker = new IdWorker(); private static final IdWorker idWorker = new IdWorker();
public static final Integer BOOK_INDEX_LIST_KEY = 1; private static final RestTemplate restTemplate = RestTemplateUtil.getInstance("utf-8");
public static final Integer BOOK_CONTENT_LIST_KEY = 2; private static final ThreadLocal<Integer> retryCount = new ThreadLocal<>();
private static RestTemplate restTemplate = RestTemplateUtil.getInstance("utf-8");
private static ThreadLocal<Integer> retryCount = new ThreadLocal<>();
@SneakyThrows @SneakyThrows
public static Book parseBook(RuleBean ruleBean, String bookId) { public static void parseBook(RuleBean ruleBean, String bookId, CrawlBookHandler handler) {
Book book = new Book(); Book book = new Book();
String bookDetailUrl = ruleBean.getBookDetailUrl().replace("{bookId}", bookId); String bookDetailUrl = ruleBean.getBookDetailUrl().replace("{bookId}", bookId);
String bookDetailHtml = getByHttpClientWithChrome(bookDetailUrl); String bookDetailHtml = getByHttpClientWithChrome(bookDetailUrl);
@ -139,13 +135,10 @@ public class CrawlParser {
} }
} }
} }
return book; handler.handle(book);
} }
public static Map<Integer, List> parseBookIndexAndContent(String sourceBookId, Book book, RuleBean ruleBean, Map<Integer, BookIndex> hasIndexs) { public static void parseBookIndexAndContent(String sourceBookId, Book book, RuleBean ruleBean, Map<Integer, BookIndex> existBookIndexMap, CrawlBookChapterHandler handler) {
Map<Integer, List> result = new HashMap<>(2);
result.put(BOOK_INDEX_LIST_KEY, new ArrayList(0));
result.put(BOOK_CONTENT_LIST_KEY, new ArrayList(0));
Date currentDate = new Date(); Date currentDate = new Date();
@ -171,11 +164,11 @@ public class CrawlParser {
int indexNum = 0; int indexNum = 0;
//总字数 //总字数
Integer totalWordCount = book.getWordCount() == null ? 0 : book.getWordCount(); int totalWordCount = book.getWordCount() == null ? 0 : book.getWordCount();
while (isFindIndex) { while (isFindIndex) {
BookIndex hasIndex = hasIndexs.get(indexNum); BookIndex hasIndex = existBookIndexMap.get(indexNum);
String indexName = indexNameMatch.group(1); String indexName = indexNameMatch.group(1);
if (hasIndex == null || !StringUtils.deleteWhitespace(hasIndex.getIndexName()).equals(StringUtils.deleteWhitespace(indexName))) { if (hasIndex == null || !StringUtils.deleteWhitespace(hasIndex.getIndexName()).equals(StringUtils.deleteWhitespace(indexName))) {
@ -221,7 +214,7 @@ public class CrawlParser {
BookIndex bookIndex = new BookIndex(); BookIndex bookIndex = new BookIndex();
bookIndex.setIndexName(indexName); bookIndex.setIndexName(indexName);
bookIndex.setIndexNum(indexNum); bookIndex.setIndexNum(indexNum);
Integer wordCount = StringUtil.getStrValidWordCount(content); int wordCount = StringUtil.getStrValidWordCount(content);
bookIndex.setWordCount(wordCount); bookIndex.setWordCount(wordCount);
indexList.add(bookIndex); indexList.add(bookIndex);
@ -235,7 +228,7 @@ public class CrawlParser {
bookContent.setIndexId(hasIndex.getId()); bookContent.setIndexId(hasIndex.getId());
//计算总字数 //计算总字数
totalWordCount = (totalWordCount+wordCount-hasIndex.getWordCount()); totalWordCount = (totalWordCount + wordCount - hasIndex.getWordCount());
} else { } else {
//章节插入 //章节插入
//设置目录和章节内容 //设置目录和章节内容
@ -253,7 +246,6 @@ public class CrawlParser {
bookIndex.setUpdateTime(currentDate); bookIndex.setUpdateTime(currentDate);
} }
@ -266,7 +258,7 @@ public class CrawlParser {
if (indexList.size() > 0) { if (indexList.size() > 0) {
//如果有爬到最新章节,则设置小说主表的最新章节信息 //如果有爬到最新章节,则设置小说主表的最新章节信息
//获取爬取到的最新章节 //获取爬取到的最新章节
BookIndex lastIndex = indexList.get(indexList.size()-1); BookIndex lastIndex = indexList.get(indexList.size() - 1);
book.setLastIndexId(lastIndex.getId()); book.setLastIndexId(lastIndex.getId());
book.setLastIndexName(lastIndex.getIndexName()); book.setLastIndexName(lastIndex.getIndexName());
book.setLastIndexUpdateTime(currentDate); book.setLastIndexUpdateTime(currentDate);
@ -277,15 +269,22 @@ public class CrawlParser {
if (indexList.size() == contentList.size() && indexList.size() > 0) { if (indexList.size() == contentList.size() && indexList.size() > 0) {
result.put(BOOK_INDEX_LIST_KEY, indexList); handler.handle(new ChapterBean() {{
result.put(BOOK_CONTENT_LIST_KEY, contentList); setBookIndexList(indexList);
setBookContentList(contentList);
}});
return;
} }
} }
handler.handle(new ChapterBean() {{
setBookIndexList(new ArrayList<>(0));
setBookContentList(new ArrayList<>(0));
}});
return result;
} }
@ -294,6 +293,7 @@ public class CrawlParser {
ResponseEntity<String> forEntity = restTemplate.getForEntity(url, String.class); ResponseEntity<String> forEntity = restTemplate.getForEntity(url, String.class);
if (forEntity.getStatusCode() == HttpStatus.OK) { if (forEntity.getStatusCode() == HttpStatus.OK) {
String body = forEntity.getBody(); String body = forEntity.getBody();
assert body != null;
if (body.length() < Constants.INVALID_HTML_LENGTH) { if (body.length() < Constants.INVALID_HTML_LENGTH) {
return processErrorHttpResult(url); return processErrorHttpResult(url);
} }

View File

@ -35,7 +35,7 @@ public class RuleBean {
private String statusPatten; private String statusPatten;
private String scorePatten; private String scorePatten;
private String visitCountPatten; private String visitCountPatten;
private String descStart;; private String descStart;
private String descEnd; private String descEnd;
private String upadateTimePatten; private String upadateTimePatten;
private String upadateTimeFormatPatten; private String upadateTimeFormatPatten;

View File

@ -1,6 +1,7 @@
package com.java2nb.novel.core.listener; package com.java2nb.novel.core.listener;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import com.java2nb.novel.core.crawl.ChapterBean;
import com.java2nb.novel.core.crawl.CrawlParser; import com.java2nb.novel.core.crawl.CrawlParser;
import com.java2nb.novel.core.crawl.RuleBean; import com.java2nb.novel.core.crawl.RuleBean;
import com.java2nb.novel.entity.*; import com.java2nb.novel.entity.*;
@ -16,9 +17,9 @@ import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener; import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener; import javax.servlet.annotation.WebListener;
import java.util.Date; import java.util.Date;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.concurrent.TimeUnit;
/** /**
* @author Administrator * @author Administrator
@ -55,26 +56,28 @@ public class StarterListener implements ServletContextListener {
CrawlSource source = crawlService.queryCrawlSource(needUpdateBook.getCrawlSourceId()); CrawlSource source = crawlService.queryCrawlSource(needUpdateBook.getCrawlSourceId());
RuleBean ruleBean = new ObjectMapper().readValue(source.getCrawlRule(), RuleBean.class); RuleBean ruleBean = new ObjectMapper().readValue(source.getCrawlRule(), RuleBean.class);
//解析小说基本信息 //解析小说基本信息
Book book = CrawlParser.parseBook(ruleBean, needUpdateBook.getCrawlBookId()); CrawlParser.parseBook(ruleBean, needUpdateBook.getCrawlBookId(),book -> {
//这里只做老书更新 //这里只做老书更新
book.setId(needUpdateBook.getId()); book.setId(needUpdateBook.getId());
book.setWordCount(needUpdateBook.getWordCount()); book.setWordCount(needUpdateBook.getWordCount());
if (needUpdateBook.getPicUrl() != null && needUpdateBook.getPicUrl().contains(Constants.LOCAL_PIC_PREFIX)) { if (needUpdateBook.getPicUrl() != null && needUpdateBook.getPicUrl().contains(Constants.LOCAL_PIC_PREFIX)) {
//本地图片则不更新 //本地图片则不更新
book.setPicUrl(null); book.setPicUrl(null);
} }
//查询已存在的章节 //查询已存在的章节
Map<Integer, BookIndex> existBookIndexMap = bookService.queryExistBookIndexMap(needUpdateBook.getId()); Map<Integer, BookIndex> existBookIndexMap = bookService.queryExistBookIndexMap(needUpdateBook.getId());
//解析章节目录 //解析章节目录
Map<Integer, List> indexAndContentList = CrawlParser.parseBookIndexAndContent(needUpdateBook.getCrawlBookId(), book, ruleBean, existBookIndexMap); CrawlParser.parseBookIndexAndContent(needUpdateBook.getCrawlBookId(), book, ruleBean, existBookIndexMap,chapter -> {
bookService.updateBookAndIndexAndContent(book, (List<BookIndex>) indexAndContentList.get(CrawlParser.BOOK_INDEX_LIST_KEY), (List<BookContent>) indexAndContentList.get(CrawlParser.BOOK_CONTENT_LIST_KEY), existBookIndexMap); bookService.updateBookAndIndexAndContent(book, chapter.getBookIndexList(), chapter.getBookContentList(), existBookIndexMap);
});
});
} catch (Exception e) { } catch (Exception e) {
log.error(e.getMessage(), e); log.error(e.getMessage(), e);
} }
} }
// 休眠10分钟
Thread.sleep(1000 * 60 * 10); TimeUnit.MINUTES.sleep(10);
} catch (Exception e) { } catch (Exception e) {
log.error(e.getMessage(), e); log.error(e.getMessage(), e);
} }
@ -107,7 +110,8 @@ public class StarterListener implements ServletContextListener {
} }
Thread.sleep(1000 * 60); //休眠1分钟
TimeUnit.MINUTES.sleep(1);
} catch (Exception e) { } catch (Exception e) {
log.error(e.getMessage(), e); log.error(e.getMessage(), e);

View File

@ -8,12 +8,10 @@ import com.java2nb.novel.entity.CrawlSource;
import com.java2nb.novel.service.CrawlService; import com.java2nb.novel.service.CrawlService;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled; import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Set; import java.util.Set;
/** /**

View File

@ -0,0 +1,16 @@
package com.java2nb.novel.service;
import com.java2nb.novel.entity.BookContent;
import java.util.List;
public interface BookContentService {
void saveBookContent(List<BookContent> bookContentList,Long bookId);
void saveBookContent(BookContent bookContent,Long bookId);
void updateBookContent(BookContent bookContent,Long bookId);
}

View File

@ -72,6 +72,7 @@ public interface BookService {
* 更新一下最后一次的抓取时间 * 更新一下最后一次的抓取时间
* @param bookId 小说ID * @param bookId 小说ID
* */ * */
@Deprecated
void updateCrawlLastTime(Long bookId); void updateCrawlLastTime(Long bookId);
/** /**

View File

@ -1,11 +1,9 @@
package com.java2nb.novel.service; package com.java2nb.novel.service;
import com.github.pagehelper.PageInfo;
import com.java2nb.novel.core.bean.PageBean; import com.java2nb.novel.core.bean.PageBean;
import com.java2nb.novel.core.crawl.RuleBean; import com.java2nb.novel.core.crawl.RuleBean;
import com.java2nb.novel.entity.CrawlSingleTask; import com.java2nb.novel.entity.CrawlSingleTask;
import com.java2nb.novel.entity.CrawlSource; import com.java2nb.novel.entity.CrawlSource;
import com.java2nb.novel.vo.CrawlSourceVO;
import java.util.List; import java.util.List;
@ -64,7 +62,7 @@ public interface CrawlService {
* 根据分类ID和规则解析分类列表 * 根据分类ID和规则解析分类列表
* @param catId 分类ID * @param catId 分类ID
* @param ruleBean 规则对象 * @param ruleBean 规则对象
* @param sourceId * @param sourceId 爬虫源ID
*/ */
void parseBookList(int catId, RuleBean ruleBean, Integer sourceId); void parseBookList(int catId, RuleBean ruleBean, Integer sourceId);

View File

@ -4,6 +4,7 @@ import com.java2nb.novel.entity.Book;
import com.java2nb.novel.entity.BookContent; import com.java2nb.novel.entity.BookContent;
import com.java2nb.novel.entity.BookIndex; import com.java2nb.novel.entity.BookIndex;
import com.java2nb.novel.mapper.*; import com.java2nb.novel.mapper.*;
import com.java2nb.novel.service.BookContentService;
import com.java2nb.novel.service.BookService; import com.java2nb.novel.service.BookService;
import com.java2nb.novel.utils.Constants; import com.java2nb.novel.utils.Constants;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
@ -37,7 +38,7 @@ public class BookServiceImpl implements BookService {
private final CrawlBookIndexMapper bookIndexMapper; private final CrawlBookIndexMapper bookIndexMapper;
private final BookContentMapper bookContentMapper; private final BookContentService bookContentService;
@Override @Override
@ -46,7 +47,7 @@ public class BookServiceImpl implements BookService {
return bookMapper.count(countFrom(BookDynamicSqlSupport.book).where(BookDynamicSqlSupport.bookName, isEqualTo(bookName)) return bookMapper.count(countFrom(BookDynamicSqlSupport.book).where(BookDynamicSqlSupport.bookName, isEqualTo(bookName))
.and(BookDynamicSqlSupport.authorName, isEqualTo(authorName)) .and(BookDynamicSqlSupport.authorName, isEqualTo(authorName))
.build() .build()
.render(RenderingStrategies.MYBATIS3))>0; .render(RenderingStrategies.MYBATIS3)) > 0;
} }
@ -57,7 +58,7 @@ public class BookServiceImpl implements BookService {
.equalTo(sourceId) .equalTo(sourceId)
.set(crawlBookId) .set(crawlBookId)
.equalTo(bookId) .equalTo(bookId)
.where(BookDynamicSqlSupport.id,isEqualTo(id)) .where(BookDynamicSqlSupport.id, isEqualTo(id))
.build() .build()
.render(RenderingStrategies.MYBATIS3)); .render(RenderingStrategies.MYBATIS3));
} }
@ -74,9 +75,9 @@ public class BookServiceImpl implements BookService {
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
@Override @Override
public void saveBookAndIndexAndContent(Book book, List<BookIndex> bookIndexList, List<BookContent> bookContentList) { public void saveBookAndIndexAndContent(Book book, List<BookIndex> bookIndexList, List<BookContent> bookContentList) {
if(!queryIsExistByBookNameAndAuthorName(book.getBookName(),book.getAuthorName())) { if (!queryIsExistByBookNameAndAuthorName(book.getBookName(), book.getAuthorName())) {
if(bookIndexList.size()>0) { if (bookIndexList.size() > 0) {
//保存小说主表 //保存小说主表
@ -85,7 +86,7 @@ public class BookServiceImpl implements BookService {
//批量保存目录和内容 //批量保存目录和内容
bookIndexMapper.insertMultiple(bookIndexList); bookIndexMapper.insertMultiple(bookIndexList);
bookContentMapper.insertMultiple(bookContentList); bookContentService.saveBookContent(bookContentList,book.getId());
} }
} }
@ -96,7 +97,7 @@ public class BookServiceImpl implements BookService {
@Override @Override
public List<Book> queryNeedUpdateBook(Date startDate, int limit) { public List<Book> queryNeedUpdateBook(Date startDate, int limit) {
List<Book> books = bookMapper.queryNeedUpdateBook(startDate, limit); List<Book> books = bookMapper.queryNeedUpdateBook(startDate, limit);
if(books.size()>0) { if (books.size() > 0) {
//更新最后抓取时间为当前时间 //更新最后抓取时间为当前时间
bookMapper.updateCrawlLastTime(books, new Date()); bookMapper.updateCrawlLastTime(books, new Date());
} }
@ -105,38 +106,33 @@ public class BookServiceImpl implements BookService {
@Override @Override
public Map<Integer, BookIndex> queryExistBookIndexMap(Long bookId) { public Map<Integer, BookIndex> queryExistBookIndexMap(Long bookId) {
List<BookIndex> bookIndexs = bookIndexMapper.selectMany(select(BookIndexDynamicSqlSupport.id,BookIndexDynamicSqlSupport.indexNum,BookIndexDynamicSqlSupport.indexName,BookIndexDynamicSqlSupport.wordCount) List<BookIndex> bookIndexs = bookIndexMapper.selectMany(select(BookIndexDynamicSqlSupport.id, BookIndexDynamicSqlSupport.indexNum, BookIndexDynamicSqlSupport.indexName, BookIndexDynamicSqlSupport.wordCount)
.from(BookIndexDynamicSqlSupport.bookIndex) .from(BookIndexDynamicSqlSupport.bookIndex)
.where(BookIndexDynamicSqlSupport.bookId,isEqualTo(bookId)) .where(BookIndexDynamicSqlSupport.bookId, isEqualTo(bookId))
.build() .build()
.render(RenderingStrategies.MYBATIS3)); .render(RenderingStrategies.MYBATIS3));
if (bookIndexs.size() > 0) { if (bookIndexs.size() > 0) {
return bookIndexs.stream().collect(Collectors.toMap(BookIndex::getIndexNum, Function.identity())); return bookIndexs.stream().collect(Collectors.toMap(BookIndex::getIndexNum, Function.identity()));
} }
return new HashMap<>(0); return new HashMap<>(0);
} }
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
@Override @Override
public void updateBookAndIndexAndContent(Book book, List<BookIndex> bookIndexList, List<BookContent> bookContentList, Map<Integer, BookIndex> existBookIndexMap) { public void updateBookAndIndexAndContent(Book book, List<BookIndex> bookIndexList, List<BookContent> bookContentList, Map<Integer, BookIndex> existBookIndexMap) {
for (int i = 0; i < bookIndexList.size(); i++) { for (int i = 0; i < bookIndexList.size(); i++) {
BookIndex bookIndex = bookIndexList.get(i); BookIndex bookIndex = bookIndexList.get(i);
BookContent bookContent = bookContentList.get(i); BookContent bookContent = bookContentList.get(i);
if(!existBookIndexMap.containsKey(bookIndex.getIndexNum())) { if (!existBookIndexMap.containsKey(bookIndex.getIndexNum())) {
//插入 //插入
bookIndexMapper.insertSelective(bookIndex); bookIndexMapper.insertSelective(bookIndex);
bookContentMapper.insertSelective(bookContent); bookContentService.saveBookContent(bookContent,book.getId());
}else{ } else {
//更新 //更新
bookIndexMapper.updateByPrimaryKeySelective(bookIndex); bookIndexMapper.updateByPrimaryKeySelective(bookIndex);
bookContentMapper.update(update(BookContentDynamicSqlSupport.bookContent) bookContentService.updateBookContent(bookContent,book.getId());
.set(BookContentDynamicSqlSupport.content)
.equalTo(bookContent.getContent())
.where(BookContentDynamicSqlSupport.indexId,isEqualTo(bookContent.getIndexId()))
.build()
.render(RenderingStrategies.MYBATIS3));
} }
@ -145,7 +141,7 @@ public class BookServiceImpl implements BookService {
//更新小说主表 //更新小说主表
book.setBookName(null); book.setBookName(null);
book.setAuthorName(null); book.setAuthorName(null);
if(Constants.VISIT_COUNT_DEFAULT.equals(book.getVisitCount())) { if (Constants.VISIT_COUNT_DEFAULT.equals(book.getVisitCount())) {
book.setVisitCount(null); book.setVisitCount(null);
} }
bookMapper.updateByPrimaryKeySelective(book); bookMapper.updateByPrimaryKeySelective(book);
@ -168,7 +164,7 @@ public class BookServiceImpl implements BookService {
.build() .build()
.render(RenderingStrategies.MYBATIS3)); .render(RenderingStrategies.MYBATIS3));
if(books.size()>0){ if (books.size() > 0) {
return books.get(0); return books.get(0);
} }
@ -176,19 +172,4 @@ public class BookServiceImpl implements BookService {
} }
/**
* 查询最后的章节
* */
private BookIndex queryLastIndex(Long bookId) {
return bookIndexMapper.queryLastIndex(bookId);
}
/**
* 查询小说总字数
* */
private Integer queryTotalWordCount(Long bookId) {
return bookMapper.queryTotalWordCount(bookId);
}
} }

View File

@ -1,9 +1,7 @@
package com.java2nb.novel.service.impl; package com.java2nb.novel.service.impl;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper; import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.java2nb.novel.core.bean.PageBean; import com.java2nb.novel.core.bean.PageBean;
import com.java2nb.novel.core.cache.CacheKey; import com.java2nb.novel.core.cache.CacheKey;
import com.java2nb.novel.core.cache.CacheService; import com.java2nb.novel.core.cache.CacheService;
@ -15,9 +13,13 @@ import com.java2nb.novel.core.utils.BeanUtil;
import com.java2nb.novel.core.utils.IdWorker; import com.java2nb.novel.core.utils.IdWorker;
import com.java2nb.novel.core.utils.SpringUtil; import com.java2nb.novel.core.utils.SpringUtil;
import com.java2nb.novel.core.utils.ThreadUtil; import com.java2nb.novel.core.utils.ThreadUtil;
import com.java2nb.novel.entity.*; import com.java2nb.novel.entity.Book;
import com.java2nb.novel.entity.CrawlSingleTask;
import com.java2nb.novel.entity.CrawlSource; import com.java2nb.novel.entity.CrawlSource;
import com.java2nb.novel.mapper.*; import com.java2nb.novel.mapper.CrawlSingleTaskDynamicSqlSupport;
import com.java2nb.novel.mapper.CrawlSingleTaskMapper;
import com.java2nb.novel.mapper.CrawlSourceDynamicSqlSupport;
import com.java2nb.novel.mapper.CrawlSourceMapper;
import com.java2nb.novel.service.BookService; import com.java2nb.novel.service.BookService;
import com.java2nb.novel.service.CrawlService; import com.java2nb.novel.service.CrawlService;
import com.java2nb.novel.vo.CrawlSingleTaskVO; import com.java2nb.novel.vo.CrawlSingleTaskVO;
@ -29,18 +31,15 @@ import org.apache.commons.lang3.StringUtils;
import org.mybatis.dynamic.sql.render.RenderingStrategies; import org.mybatis.dynamic.sql.render.RenderingStrategies;
import org.mybatis.dynamic.sql.select.render.SelectStatementProvider; import org.mybatis.dynamic.sql.select.render.SelectStatementProvider;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.*; import java.util.*;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import static com.java2nb.novel.core.utils.HttpUtil.getByHttpClient;
import static com.java2nb.novel.core.utils.HttpUtil.getByHttpClientWithChrome; import static com.java2nb.novel.core.utils.HttpUtil.getByHttpClientWithChrome;
import static com.java2nb.novel.mapper.BookDynamicSqlSupport.crawlBookId;
import static com.java2nb.novel.mapper.BookDynamicSqlSupport.crawlSourceId;
import static com.java2nb.novel.mapper.CrawlSourceDynamicSqlSupport.*; import static com.java2nb.novel.mapper.CrawlSourceDynamicSqlSupport.*;
import static org.mybatis.dynamic.sql.SqlBuilder.*; import static org.mybatis.dynamic.sql.SqlBuilder.isEqualTo;
import static org.mybatis.dynamic.sql.select.SelectDSL.select; import static org.mybatis.dynamic.sql.select.SelectDSL.select;
/** /**
@ -121,11 +120,7 @@ public class CrawlServiceImpl implements CrawlService {
//按分类开始爬虫解析任务 //按分类开始爬虫解析任务
for (int i = 1; i < 8; i++) { for (int i = 1; i < 8; i++) {
final int catId = i; final int catId = i;
Thread thread = new Thread(() -> { Thread thread = new Thread(() -> CrawlServiceImpl.this.parseBookList(catId, ruleBean, sourceId));
parseBookList(catId, ruleBean, sourceId);
});
thread.start(); thread.start();
//thread加入到监控缓存中 //thread加入到监控缓存中
threadIds.add(thread.getId()); threadIds.add(thread.getId());
@ -279,39 +274,46 @@ public class CrawlServiceImpl implements CrawlService {
@Override @Override
public boolean parseBookAndSave(int catId, RuleBean ruleBean, Integer sourceId, String bookId) { public boolean parseBookAndSave(int catId, RuleBean ruleBean, Integer sourceId, String bookId) {
Book book = CrawlParser.parseBook(ruleBean, bookId);
if(book.getBookName() == null || book.getAuthorName() == null){ final AtomicBoolean parseResult = new AtomicBoolean(false);
return false;
} CrawlParser.parseBook(ruleBean, bookId, book -> {
//这里只做新书入库,查询是否存在这本书 if(book.getBookName() == null || book.getAuthorName() == null){
Book existBook = bookService.queryBookByBookNameAndAuthorName(book.getBookName(), book.getAuthorName()); return;
//如果该小说不存在则可以解析入库但是标记该小说正在入库30分钟之后才允许再次入库
if (existBook == null) {
//没有该书,可以入库
book.setCatId(catId);
//根据分类ID查询分类
book.setCatName(bookService.queryCatNameByCatId(catId));
if (catId == 7) {
//女频
book.setWorkDirection((byte) 1);
} else {
//男频
book.setWorkDirection((byte) 0);
} }
book.setCrawlBookId(bookId); //这里只做新书入库,查询是否存在这本书
book.setCrawlSourceId(sourceId); Book existBook = bookService.queryBookByBookNameAndAuthorName(book.getBookName(), book.getAuthorName());
book.setCrawlLastTime(new Date()); //如果该小说不存在则可以解析入库但是标记该小说正在入库30分钟之后才允许再次入库
book.setId(new IdWorker().nextId()); if (existBook == null) {
//解析章节目录 //没有该书,可以入库
Map<Integer, List> indexAndContentList = CrawlParser.parseBookIndexAndContent(bookId, book, ruleBean, new HashMap<>(0)); book.setCatId(catId);
//根据分类ID查询分类
book.setCatName(bookService.queryCatNameByCatId(catId));
if (catId == 7) {
//女频
book.setWorkDirection((byte) 1);
} else {
//男频
book.setWorkDirection((byte) 0);
}
book.setCrawlBookId(bookId);
book.setCrawlSourceId(sourceId);
book.setCrawlLastTime(new Date());
book.setId(new IdWorker().nextId());
//解析章节目录
CrawlParser.parseBookIndexAndContent(bookId, book, ruleBean, new HashMap<>(0),chapter -> {
bookService.saveBookAndIndexAndContent(book, chapter.getBookIndexList(), chapter.getBookContentList());
});
bookService.saveBookAndIndexAndContent(book, (List<BookIndex>) indexAndContentList.get(CrawlParser.BOOK_INDEX_LIST_KEY), (List<BookContent>) indexAndContentList.get(CrawlParser.BOOK_CONTENT_LIST_KEY)); } else {
//只更新书籍的爬虫相关字段
bookService.updateCrawlProperties(existBook.getId(), sourceId, bookId);
}
parseResult.set(true);
});
return parseResult.get();
} else {
//只更新书籍的爬虫相关字段
bookService.updateCrawlProperties(existBook.getId(), sourceId, bookId);
}
return true;
} }
@Override @Override

View File

@ -0,0 +1,44 @@
package com.java2nb.novel.service.impl;
import com.java2nb.novel.entity.BookContent;
import com.java2nb.novel.mapper.BookContentDynamicSqlSupport;
import com.java2nb.novel.mapper.BookContentMapper;
import com.java2nb.novel.service.BookContentService;
import lombok.RequiredArgsConstructor;
import org.mybatis.dynamic.sql.render.RenderingStrategies;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Service;
import java.util.List;
import static org.mybatis.dynamic.sql.SqlBuilder.isEqualTo;
import static org.mybatis.dynamic.sql.SqlBuilder.update;
@Service
@RequiredArgsConstructor
@ConditionalOnProperty(prefix = "txt.save", name = "storage", havingValue = "db")
public class DbBookContentServiceImpl implements BookContentService {
private final BookContentMapper bookContentMapper;
@Override
public void saveBookContent(List<BookContent> bookContentList,Long bookId) {
bookContentMapper.insertMultiple(bookContentList);
}
@Override
public void saveBookContent(BookContent bookContent,Long bookId) {
bookContentMapper.insertSelective(bookContent);
}
@Override
public void updateBookContent(BookContent bookContent,Long bookId) {
bookContentMapper.update(update(BookContentDynamicSqlSupport.bookContent)
.set(BookContentDynamicSqlSupport.content)
.equalTo(bookContent.getContent())
.where(BookContentDynamicSqlSupport.indexId,isEqualTo(bookContent.getIndexId()))
.build()
.render(RenderingStrategies.MYBATIS3));
}
}

View File

@ -0,0 +1,36 @@
package com.java2nb.novel.service.impl;
import com.java2nb.novel.core.utils.FileUtil;
import com.java2nb.novel.entity.BookContent;
import com.java2nb.novel.service.BookContentService;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
@RequiredArgsConstructor
@ConditionalOnProperty(prefix = "txt.save", name = "storage", havingValue = "file")
public class FileBookContentServiceImpl implements BookContentService {
@Value("${txt.save.path}")
private String fileSavePath;
@Override
public void saveBookContent(List<BookContent> bookContentList,Long bookId) {
bookContentList.forEach(bookContent -> saveBookContent(bookContent,bookId));
}
@Override
public void saveBookContent(BookContent bookContent,Long bookId) {
FileUtil.writeContentToFile(fileSavePath,"/"+bookId+"/"+bookContent.getIndexId()+".txt",bookContent.getContent());
}
@Override
public void updateBookContent(BookContent bookContent,Long bookId) {
FileUtil.writeContentToFile(fileSavePath,"/"+bookId+"/"+bookContent.getIndexId()+".txt",bookContent.getContent());
}
}

View File

@ -2,14 +2,15 @@ package com.java2nb.novel.vo;
import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.annotation.JsonFormat;
import com.java2nb.novel.entity.CrawlSingleTask; import com.java2nb.novel.entity.CrawlSingleTask;
import com.java2nb.novel.entity.CrawlSource;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode;
import java.util.Date; import java.util.Date;
/** /**
* @author Administrator * @author Administrator
*/ */
@EqualsAndHashCode(callSuper = true)
@Data @Data
public class CrawlSingleTaskVO extends CrawlSingleTask { public class CrawlSingleTaskVO extends CrawlSingleTask {

View File

@ -3,13 +3,14 @@ package com.java2nb.novel.vo;
import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.annotation.JsonFormat;
import com.java2nb.novel.entity.CrawlSource; import com.java2nb.novel.entity.CrawlSource;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode;
import javax.annotation.Generated;
import java.util.Date; import java.util.Date;
/** /**
* @author Administrator * @author Administrator
*/ */
@EqualsAndHashCode(callSuper = true)
@Data @Data
public class CrawlSourceVO extends CrawlSource{ public class CrawlSourceVO extends CrawlSource{

View File

@ -5,7 +5,7 @@
<parent> <parent>
<artifactId>novel</artifactId> <artifactId>novel</artifactId>
<groupId>com.java2nb</groupId> <groupId>com.java2nb</groupId>
<version>3.5.2</version> <version>3.6.0</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

View File

@ -1,22 +1,21 @@
package com.java2nb.novel.controller; package com.java2nb.novel.controller;
import com.github.pagehelper.PageInfo; import com.java2nb.novel.core.bean.PageBean;
import com.java2nb.novel.core.bean.ResultBean; import com.java2nb.novel.core.bean.ResultBean;
import com.java2nb.novel.core.bean.UserDetails; import com.java2nb.novel.core.bean.UserDetails;
import com.java2nb.novel.core.enums.ResponseStatus; import com.java2nb.novel.core.enums.ResponseStatus;
import com.java2nb.novel.core.exception.BusinessException; import com.java2nb.novel.core.exception.BusinessException;
import com.java2nb.novel.core.utils.BeanUtil;
import com.java2nb.novel.entity.Author; import com.java2nb.novel.entity.Author;
import com.java2nb.novel.entity.AuthorIncome;
import com.java2nb.novel.entity.AuthorIncomeDetail;
import com.java2nb.novel.entity.Book; import com.java2nb.novel.entity.Book;
import com.java2nb.novel.service.AuthorService; import com.java2nb.novel.service.AuthorService;
import com.java2nb.novel.service.BookService; import com.java2nb.novel.service.BookService;
import com.java2nb.novel.service.FriendLinkService;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Date; import java.util.Date;
/** /**
@ -36,7 +35,7 @@ public class AuthorController extends BaseController{
* 校验笔名是否存在 * 校验笔名是否存在
* */ * */
@GetMapping("checkPenName") @GetMapping("checkPenName")
public ResultBean checkPenName(String penName){ public ResultBean<Boolean> checkPenName(String penName){
return ResultBean.ok(authorService.checkPenName(penName)); return ResultBean.ok(authorService.checkPenName(penName));
} }
@ -45,7 +44,7 @@ public class AuthorController extends BaseController{
* 作家发布小说分页列表查询 * 作家发布小说分页列表查询
* */ * */
@GetMapping("listBookByPage") @GetMapping("listBookByPage")
public ResultBean listBookByPage(@RequestParam(value = "curr", defaultValue = "1") int page, @RequestParam(value = "limit", defaultValue = "10") int pageSize ,HttpServletRequest request){ public ResultBean<PageBean<Book>> listBookByPage(@RequestParam(value = "curr", defaultValue = "1") int page, @RequestParam(value = "limit", defaultValue = "10") int pageSize , HttpServletRequest request){
return ResultBean.ok(bookService.listBookPageByUserId(getUserDetails(request).getId(),page,pageSize)); return ResultBean.ok(bookService.listBookPageByUserId(getUserDetails(request).getId(),page,pageSize));
} }
@ -54,7 +53,7 @@ public class AuthorController extends BaseController{
* 发布小说 * 发布小说
* */ * */
@PostMapping("addBook") @PostMapping("addBook")
public ResultBean addBook(@RequestParam("bookDesc") String bookDesc,Book book,HttpServletRequest request){ public ResultBean<Void> addBook(@RequestParam("bookDesc") String bookDesc,Book book,HttpServletRequest request){
Author author = checkAuthor(request); Author author = checkAuthor(request);
@ -72,7 +71,7 @@ public class AuthorController extends BaseController{
* 更新小说状态,上架或下架 * 更新小说状态,上架或下架
* */ * */
@PostMapping("updateBookStatus") @PostMapping("updateBookStatus")
public ResultBean updateBookStatus(Long bookId,Byte status,HttpServletRequest request){ public ResultBean<Void> updateBookStatus(Long bookId,Byte status,HttpServletRequest request){
Author author = checkAuthor(request); Author author = checkAuthor(request);
//更新小说状态,上架或下架 //更新小说状态,上架或下架
@ -87,7 +86,7 @@ public class AuthorController extends BaseController{
* 删除章节 * 删除章节
*/ */
@DeleteMapping("deleteIndex/{indexId}") @DeleteMapping("deleteIndex/{indexId}")
public ResultBean deleteIndex(@PathVariable("indexId") Long indexId, HttpServletRequest request) { public ResultBean<Void> deleteIndex(@PathVariable("indexId") Long indexId, HttpServletRequest request) {
Author author = checkAuthor(request); Author author = checkAuthor(request);
@ -101,7 +100,7 @@ public class AuthorController extends BaseController{
* 更新章节名 * 更新章节名
*/ */
@PostMapping("updateIndexName") @PostMapping("updateIndexName")
public ResultBean updateIndexName(Long indexId, String indexName, HttpServletRequest request) { public ResultBean<Void> updateIndexName(Long indexId, String indexName, HttpServletRequest request) {
Author author = checkAuthor(request); Author author = checkAuthor(request);
@ -118,7 +117,7 @@ public class AuthorController extends BaseController{
* 发布章节内容 * 发布章节内容
*/ */
@PostMapping("addBookContent") @PostMapping("addBookContent")
public ResultBean addBookContent(Long bookId, String indexName, String content,Byte isVip, HttpServletRequest request) { public ResultBean<Void> addBookContent(Long bookId, String indexName, String content,Byte isVip, HttpServletRequest request) {
Author author = checkAuthor(request); Author author = checkAuthor(request);
content = content.replaceAll("\\n", "<br>") content = content.replaceAll("\\n", "<br>")
@ -133,7 +132,7 @@ public class AuthorController extends BaseController{
* 查询章节内容 * 查询章节内容
*/ */
@GetMapping("queryIndexContent/{indexId}") @GetMapping("queryIndexContent/{indexId}")
public ResultBean queryIndexContent(@PathVariable("indexId") Long indexId, HttpServletRequest request) { public ResultBean<String> queryIndexContent(@PathVariable("indexId") Long indexId, HttpServletRequest request) {
Author author = checkAuthor(request); Author author = checkAuthor(request);
@ -149,7 +148,7 @@ public class AuthorController extends BaseController{
* 更新章节内容 * 更新章节内容
*/ */
@PostMapping("updateBookContent") @PostMapping("updateBookContent")
public ResultBean updateBookContent(Long indexId, String indexName, String content, HttpServletRequest request) { public ResultBean<Void> updateBookContent(Long indexId, String indexName, String content, HttpServletRequest request) {
Author author = checkAuthor(request); Author author = checkAuthor(request);
content = content.replaceAll("\\n", "<br>") content = content.replaceAll("\\n", "<br>")
@ -164,7 +163,7 @@ public class AuthorController extends BaseController{
* 修改小说封面 * 修改小说封面
*/ */
@PostMapping("updateBookPic") @PostMapping("updateBookPic")
public ResultBean updateBookPic(@RequestParam("bookId") Long bookId,@RequestParam("bookPic") String bookPic,HttpServletRequest request) { public ResultBean<Void> updateBookPic(@RequestParam("bookId") Long bookId,@RequestParam("bookPic") String bookPic,HttpServletRequest request) {
Author author = checkAuthor(request); Author author = checkAuthor(request);
bookService.updateBookPic(bookId,bookPic, author.getId()); bookService.updateBookPic(bookId,bookPic, author.getId());
return ResultBean.ok(); return ResultBean.ok();
@ -175,12 +174,12 @@ public class AuthorController extends BaseController{
* 作家日收入统计数据分页列表查询 * 作家日收入统计数据分页列表查询
* */ * */
@GetMapping("listIncomeDailyByPage") @GetMapping("listIncomeDailyByPage")
public ResultBean listIncomeDailyByPage(@RequestParam(value = "curr", defaultValue = "1") int page, public ResultBean<PageBean<AuthorIncomeDetail>> listIncomeDailyByPage(@RequestParam(value = "curr", defaultValue = "1") int page,
@RequestParam(value = "limit", defaultValue = "10") int pageSize , @RequestParam(value = "limit", defaultValue = "10") int pageSize ,
@RequestParam(value = "bookId", defaultValue = "0") Long bookId, @RequestParam(value = "bookId", defaultValue = "0") Long bookId,
@RequestParam(value = "startTime",defaultValue = "2020-05-01") Date startTime, @RequestParam(value = "startTime",defaultValue = "2020-05-01") Date startTime,
@RequestParam(value = "endTime",defaultValue = "2030-01-01") Date endTime, @RequestParam(value = "endTime",defaultValue = "2030-01-01") Date endTime,
HttpServletRequest request){ HttpServletRequest request){
return ResultBean.ok(authorService.listIncomeDailyByPage(page,pageSize,getUserDetails(request).getId(),bookId,startTime,endTime)); return ResultBean.ok(authorService.listIncomeDailyByPage(page,pageSize,getUserDetails(request).getId(),bookId,startTime,endTime));
} }
@ -190,10 +189,10 @@ public class AuthorController extends BaseController{
* 作家月收入统计数据分页列表查询 * 作家月收入统计数据分页列表查询
* */ * */
@GetMapping("listIncomeMonthByPage") @GetMapping("listIncomeMonthByPage")
public ResultBean listIncomeMonthByPage(@RequestParam(value = "curr", defaultValue = "1") int page, public ResultBean<PageBean<AuthorIncome>> listIncomeMonthByPage(@RequestParam(value = "curr", defaultValue = "1") int page,
@RequestParam(value = "limit", defaultValue = "10") int pageSize , @RequestParam(value = "limit", defaultValue = "10") int pageSize ,
@RequestParam(value = "bookId", defaultValue = "0") Long bookId, @RequestParam(value = "bookId", defaultValue = "0") Long bookId,
HttpServletRequest request){ HttpServletRequest request){
return ResultBean.ok(authorService.listIncomeMonthByPage(page,pageSize,getUserDetails(request).getId(),bookId)); return ResultBean.ok(authorService.listIncomeMonthByPage(page,pageSize,getUserDetails(request).getId(),bookId));
} }

View File

@ -6,7 +6,12 @@ import com.java2nb.novel.core.bean.ResultBean;
import com.java2nb.novel.core.bean.UserDetails; import com.java2nb.novel.core.bean.UserDetails;
import com.java2nb.novel.core.enums.ResponseStatus; import com.java2nb.novel.core.enums.ResponseStatus;
import com.java2nb.novel.entity.Book; import com.java2nb.novel.entity.Book;
import com.java2nb.novel.entity.BookCategory;
import com.java2nb.novel.entity.BookComment; import com.java2nb.novel.entity.BookComment;
import com.java2nb.novel.entity.BookIndex;
import com.java2nb.novel.service.BookContentService;
import com.java2nb.novel.vo.BookCommentVO;
import com.java2nb.novel.vo.BookSettingVO;
import com.java2nb.novel.vo.BookSpVO; import com.java2nb.novel.vo.BookSpVO;
import com.java2nb.novel.service.BookService; import com.java2nb.novel.service.BookService;
import com.java2nb.novel.vo.BookVO; import com.java2nb.novel.vo.BookVO;
@ -18,6 +23,7 @@ import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import java.util.HashMap; import java.util.HashMap;
import java.util.List;
import java.util.Map; import java.util.Map;
/** /**
@ -27,10 +33,12 @@ import java.util.Map;
@RestController @RestController
@Slf4j @Slf4j
@RequiredArgsConstructor @RequiredArgsConstructor
public class BookController extends BaseController{ public class BookController extends BaseController {
private final BookService bookService; private final BookService bookService;
private final BookContentService bookContentService;
private final RabbitTemplate rabbitTemplate; private final RabbitTemplate rabbitTemplate;
@Value("${spring.rabbitmq.enable}") @Value("${spring.rabbitmq.enable}")
@ -39,77 +47,77 @@ public class BookController extends BaseController{
/** /**
* 查询首页小说设置列表数据 * 查询首页小说设置列表数据
* */ */
@GetMapping("listBookSetting") @GetMapping("listBookSetting")
public ResultBean listBookSetting(){ public ResultBean<Map<Byte, List<BookSettingVO>>> listBookSetting() {
return ResultBean.ok(bookService.listBookSettingVO()); return ResultBean.ok(bookService.listBookSettingVO());
} }
/** /**
* 查询首页点击榜单数据 * 查询首页点击榜单数据
* */ */
@GetMapping("listClickRank") @GetMapping("listClickRank")
public ResultBean listClickRank(){ public ResultBean<List<Book>> listClickRank() {
return ResultBean.ok(bookService.listClickRank()); return ResultBean.ok(bookService.listClickRank());
} }
/** /**
* 查询首页新书榜单数据 * 查询首页新书榜单数据
* */ */
@GetMapping("listNewRank") @GetMapping("listNewRank")
public ResultBean listNewRank(){ public ResultBean<List<Book>> listNewRank() {
return ResultBean.ok(bookService.listNewRank()); return ResultBean.ok(bookService.listNewRank());
} }
/** /**
* 查询首页更新榜单数据 * 查询首页更新榜单数据
* */ */
@GetMapping("listUpdateRank") @GetMapping("listUpdateRank")
public ResultBean listUpdateRank(){ public ResultBean<List<BookVO>> listUpdateRank() {
return ResultBean.ok(bookService.listUpdateRank()); return ResultBean.ok(bookService.listUpdateRank());
} }
/** /**
* 查询小说分类列表 * 查询小说分类列表
* */ */
@GetMapping("listBookCategory") @GetMapping("listBookCategory")
public ResultBean listBookCategory(){ public ResultBean<List<BookCategory>> listBookCategory() {
return ResultBean.ok(bookService.listBookCategory()); return ResultBean.ok(bookService.listBookCategory());
} }
/** /**
* 分页搜索 * 分页搜索
* */ */
@GetMapping("searchByPage") @GetMapping("searchByPage")
public ResultBean searchByPage(BookSpVO bookSP, @RequestParam(value = "curr", defaultValue = "1") int page, @RequestParam(value = "limit", defaultValue = "20") int pageSize){ public ResultBean<?> searchByPage(BookSpVO bookSP, @RequestParam(value = "curr", defaultValue = "1") int page, @RequestParam(value = "limit", defaultValue = "20") int pageSize) {
return ResultBean.ok(bookService.searchByPage(bookSP,page,pageSize)); return ResultBean.ok(bookService.searchByPage(bookSP, page, pageSize));
} }
/** /**
* 查询小说详情信息 * 查询小说详情信息
* */ */
@GetMapping("queryBookDetail/{id}") @GetMapping("queryBookDetail/{id}")
public ResultBean queryBookDetail(@PathVariable("id") Long id){ public ResultBean<Book> queryBookDetail(@PathVariable("id") Long id) {
return ResultBean.ok(bookService.queryBookDetail(id)); return ResultBean.ok(bookService.queryBookDetail(id));
} }
/** /**
* 查询小说排行信息 * 查询小说排行信息
* */ */
@GetMapping("listRank") @GetMapping("listRank")
public ResultBean listRank(@RequestParam(value = "type",defaultValue = "0") Byte type,@RequestParam(value = "limit",defaultValue = "30") Integer limit){ public ResultBean<List<Book>> listRank(@RequestParam(value = "type", defaultValue = "0") Byte type, @RequestParam(value = "limit", defaultValue = "30") Integer limit) {
return ResultBean.ok(bookService.listRank(type,limit)); return ResultBean.ok(bookService.listRank(type, limit));
} }
/** /**
* 增加点击次数 * 增加点击次数
* */ */
@PostMapping("addVisitCount") @PostMapping("addVisitCount")
public ResultBean addVisitCount(Long bookId){ public ResultBean<Void> addVisitCount(Long bookId) {
if(enableMq == 1) { if (enableMq == 1) {
rabbitTemplate.convertAndSend("ADD-BOOK-VISIT-EXCHANGE", null, bookId); rabbitTemplate.convertAndSend("ADD-BOOK-VISIT-EXCHANGE", null, bookId);
}else { } else {
bookService.addVisitCount(bookId, 1); bookService.addVisitCount(bookId, 1);
} }
return ResultBean.ok(); return ResultBean.ok();
@ -117,68 +125,64 @@ public class BookController extends BaseController{
/** /**
* 查询章节相关信息 * 查询章节相关信息
* */ */
@GetMapping("queryBookIndexAbout") @GetMapping("queryBookIndexAbout")
public ResultBean queryBookIndexAbout(Long bookId,Long lastBookIndexId) { public ResultBean<Map<String, Object>> queryBookIndexAbout(Long bookId, Long lastBookIndexId) {
Map<String,Object> data = new HashMap<>(2); Map<String, Object> data = new HashMap<>(2);
data.put("bookIndexCount",bookService.queryIndexCount(bookId)); data.put("bookIndexCount", bookService.queryIndexCount(bookId));
String lastBookContent = bookService.queryBookContent(lastBookIndexId).getContent(); String lastBookContent = bookContentService.queryBookContent(bookId,lastBookIndexId).getContent();
if(lastBookContent.length()>42){ if (lastBookContent.length() > 42) {
lastBookContent=lastBookContent.substring(0,42); lastBookContent = lastBookContent.substring(0, 42);
} }
data.put("lastBookContent",lastBookContent); data.put("lastBookContent", lastBookContent);
return ResultBean.ok(data); return ResultBean.ok(data);
} }
/** /**
* 根据分类id查询同类推荐书籍 * 根据分类id查询同类推荐书籍
* */ */
@GetMapping("listRecBookByCatId") @GetMapping("listRecBookByCatId")
public ResultBean listRecBookByCatId(Integer catId) { public ResultBean<List<Book>> listRecBookByCatId(Integer catId) {
return ResultBean.ok(bookService.listRecBookByCatId(catId)); return ResultBean.ok(bookService.listRecBookByCatId(catId));
} }
/** /**
*分页查询书籍评论列表 * 分页查询书籍评论列表
* */ */
@GetMapping("listCommentByPage") @GetMapping("listCommentByPage")
public ResultBean listCommentByPage(@RequestParam("bookId") Long bookId,@RequestParam(value = "curr", defaultValue = "1") int page, @RequestParam(value = "limit", defaultValue = "5") int pageSize) { public ResultBean<PageBean<BookCommentVO>> listCommentByPage(@RequestParam("bookId") Long bookId, @RequestParam(value = "curr", defaultValue = "1") int page, @RequestParam(value = "limit", defaultValue = "5") int pageSize) {
return ResultBean.ok(bookService.listCommentByPage(null,bookId,page,pageSize)); return ResultBean.ok(bookService.listCommentByPage(null, bookId, page, pageSize));
} }
/** /**
* 新增评价 * 新增评价
* */ */
@PostMapping("addBookComment") @PostMapping("addBookComment")
public ResultBean addBookComment(BookComment comment, HttpServletRequest request) { public ResultBean<?> addBookComment(BookComment comment, HttpServletRequest request) {
UserDetails userDetails = getUserDetails(request); UserDetails userDetails = getUserDetails(request);
if (userDetails == null) { if (userDetails == null) {
return ResultBean.fail(ResponseStatus.NO_LOGIN); return ResultBean.fail(ResponseStatus.NO_LOGIN);
} }
bookService.addBookComment(userDetails.getId(),comment); bookService.addBookComment(userDetails.getId(), comment);
return ResultBean.ok(); return ResultBean.ok();
} }
/** /**
* 根据小说ID查询小说前十条最新更新目录集合 * 根据小说ID查询小说前十条最新更新目录集合
* */ */
@GetMapping("queryNewIndexList") @GetMapping("queryNewIndexList")
public ResultBean queryNewIndexList(Long bookId){ public ResultBean<List<BookIndex>> queryNewIndexList(Long bookId) {
return ResultBean.ok(bookService.queryIndexList(bookId,"index_num desc",1,10)); return ResultBean.ok(bookService.queryIndexList(bookId, "index_num desc", 1, 10));
} }
/** /**
* 目录页 * 目录页
* */ */
@GetMapping("/queryIndexList") @GetMapping("/queryIndexList")
public ResultBean indexList(Long bookId,@RequestParam(value = "curr", defaultValue = "1") int page, @RequestParam(value = "limit", defaultValue = "5") int pageSize,@RequestParam(value = "orderBy",defaultValue = "index_num desc") String orderBy) { public ResultBean<PageBean<BookIndex>> indexList(Long bookId, @RequestParam(value = "curr", defaultValue = "1") int page, @RequestParam(value = "limit", defaultValue = "5") int pageSize, @RequestParam(value = "orderBy", defaultValue = "index_num desc") String orderBy) {
return ResultBean.ok(new PageBean<>(bookService.queryIndexList(bookId,orderBy,page,pageSize))); return ResultBean.ok(new PageBean<>(bookService.queryIndexList(bookId, orderBy, page, pageSize)));
} }
} }

View File

@ -40,7 +40,7 @@ public class CacheController {
* @param type 缓存类型1首页书籍推荐2首页新闻3首页友情链接 * @param type 缓存类型1首页书籍推荐2首页新闻3首页友情链接
* */ * */
@GetMapping("refresh/{pass}/{type}") @GetMapping("refresh/{pass}/{type}")
public ResultBean refreshCache(@PathVariable("type") Byte type, @PathVariable("pass") String pass){ public ResultBean<Void> refreshCache(@PathVariable("type") Byte type, @PathVariable("pass") String pass){
if(!cacheManagerPass.equals(pass)){ if(!cacheManagerPass.equals(pass)){
return ResultBean.fail(ResponseStatus.PASSWORD_ERROR); return ResultBean.fail(ResponseStatus.PASSWORD_ERROR);
} }

View File

@ -2,28 +2,23 @@ package com.java2nb.novel.controller;
import com.java2nb.novel.core.bean.ResultBean; import com.java2nb.novel.core.bean.ResultBean;
import com.java2nb.novel.core.cache.CacheService; import com.java2nb.novel.core.cache.CacheService;
import com.java2nb.novel.core.enums.ResponseStatus;
import com.java2nb.novel.core.exception.BusinessException;
import com.java2nb.novel.core.utils.Constants; import com.java2nb.novel.core.utils.Constants;
import com.java2nb.novel.core.utils.FileUtil;
import com.java2nb.novel.core.utils.RandomValidateCodeUtil; import com.java2nb.novel.core.utils.RandomValidateCodeUtil;
import com.java2nb.novel.core.utils.RestTemplateUtil;
import com.java2nb.novel.core.utils.UUIDUtil; import com.java2nb.novel.core.utils.UUIDUtil;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.Charsets;
import org.apache.http.client.utils.DateUtils; 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.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.*; import java.io.*;
import java.util.Date; import java.util.Date;
import java.util.Objects; import java.util.Objects;
@ -63,29 +58,35 @@ public class FileController {
} }
/** /**
* 文件上传 * 图片上传
* @return
*/ */
@SneakyThrows
@ResponseBody @ResponseBody
@PostMapping("/upload") @PostMapping("/picUpload")
ResultBean upload(@RequestParam("file") MultipartFile file) { ResultBean<String> upload(@RequestParam("file") MultipartFile file) {
Date currentDate = new Date(); Date currentDate = new Date();
try { String savePath =
String savePath = Constants.LOCAL_PIC_PREFIX + DateUtils.formatDate(currentDate, "yyyy") + "/" +
Constants.LOCAL_PIC_PREFIX + DateUtils.formatDate(currentDate, "yyyy") + "/" + DateUtils.formatDate(currentDate, "MM") + "/" +
DateUtils.formatDate(currentDate, "MM") + "/" + DateUtils.formatDate(currentDate, "dd");
DateUtils.formatDate(currentDate, "dd") ; String oriName = file.getOriginalFilename();
String oriName = file.getOriginalFilename(); assert oriName != null;
String saveFileName = UUIDUtil.getUUID32() + oriName.substring(oriName.lastIndexOf(".")); String saveFileName = UUIDUtil.getUUID32() + oriName.substring(oriName.lastIndexOf("."));
File saveFile = new File( picSavePath + savePath, saveFileName); File saveFile = new File(picSavePath + savePath, saveFileName);
if (!saveFile.getParentFile().exists()) { if (!saveFile.getParentFile().exists()) {
saveFile.getParentFile().mkdirs(); boolean isSuccess = saveFile.getParentFile().mkdirs();
if(!isSuccess){
throw new BusinessException(ResponseStatus.FILE_DIR_MAKE_FAIL);
} }
file.transferTo(saveFile);
return ResultBean.ok(savePath+"/"+saveFileName);
} catch (Exception e) {
log.error(e.getMessage(), e);
return ResultBean.error();
} }
file.transferTo(saveFile);
if(!FileUtil.isImage(saveFile)){
//上传的文件不是图片
saveFile.delete();
throw new BusinessException(ResponseStatus.FILE_NOT_IMAGE);
};
return ResultBean.ok(savePath + "/" + saveFileName);
} }

View File

@ -1,6 +1,7 @@
package com.java2nb.novel.controller; package com.java2nb.novel.controller;
import com.java2nb.novel.core.bean.ResultBean; import com.java2nb.novel.core.bean.ResultBean;
import com.java2nb.novel.entity.FriendLink;
import com.java2nb.novel.service.FriendLinkService; import com.java2nb.novel.service.FriendLinkService;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@ -9,6 +10,8 @@ import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/** /**
* @author 11797 * @author 11797
*/ */
@ -24,7 +27,7 @@ public class FriendLinkController {
* 查询首页友情链接 * 查询首页友情链接
* */ * */
@GetMapping("listIndexLink") @GetMapping("listIndexLink")
public ResultBean listIndexLink(){ public ResultBean<List<FriendLink>> listIndexLink(){
return ResultBean.ok(friendLinkService.listIndexLink()); return ResultBean.ok(friendLinkService.listIndexLink());
} }

View File

@ -1,12 +1,16 @@
package com.java2nb.novel.controller; package com.java2nb.novel.controller;
import com.github.pagehelper.PageInfo; import com.github.pagehelper.PageInfo;
import com.java2nb.novel.core.bean.PageBean;
import com.java2nb.novel.core.bean.ResultBean; import com.java2nb.novel.core.bean.ResultBean;
import com.java2nb.novel.entity.News;
import com.java2nb.novel.service.NewsService; import com.java2nb.novel.service.NewsService;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import java.util.List;
/** /**
* @author 11797 * @author 11797
*/ */
@ -22,7 +26,7 @@ public class NewsController {
* 查询首页新闻 * 查询首页新闻
* */ * */
@GetMapping("listIndexNews") @GetMapping("listIndexNews")
public ResultBean listIndexNews(){ public ResultBean<List<News>> listIndexNews(){
return ResultBean.ok(newsService.listIndexNews()); return ResultBean.ok(newsService.listIndexNews());
} }
@ -30,10 +34,19 @@ public class NewsController {
* 分页查询新闻列表 * 分页查询新闻列表
* */ * */
@GetMapping("listByPage") @GetMapping("listByPage")
public ResultBean listByPage(@RequestParam(value = "curr", defaultValue = "1") int page, @RequestParam(value = "limit", defaultValue = "5") int pageSize){ public ResultBean<PageBean<News>> listByPage(@RequestParam(value = "curr", defaultValue = "1") int page, @RequestParam(value = "limit", defaultValue = "5") int pageSize){
return ResultBean.ok(newsService.listByPage(page,pageSize)); return ResultBean.ok(newsService.listByPage(page,pageSize));
} }
/**
* 增加新闻阅读量
* */
@PostMapping("addReadCount")
public ResultBean<Void> addReadCount(@RequestParam(value = "newsId") Integer newsId){
newsService.addReadCount(newsId);
return ResultBean.ok();
}
} }

View File

@ -17,8 +17,8 @@ import org.springframework.web.bind.annotation.RequestMapping;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter; import java.io.PrintWriter;
import java.nio.charset.StandardCharsets;
import java.util.HashMap; import java.util.HashMap;
import java.util.Iterator;
import java.util.Map; import java.util.Map;
/** /**
@ -47,7 +47,6 @@ public class PayController extends BaseController {
if (userDetails == null) { if (userDetails == null) {
//未登录,跳转到登陆页面 //未登录,跳转到登陆页面
httpResponse.sendRedirect("/user/login.html?originUrl=/pay/aliPay?payAmount="+payAmount); httpResponse.sendRedirect("/user/login.html?originUrl=/pay/aliPay?payAmount="+payAmount);
return;
}else { }else {
//创建充值订单 //创建充值订单
Long outTradeNo = orderService.createPayOrder((byte)1,payAmount,userDetails.getId()); Long outTradeNo = orderService.createPayOrder((byte)1,payAmount,userDetails.getId());
@ -92,11 +91,10 @@ public class PayController extends BaseController {
PrintWriter out = httpResponse.getWriter(); PrintWriter out = httpResponse.getWriter();
//获取支付宝POST过来反馈信息 //获取支付宝POST过来反馈信息
Map<String,String> params = new HashMap<String,String>(); Map<String,String> params = new HashMap<>();
Map<String,String[]> requestParams = request.getParameterMap(); Map<String,String[]> requestParams = request.getParameterMap();
for (Iterator<String> iter = requestParams.keySet().iterator(); iter.hasNext();) { for (String name : requestParams.keySet()) {
String name = (String) iter.next(); String[] values = requestParams.get(name);
String[] values = (String[]) requestParams.get(name);
String valueStr = ""; String valueStr = "";
for (int i = 0; i < values.length; i++) { for (int i = 0; i < values.length; i++) {
valueStr = (i == values.length - 1) ? valueStr + values[i] valueStr = (i == values.length - 1) ? valueStr + values[i]
@ -119,13 +117,13 @@ public class PayController extends BaseController {
if(signVerified) { if(signVerified) {
//验证成功 //验证成功
//商户订单号 //商户订单号
String outTradeNo = new String(request.getParameter("out_trade_no").getBytes("ISO-8859-1"),"UTF-8"); String outTradeNo = new String(request.getParameter("out_trade_no").getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8);
//支付宝交易号 //支付宝交易号
String tradeNo = new String(request.getParameter("trade_no").getBytes("ISO-8859-1"),"UTF-8"); String tradeNo = new String(request.getParameter("trade_no").getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8);
//交易状态 //交易状态
String tradeStatus = new String(request.getParameter("trade_status").getBytes("ISO-8859-1"),"UTF-8"); String tradeStatus = new String(request.getParameter("trade_status").getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8);
//更新订单状态 //更新订单状态
orderService.updatePayOrder(Long.parseLong(outTradeNo), tradeNo, tradeStatus); orderService.updatePayOrder(Long.parseLong(outTradeNo), tradeNo, tradeStatus);

View File

@ -41,7 +41,7 @@ public class UserController extends BaseController {
* 登陆 * 登陆
*/ */
@PostMapping("login") @PostMapping("login")
public ResultBean login(User user) { public ResultBean<Map<String, Object>> login(User user) {
//登陆 //登陆
UserDetails userDetails = userService.login(user); UserDetails userDetails = userService.login(user);
@ -58,7 +58,7 @@ public class UserController extends BaseController {
* 注册 * 注册
*/ */
@PostMapping("register") @PostMapping("register")
public ResultBean register(@Validated({AddGroup.class}) User user, @RequestParam(value = "velCode", defaultValue = "") String velCode) { public ResultBean<?> register(@Validated({AddGroup.class}) User user, @RequestParam(value = "velCode", defaultValue = "") String velCode) {
//判断验证码是否正确 //判断验证码是否正确
@ -81,7 +81,7 @@ public class UserController extends BaseController {
* 刷新token * 刷新token
*/ */
@PostMapping("refreshToken") @PostMapping("refreshToken")
public ResultBean refreshToken(HttpServletRequest request) { public ResultBean<?> refreshToken(HttpServletRequest request) {
String token = getToken(request); String token = getToken(request);
if (jwtTokenUtil.canRefresh(token)) { if (jwtTokenUtil.canRefresh(token)) {
token = jwtTokenUtil.refreshToken(token); token = jwtTokenUtil.refreshToken(token);
@ -102,7 +102,7 @@ public class UserController extends BaseController {
* 查询小说是否已加入书架 * 查询小说是否已加入书架
*/ */
@GetMapping("queryIsInShelf") @GetMapping("queryIsInShelf")
public ResultBean queryIsInShelf(Long bookId, HttpServletRequest request) { public ResultBean<?> queryIsInShelf(Long bookId, HttpServletRequest request) {
UserDetails userDetails = getUserDetails(request); UserDetails userDetails = getUserDetails(request);
if (userDetails == null) { if (userDetails == null) {
return ResultBean.fail(ResponseStatus.NO_LOGIN); return ResultBean.fail(ResponseStatus.NO_LOGIN);
@ -114,7 +114,7 @@ public class UserController extends BaseController {
* 加入书架 * 加入书架
* */ * */
@PostMapping("addToBookShelf") @PostMapping("addToBookShelf")
public ResultBean addToBookShelf(Long bookId,Long preContentId, HttpServletRequest request) { public ResultBean<Void> addToBookShelf(Long bookId,Long preContentId, HttpServletRequest request) {
UserDetails userDetails = getUserDetails(request); UserDetails userDetails = getUserDetails(request);
if (userDetails == null) { if (userDetails == null) {
return ResultBean.fail(ResponseStatus.NO_LOGIN); return ResultBean.fail(ResponseStatus.NO_LOGIN);
@ -127,7 +127,7 @@ public class UserController extends BaseController {
* 移出书架 * 移出书架
* */ * */
@DeleteMapping("removeFromBookShelf/{bookId}") @DeleteMapping("removeFromBookShelf/{bookId}")
public ResultBean removeFromBookShelf(@PathVariable("bookId") Long bookId, HttpServletRequest request) { public ResultBean<?> removeFromBookShelf(@PathVariable("bookId") Long bookId, HttpServletRequest request) {
UserDetails userDetails = getUserDetails(request); UserDetails userDetails = getUserDetails(request);
if (userDetails == null) { if (userDetails == null) {
return ResultBean.fail(ResponseStatus.NO_LOGIN); return ResultBean.fail(ResponseStatus.NO_LOGIN);
@ -140,7 +140,7 @@ public class UserController extends BaseController {
* 分页查询书架 * 分页查询书架
* */ * */
@GetMapping("listBookShelfByPage") @GetMapping("listBookShelfByPage")
public ResultBean listBookShelfByPage(@RequestParam(value = "curr", defaultValue = "1") int page, @RequestParam(value = "limit", defaultValue = "10") int pageSize,HttpServletRequest request) { public ResultBean<?> listBookShelfByPage(@RequestParam(value = "curr", defaultValue = "1") int page, @RequestParam(value = "limit", defaultValue = "10") int pageSize,HttpServletRequest request) {
UserDetails userDetails = getUserDetails(request); UserDetails userDetails = getUserDetails(request);
if (userDetails == null) { if (userDetails == null) {
return ResultBean.fail(ResponseStatus.NO_LOGIN); return ResultBean.fail(ResponseStatus.NO_LOGIN);
@ -152,7 +152,7 @@ public class UserController extends BaseController {
* 分页查询阅读记录 * 分页查询阅读记录
* */ * */
@GetMapping("listReadHistoryByPage") @GetMapping("listReadHistoryByPage")
public ResultBean listReadHistoryByPage(@RequestParam(value = "curr", defaultValue = "1") int page, @RequestParam(value = "limit", defaultValue = "10") int pageSize,HttpServletRequest request) { public ResultBean<?> listReadHistoryByPage(@RequestParam(value = "curr", defaultValue = "1") int page, @RequestParam(value = "limit", defaultValue = "10") int pageSize,HttpServletRequest request) {
UserDetails userDetails = getUserDetails(request); UserDetails userDetails = getUserDetails(request);
if (userDetails == null) { if (userDetails == null) {
return ResultBean.fail(ResponseStatus.NO_LOGIN); return ResultBean.fail(ResponseStatus.NO_LOGIN);
@ -164,7 +164,7 @@ public class UserController extends BaseController {
* 添加阅读记录 * 添加阅读记录
* */ * */
@PostMapping("addReadHistory") @PostMapping("addReadHistory")
public ResultBean addReadHistory(Long bookId,Long preContentId, HttpServletRequest request) { public ResultBean<?> addReadHistory(Long bookId,Long preContentId, HttpServletRequest request) {
UserDetails userDetails = getUserDetails(request); UserDetails userDetails = getUserDetails(request);
if (userDetails == null) { if (userDetails == null) {
return ResultBean.fail(ResponseStatus.NO_LOGIN); return ResultBean.fail(ResponseStatus.NO_LOGIN);
@ -177,7 +177,7 @@ public class UserController extends BaseController {
* 添加反馈 * 添加反馈
* */ * */
@PostMapping("addFeedBack") @PostMapping("addFeedBack")
public ResultBean addFeedBack(String content, HttpServletRequest request) { public ResultBean<?> addFeedBack(String content, HttpServletRequest request) {
UserDetails userDetails = getUserDetails(request); UserDetails userDetails = getUserDetails(request);
if (userDetails == null) { if (userDetails == null) {
return ResultBean.fail(ResponseStatus.NO_LOGIN); return ResultBean.fail(ResponseStatus.NO_LOGIN);
@ -190,7 +190,7 @@ public class UserController extends BaseController {
* 分页查询我的反馈列表 * 分页查询我的反馈列表
* */ * */
@GetMapping("listUserFeedBackByPage") @GetMapping("listUserFeedBackByPage")
public ResultBean listUserFeedBackByPage(@RequestParam(value = "curr", defaultValue = "1") int page, @RequestParam(value = "limit", defaultValue = "5") int pageSize, HttpServletRequest request){ public ResultBean<?> listUserFeedBackByPage(@RequestParam(value = "curr", defaultValue = "1") int page, @RequestParam(value = "limit", defaultValue = "5") int pageSize, HttpServletRequest request){
UserDetails userDetails = getUserDetails(request); UserDetails userDetails = getUserDetails(request);
if (userDetails == null) { if (userDetails == null) {
return ResultBean.fail(ResponseStatus.NO_LOGIN); return ResultBean.fail(ResponseStatus.NO_LOGIN);
@ -202,7 +202,7 @@ public class UserController extends BaseController {
* 查询个人信息 * 查询个人信息
* */ * */
@GetMapping("userInfo") @GetMapping("userInfo")
public ResultBean userInfo(HttpServletRequest request) { public ResultBean<?> userInfo(HttpServletRequest request) {
UserDetails userDetails = getUserDetails(request); UserDetails userDetails = getUserDetails(request);
if (userDetails == null) { if (userDetails == null) {
return ResultBean.fail(ResponseStatus.NO_LOGIN); return ResultBean.fail(ResponseStatus.NO_LOGIN);
@ -214,7 +214,7 @@ public class UserController extends BaseController {
* 更新个人信息 * 更新个人信息
* */ * */
@PostMapping("updateUserInfo") @PostMapping("updateUserInfo")
public ResultBean updateUserInfo(@Validated({UpdateGroup.class}) User user, HttpServletRequest request) { public ResultBean<?> updateUserInfo(@Validated({UpdateGroup.class}) User user, HttpServletRequest request) {
UserDetails userDetails = getUserDetails(request); UserDetails userDetails = getUserDetails(request);
if (userDetails == null) { if (userDetails == null) {
return ResultBean.fail(ResponseStatus.NO_LOGIN); return ResultBean.fail(ResponseStatus.NO_LOGIN);
@ -234,7 +234,7 @@ public class UserController extends BaseController {
* 更新密码 * 更新密码
* */ * */
@PostMapping("updatePassword") @PostMapping("updatePassword")
public ResultBean updatePassword(String oldPassword,String newPassword1,String newPassword2,HttpServletRequest request) { public ResultBean<?> updatePassword(String oldPassword,String newPassword1,String newPassword2,HttpServletRequest request) {
UserDetails userDetails = getUserDetails(request); UserDetails userDetails = getUserDetails(request);
if (userDetails == null) { if (userDetails == null) {
return ResultBean.fail(ResponseStatus.NO_LOGIN); return ResultBean.fail(ResponseStatus.NO_LOGIN);
@ -250,7 +250,7 @@ public class UserController extends BaseController {
* 分页查询用户书评 * 分页查询用户书评
* */ * */
@GetMapping("listCommentByPage") @GetMapping("listCommentByPage")
public ResultBean listCommentByPage(@RequestParam(value = "curr", defaultValue = "1") int page, @RequestParam(value = "limit", defaultValue = "5") int pageSize,HttpServletRequest request) { public ResultBean<?> listCommentByPage(@RequestParam(value = "curr", defaultValue = "1") int page, @RequestParam(value = "limit", defaultValue = "5") int pageSize,HttpServletRequest request) {
UserDetails userDetails = getUserDetails(request); UserDetails userDetails = getUserDetails(request);
if (userDetails == null) { if (userDetails == null) {
return ResultBean.fail(ResponseStatus.NO_LOGIN); return ResultBean.fail(ResponseStatus.NO_LOGIN);
@ -263,7 +263,7 @@ public class UserController extends BaseController {
* 购买小说章节 * 购买小说章节
* */ * */
@PostMapping("buyBookIndex") @PostMapping("buyBookIndex")
public ResultBean buyBookIndex(UserBuyRecord buyRecord, HttpServletRequest request) { public ResultBean<?> buyBookIndex(UserBuyRecord buyRecord, HttpServletRequest request) {
UserDetails userDetails = getUserDetails(request); UserDetails userDetails = getUserDetails(request);
if (userDetails == null) { if (userDetails == null) {
return ResultBean.fail(ResponseStatus.NO_LOGIN); return ResultBean.fail(ResponseStatus.NO_LOGIN);

View File

@ -30,7 +30,7 @@ public class EsConfig {
String uri = uris[i]; String uri = uris[i];
String scheme = uri.substring(0,uri.indexOf(":")).trim(); String scheme = uri.substring(0,uri.indexOf(":")).trim();
String hostname = uri.substring(uri.indexOf("://")+3,uri.lastIndexOf(":")).trim(); String hostname = uri.substring(uri.indexOf("://")+3,uri.lastIndexOf(":")).trim();
Integer port = Integer.parseInt(uri.substring(uri.lastIndexOf(":")+1).trim()); int port = Integer.parseInt(uri.substring(uri.lastIndexOf(":")+1).trim());
hosts[i] = new HttpHost(hostname,port,scheme); hosts[i] = new HttpHost(hostname,port,scheme);
} }

View File

@ -32,7 +32,7 @@ public class FilterConfig{
private String urlPatterns; private String urlPatterns;
@Bean @Bean
public FilterRegistrationBean<NovelFilter> filterRegist() { public FilterRegistrationBean<NovelFilter> filterRegister() {
FilterRegistrationBean<NovelFilter> frBean = new FilterRegistrationBean<>(); FilterRegistrationBean<NovelFilter> frBean = new FilterRegistrationBean<>();
frBean.setFilter(new NovelFilter()); frBean.setFilter(new NovelFilter());
frBean.addUrlPatterns("/*"); frBean.addUrlPatterns("/*");
@ -41,9 +41,9 @@ public class FilterConfig{
} }
@Bean @Bean
public FilterRegistrationBean xssFilterRegistration() public FilterRegistrationBean<XssFilter> xssFilterRegistration()
{ {
FilterRegistrationBean registration = new FilterRegistrationBean(); FilterRegistrationBean<XssFilter> registration = new FilterRegistrationBean<>();
// //
registration.setDispatcherTypes(DispatcherType.REQUEST); registration.setDispatcherTypes(DispatcherType.REQUEST);
//过滤器类继承Filter //过滤器类继承Filter

View File

@ -38,7 +38,7 @@ public class NovelFilter implements Filter {
//缓存10天 //缓存10天
resp.setDateHeader("expires", System.currentTimeMillis()+60*60*24*10*1000); resp.setDateHeader("expires", System.currentTimeMillis()+60*60*24*10*1000);
OutputStream out = resp.getOutputStream(); OutputStream out = resp.getOutputStream();
InputStream input = new FileInputStream(new File(picSavePath + requestUri)); InputStream input = new FileInputStream(picSavePath + requestUri);
byte[] b = new byte[4096]; byte[] b = new byte[4096];
for (int n; (n = input.read(b)) != -1; ) { for (int n; (n = input.read(b)) != -1; ) {
out.write(b, 0, n); out.write(b, 0, n);
@ -55,7 +55,7 @@ public class NovelFilter implements Filter {
userMark = UUIDUtil.getUUID32(); userMark = UUIDUtil.getUUID32();
CookieUtil.setCookie(resp,Constants.USER_CLIENT_MARK_KEY,userMark); CookieUtil.setCookie(resp,Constants.USER_CLIENT_MARK_KEY,userMark);
} }
ThreadLocalUtil.setCientId(userMark); ThreadLocalUtil.setClientId(userMark);
//根据浏览器类型选择前端模板 //根据浏览器类型选择前端模板
String to = req.getParameter("to"); String to = req.getParameter("to");
CacheService cacheService = SpringUtil.getBean(CacheService.class); CacheService cacheService = SpringUtil.getBean(CacheService.class);

View File

@ -6,8 +6,8 @@ import org.apache.commons.lang3.StringUtils;
import javax.servlet.*; import javax.servlet.*;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
@ -34,12 +34,10 @@ public class XssFilter implements Filter {
String tempEnabled = filterConfig.getInitParameter("enabled"); String tempEnabled = filterConfig.getInitParameter("enabled");
if (StringUtils.isNotBlank(tempExcludes)) { if (StringUtils.isNotBlank(tempExcludes)) {
String[] url = tempExcludes.split(","); String[] url = tempExcludes.split(",");
for (int i = 0; url != null && i < url.length; i++) { excludes.addAll(Arrays.asList(url));
excludes.add(url[i]);
}
} }
if (StringUtils.isNotEmpty(tempEnabled)) { if (StringUtils.isNotEmpty(tempEnabled)) {
enabled = Boolean.valueOf(tempEnabled); enabled = Boolean.parseBoolean(tempEnabled);
} }
} }
@ -48,8 +46,7 @@ public class XssFilter implements Filter {
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
{ {
HttpServletRequest req = (HttpServletRequest) request; HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse resp = (HttpServletResponse) response; if (handleExcludeURL(req)) {
if (handleExcludeURL(req, resp)) {
chain.doFilter(request, response); chain.doFilter(request, response);
return; return;
} }
@ -57,7 +54,7 @@ public class XssFilter implements Filter {
chain.doFilter(xssRequest, response); chain.doFilter(xssRequest, response);
} }
private boolean handleExcludeURL(HttpServletRequest request, HttpServletResponse response) { private boolean handleExcludeURL(HttpServletRequest request) {
if (!enabled) { if (!enabled) {
return true; return true;
} }

View File

@ -58,8 +58,8 @@ public class MonthIncomeStaSchedule {
//2.查询作家作品 //2.查询作家作品
List<Book> books = bookService.queryBookList(authorId); List<Book> books = bookService.queryBookList(authorId);
Long totalPreTaxIncome = 0L; long totalPreTaxIncome = 0L;
Long totalAfterTaxIncome = 0L; long totalAfterTaxIncome = 0L;
for (Book book : books) { for (Book book : books) {
Long bookId = book.getId(); Long bookId = book.getId();
@ -70,14 +70,14 @@ public class MonthIncomeStaSchedule {
BigDecimal monthIncomeShare = new BigDecimal(monthIncome) BigDecimal monthIncomeShare = new BigDecimal(monthIncome)
.multiply(authorIncomeConfig.getShareProportion()); .multiply(authorIncomeConfig.getShareProportion());
Long preTaxIncome = monthIncomeShare long preTaxIncome = monthIncomeShare
.multiply(authorIncomeConfig.getExchangeProportion()) .multiply(authorIncomeConfig.getExchangeProportion())
.multiply(new BigDecimal(100)) .multiply(new BigDecimal(100))
.longValue(); .longValue();
totalPreTaxIncome += preTaxIncome; totalPreTaxIncome += preTaxIncome;
Long afterTaxIncome = monthIncomeShare long afterTaxIncome = monthIncomeShare
.multiply(authorIncomeConfig.getTaxRate()) .multiply(authorIncomeConfig.getTaxRate())
.multiply(authorIncomeConfig.getExchangeProportion()) .multiply(authorIncomeConfig.getExchangeProportion())
.multiply(new BigDecimal(100)) .multiply(new BigDecimal(100))

View File

@ -0,0 +1,20 @@
package com.java2nb.novel.core.serialize;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import org.apache.commons.lang3.StringUtils;
import java.io.IOException;
public class CommentUserNameSerialize extends JsonSerializer<String> {
@Override
public void serialize(String s, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
if(StringUtils.isNotBlank(s)){
jsonGenerator.writeString(s.substring(0, 4) + "****" + s.substring(s.length() - 3));
}
}
}

View File

@ -12,12 +12,12 @@ public class ThreadLocalUtil {
/** /**
* 存储当前线程访问的模板目录 * 存储当前线程访问的模板目录
* */ * */
private static ThreadLocal<String> templateDir = new ThreadLocal<>(); private static final ThreadLocal<String> templateDir = new ThreadLocal<>();
/** /**
* 存储当前会话的sessionID * 存储当前会话的sessionID
* */ * */
private static ThreadLocal<String> clientId = new ThreadLocal<>(); private static final ThreadLocal<String> clientId = new ThreadLocal<>();
/** /**
* 设置当前应该访问的模板目录 * 设置当前应该访问的模板目录
@ -41,7 +41,7 @@ public class ThreadLocalUtil {
/** /**
* 设置当前访问线程的客户端ID * 设置当前访问线程的客户端ID
* */ * */
public static void setCientId(String id){ public static void setClientId(String id){
clientId.set(id); clientId.set(id);
} }

View File

@ -14,11 +14,6 @@ import java.util.List;
*/ */
public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper { public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper {
/**
* 假如有有html 代码是自己传来的 需要设定对应的name 不过滤
*/
private static final List<String> noFilterNames = Arrays.asList("content");
/** /**
* @param request * @param request
*/ */
@ -29,14 +24,14 @@ public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper {
@Override @Override
public String[] getParameterValues(String name) { public String[] getParameterValues(String name) {
String[] values = super.getParameterValues(name); String[] values = super.getParameterValues(name);
if (!noFilterNames.contains(name) && values != null) { if (values != null) {
int length = values.length; int length = values.length;
String[] escapseValues = new String[length]; String[] escapeValues = new String[length];
for (int i = 0; i < length; i++) { for (int i = 0; i < length; i++) {
escapseValues[i] = values[i].replaceAll("<", "&lt;").replaceAll(">", "&gt;"); escapeValues[i] = values[i].replaceAll("<", "&lt;").replaceAll(">", "&gt;");
} }
return escapseValues; return escapeValues;
} }
return values; return null;
} }
} }

View File

@ -0,0 +1,21 @@
package com.java2nb.novel.mapper;
import com.java2nb.novel.entity.Book;
import com.java2nb.novel.vo.BookSpVO;
import com.java2nb.novel.vo.BookVO;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* @author Administrator
*/
public interface FrontNewsMapper extends NewsMapper {
/**
* 增加新闻阅读量
* @param newsId 新闻ID
* */
void addReadCount(@Param("newsId") Integer newsId);
}

View File

@ -1,17 +1,18 @@
package com.java2nb.novel.page; package com.java2nb.novel.page;
import com.java2nb.novel.controller.BaseController; import com.java2nb.novel.controller.BaseController;
import com.java2nb.novel.core.bean.PageBean;
import com.java2nb.novel.core.bean.UserDetails; import com.java2nb.novel.core.bean.UserDetails;
import com.java2nb.novel.core.utils.ThreadLocalUtil; import com.java2nb.novel.core.utils.ThreadLocalUtil;
import com.java2nb.novel.entity.*; import com.java2nb.novel.entity.*;
import com.java2nb.novel.service.AuthorService; import com.java2nb.novel.service.*;
import com.java2nb.novel.service.BookService; import com.java2nb.novel.vo.BookCommentVO;
import com.java2nb.novel.service.NewsService; import com.java2nb.novel.vo.BookSettingVO;
import com.java2nb.novel.service.UserService;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows; import lombok.SneakyThrows;
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.Value;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
import org.springframework.ui.Model; import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PathVariable;
@ -21,6 +22,7 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import java.io.Serializable; import java.io.Serializable;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.ThreadPoolExecutor;
@ -32,6 +34,9 @@ import java.util.concurrent.ThreadPoolExecutor;
@Controller @Controller
public class PageController extends BaseController { public class PageController extends BaseController {
@Value("${txt.save.path}")
private String fileSavePath;
private final BookService bookService; private final BookService bookService;
private final NewsService newsService; private final NewsService newsService;
@ -40,6 +45,8 @@ public class PageController extends BaseController {
private final UserService userService; private final UserService userService;
private final BookContentService bookContentService;
private final ThreadPoolExecutor threadPoolExecutor; private final ThreadPoolExecutor threadPoolExecutor;
@ -76,8 +83,15 @@ public class PageController extends BaseController {
/** /**
* 首页 * 首页
*/ */
@SneakyThrows
@RequestMapping(path = {"/", "/index", "/index.html"}) @RequestMapping(path = {"/", "/index", "/index.html"})
public String index() { public String index(Model model) {
//加载小说首页小说基本信息线程
CompletableFuture<Map<Byte, List<BookSettingVO>>> bookCompletableFuture = CompletableFuture.supplyAsync(bookService::listBookSettingVO, threadPoolExecutor);
//加载首页新闻线程
CompletableFuture<List<News>> newsCompletableFuture = CompletableFuture.supplyAsync(newsService::listIndexNews, threadPoolExecutor);
model.addAttribute("bookMap", bookCompletableFuture.get());
model.addAttribute("newsList", newsCompletableFuture.get());
return ThreadLocalUtil.getTemplateDir() + "index"; return ThreadLocalUtil.getTemplateDir() + "index";
} }
@ -105,13 +119,42 @@ public class PageController extends BaseController {
@SneakyThrows @SneakyThrows
@RequestMapping("/book/{bookId}.html") @RequestMapping("/book/{bookId}.html")
public String bookDetail(@PathVariable("bookId") Long bookId, Model model) { public String bookDetail(@PathVariable("bookId") Long bookId, Model model) {
Book book = bookService.queryBookDetail(bookId); //加载小说基本信息线程
model.addAttribute("book", book); CompletableFuture<Book> bookCompletableFuture = CompletableFuture.supplyAsync(() -> {
if (book.getLastIndexId() != null) { //查询书籍
//查询首章目录ID Book book = bookService.queryBookDetail(bookId);
Long firstBookIndexId = bookService.queryFirstBookIndexId(bookId); log.debug("加载小说基本信息线程结束");
model.addAttribute("firstBookIndexId", firstBookIndexId); return book;
} }, threadPoolExecutor);
//加载小说评论列表线程
CompletableFuture<PageBean<BookCommentVO>> bookCommentPageBeanCompletableFuture = CompletableFuture.supplyAsync(() -> {
PageBean<BookCommentVO> bookCommentVOPageBean = bookService.listCommentByPage(null, bookId, 1, 5);
log.debug("加载小说评论列表线程结束");
return bookCommentVOPageBean;
}, threadPoolExecutor);
//加载小说首章信息线程,该线程在加载小说基本信息线程执行完毕后才执行
CompletableFuture<Long> firstBookIndexIdCompletableFuture = bookCompletableFuture.thenApplyAsync((book) -> {
if (book.getLastIndexId() != null) {
//查询首章目录ID
Long firstBookIndexId = bookService.queryFirstBookIndexId(bookId);
log.debug("加载小说基本信息线程结束");
return firstBookIndexId;
}
return null;
}, threadPoolExecutor);
//加载随机推荐小说线程,该线程在加载小说基本信息线程执行完毕后才执行
CompletableFuture<List<Book>> recBookCompletableFuture = bookCompletableFuture.thenApplyAsync((book) -> {
List<Book> books = bookService.listRecBookByCatId(book.getCatId());
log.debug("加载随机推荐小说线程结束");
return books;
}, threadPoolExecutor);
model.addAttribute("book", bookCompletableFuture.get());
model.addAttribute("firstBookIndexId", firstBookIndexIdCompletableFuture.get());
model.addAttribute("recBooks", recBookCompletableFuture.get());
model.addAttribute("bookCommentPageBean", bookCommentPageBeanCompletableFuture.get());
return ThreadLocalUtil.getTemplateDir() + "book/book_detail"; return ThreadLocalUtil.getTemplateDir() + "book/book_detail";
} }
@ -134,9 +177,7 @@ public class PageController extends BaseController {
*/ */
@SneakyThrows @SneakyThrows
@RequestMapping("/book/{bookId}/{bookIndexId}.html") @RequestMapping("/book/{bookId}/{bookIndexId}.html")
public String indexList(@PathVariable("bookId") Long bookId, @PathVariable("bookIndexId") Long bookIndexId, HttpServletRequest request, Model model) { public String bookContent(@PathVariable("bookId") Long bookId, @PathVariable("bookIndexId") Long bookIndexId, HttpServletRequest request, Model model) {
//加载小说基本信息线程 //加载小说基本信息线程
CompletableFuture<Book> bookCompletableFuture = CompletableFuture.supplyAsync(() -> { CompletableFuture<Book> bookCompletableFuture = CompletableFuture.supplyAsync(() -> {
//查询书籍 //查询书籍
@ -172,7 +213,7 @@ public class PageController extends BaseController {
//加载小说内容信息线程 //加载小说内容信息线程
CompletableFuture<BookContent> bookContentCompletableFuture = CompletableFuture.supplyAsync(() -> { CompletableFuture<BookContent> bookContentCompletableFuture = CompletableFuture.supplyAsync(() -> {
//查询内容 //查询内容
BookContent bookContent = bookService.queryBookContent(bookIndexId); BookContent bookContent = bookContentService.queryBookContent(bookId, bookIndexId);
log.debug("加载小说内容信息线程结束"); log.debug("加载小说内容信息线程结束");
return bookContent; return bookContent;
}, threadPoolExecutor); }, threadPoolExecutor);

View File

@ -5,7 +5,6 @@ import com.java2nb.novel.core.bean.PageBean;
import com.java2nb.novel.entity.Author; import com.java2nb.novel.entity.Author;
import com.java2nb.novel.entity.AuthorIncome; import com.java2nb.novel.entity.AuthorIncome;
import com.java2nb.novel.entity.AuthorIncomeDetail; import com.java2nb.novel.entity.AuthorIncomeDetail;
import com.java2nb.novel.entity.FriendLink;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;

View File

@ -0,0 +1,11 @@
package com.java2nb.novel.service;
import com.java2nb.novel.entity.BookContent;
import java.util.List;
public interface BookContentService {
BookContent queryBookContent(Long bookId, Long bookIndexId);
}

View File

@ -1,12 +1,11 @@
package com.java2nb.novel.service; package com.java2nb.novel.service;
import com.github.pagehelper.PageInfo;
import com.java2nb.novel.core.bean.PageBean; import com.java2nb.novel.core.bean.PageBean;
import com.java2nb.novel.vo.BookSpVO; import com.java2nb.novel.entity.*;
import com.java2nb.novel.vo.BookCommentVO; import com.java2nb.novel.vo.BookCommentVO;
import com.java2nb.novel.vo.BookSettingVO; import com.java2nb.novel.vo.BookSettingVO;
import com.java2nb.novel.entity.*; import com.java2nb.novel.vo.BookSpVO;
import com.java2nb.novel.vo.BookVO; import com.java2nb.novel.vo.BookVO;
import java.util.Date; import java.util.Date;
@ -32,7 +31,7 @@ public interface BookService {
/** /**
* 查询首页新书榜单数据 * 查询首页新书榜单数据
* @return * @return 小说列表
* */ * */
List<Book> listNewRank(); List<Book> listNewRank();
@ -49,7 +48,7 @@ public interface BookService {
* @param pageSize 分页大小 * @param pageSize 分页大小
* @return 小说集合分页信息 * @return 小说集合分页信息
* */ * */
PageBean searchByPage(BookSpVO params, int page, int pageSize); PageBean<?> searchByPage(BookSpVO params, int page, int pageSize);
/** /**
* 查询小说分类列表 * 查询小说分类列表
@ -102,6 +101,7 @@ public interface BookService {
* @param bookIndexId 目录ID * @param bookIndexId 目录ID
* @return 书籍内容 * @return 书籍内容
* */ * */
@Deprecated
BookContent queryBookContent(Long bookIndexId); BookContent queryBookContent(Long bookIndexId);
/** /**
@ -115,7 +115,8 @@ public interface BookService {
/** /**
* 增加点击次数 * 增加点击次数
* @param bookId 书籍ID * @param bookId 书籍ID
* @param visitCount*/ * @param visitCount 点击量
* */
void addVisitCount(Long bookId, Integer visitCount); void addVisitCount(Long bookId, Integer visitCount);
/** /**
@ -162,6 +163,7 @@ public interface BookService {
* @param workDirection 作品方向 * @param workDirection 作品方向
* @return 作者ID * @return 作者ID
* */ * */
@Deprecated
Long getOrCreateAuthorIdByName(String authorName, Byte workDirection); Long getOrCreateAuthorIdByName(String authorName, Byte workDirection);
@ -179,6 +181,7 @@ public interface BookService {
* @param bookId 小说ID * @param bookId 小说ID
* @return 目录号集合 * @return 目录号集合
* */ * */
@Deprecated
List<Integer> queryIndexNumByBookId(Long bookId); List<Integer> queryIndexNumByBookId(Long bookId);
/** /**

View File

@ -32,4 +32,10 @@ public interface NewsService {
* @return 新闻分页数据 * @return 新闻分页数据
* */ * */
PageBean<News> listByPage(int page, int pageSize); PageBean<News> listByPage(int page, int pageSize);
/**
* 增加新闻阅读量
* @param newsId 新闻ID
* */
void addReadCount(Integer newsId);
} }

View File

@ -2,24 +2,26 @@ package com.java2nb.novel.service.impl;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.pagehelper.PageHelper; import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.java2nb.novel.core.bean.PageBean; import com.java2nb.novel.core.bean.PageBean;
import com.java2nb.novel.core.cache.CacheKey; import com.java2nb.novel.core.cache.CacheKey;
import com.java2nb.novel.core.cache.CacheService; import com.java2nb.novel.core.cache.CacheService;
import com.java2nb.novel.core.config.BookPriceProperties; import com.java2nb.novel.core.config.BookPriceProperties;
import com.java2nb.novel.core.enums.ResponseStatus; import com.java2nb.novel.core.enums.ResponseStatus;
import com.java2nb.novel.core.exception.BusinessException; import com.java2nb.novel.core.exception.BusinessException;
import com.java2nb.novel.core.utils.*; import com.java2nb.novel.core.utils.BeanUtil;
import com.java2nb.novel.entity.*; import com.java2nb.novel.core.utils.Constants;
import com.java2nb.novel.core.utils.IdWorker;
import com.java2nb.novel.core.utils.StringUtil;
import com.java2nb.novel.entity.Book; import com.java2nb.novel.entity.Book;
import com.java2nb.novel.entity.*;
import com.java2nb.novel.mapper.*; import com.java2nb.novel.mapper.*;
import com.java2nb.novel.vo.BookSpVO;
import com.java2nb.novel.service.AuthorService; import com.java2nb.novel.service.AuthorService;
import com.java2nb.novel.service.BookService; import com.java2nb.novel.service.BookService;
import com.java2nb.novel.service.FileService; import com.java2nb.novel.service.FileService;
import com.java2nb.novel.service.SearchService; import com.java2nb.novel.service.SearchService;
import com.java2nb.novel.vo.BookCommentVO; import com.java2nb.novel.vo.BookCommentVO;
import com.java2nb.novel.vo.BookSettingVO; import com.java2nb.novel.vo.BookSettingVO;
import com.java2nb.novel.vo.BookSpVO;
import com.java2nb.novel.vo.BookVO; import com.java2nb.novel.vo.BookVO;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows; import lombok.SneakyThrows;
@ -27,7 +29,6 @@ import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.mybatis.dynamic.sql.SortSpecification; import org.mybatis.dynamic.sql.SortSpecification;
import org.mybatis.dynamic.sql.render.RenderingStrategies; import org.mybatis.dynamic.sql.render.RenderingStrategies;
import org.mybatis.dynamic.sql.render.RenderingStrategy;
import org.mybatis.dynamic.sql.select.render.SelectStatementProvider; import org.mybatis.dynamic.sql.select.render.SelectStatementProvider;
import org.springframework.beans.BeanUtils; import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
@ -36,6 +37,7 @@ import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.orderbyhelper.OrderByHelper; import tk.mybatis.orderbyhelper.OrderByHelper;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
@ -187,7 +189,7 @@ public class BookServiceImpl implements BookService {
} }
@Override @Override
public PageBean searchByPage(BookSpVO params, int page, int pageSize) { public PageBean<?> searchByPage(BookSpVO params, int page, int pageSize) {
if (params.getUpdatePeriod() != null) { if (params.getUpdatePeriod() != null) {
@ -214,7 +216,7 @@ public class BookServiceImpl implements BookService {
if (StringUtils.isNotBlank(params.getSort())) { if (StringUtils.isNotBlank(params.getSort())) {
OrderByHelper.orderBy(params.getSort() + " desc"); OrderByHelper.orderBy(params.getSort() + " desc");
} }
return new PageBean(bookMapper.searchByPage(params)); return new PageBean<>(bookMapper.searchByPage(params));
} }
@ -513,7 +515,6 @@ public class BookServiceImpl implements BookService {
//该作者发布过此书名的小说 //该作者发布过此书名的小说
throw new BusinessException(ResponseStatus.BOOKNAME_EXISTS); throw new BusinessException(ResponseStatus.BOOKNAME_EXISTS);
} }
;
book.setAuthorName(penName); book.setAuthorName(penName);
book.setAuthorId(authorId); book.setAuthorId(authorId);
book.setVisitCount(0L); book.setVisitCount(0L);
@ -566,7 +567,7 @@ public class BookServiceImpl implements BookService {
.render(RenderingStrategies.MYBATIS3)); .render(RenderingStrategies.MYBATIS3));
//计算价格 //计算价格
int bookPrice = new BigDecimal(wordCount).divide(bookPriceConfig.getWordCount()).multiply(bookPriceConfig.getValue()).intValue(); int bookPrice = new BigDecimal(wordCount).multiply(bookPriceConfig.getValue()).divide(bookPriceConfig.getWordCount(),0, RoundingMode.DOWN).intValue();
//更新小说目录表 //更新小说目录表
int indexNum = 0; int indexNum = 0;
@ -626,7 +627,7 @@ public class BookServiceImpl implements BookService {
List<BookIndex> bookIndices = bookIndexMapper.selectMany( List<BookIndex> bookIndices = bookIndexMapper.selectMany(
select(BookIndexDynamicSqlSupport.bookId, BookIndexDynamicSqlSupport.wordCount) select(BookIndexDynamicSqlSupport.bookId, BookIndexDynamicSqlSupport.wordCount)
.from(bookIndex) .from(bookIndex)
.where(BookIndexDynamicSqlSupport.id, isEqualTo(indexId)).build().render(RenderingStrategy.MYBATIS3)); .where(BookIndexDynamicSqlSupport.id, isEqualTo(indexId)).build().render(RenderingStrategies.MYBATIS3));
if (bookIndices.size() > 0) { if (bookIndices.size() > 0) {
BookIndex bookIndex = bookIndices.get(0); BookIndex bookIndex = bookIndices.get(0);
//获取小说ID //获取小说ID
@ -637,7 +638,7 @@ public class BookServiceImpl implements BookService {
.from(book) .from(book)
.where(id, isEqualTo(bookId)) .where(id, isEqualTo(bookId))
.build() .build()
.render(RenderingStrategy.MYBATIS3)); .render(RenderingStrategies.MYBATIS3));
if (books.size() > 0) { if (books.size() > 0) {
Book book = books.get(0); Book book = books.get(0);
int wordCount = book.getWordCount(); int wordCount = book.getWordCount();
@ -660,7 +661,7 @@ public class BookServiceImpl implements BookService {
.orderBy(BookIndexDynamicSqlSupport.indexNum.descending()) .orderBy(BookIndexDynamicSqlSupport.indexNum.descending())
.limit(1) .limit(1)
.build() .build()
.render(RenderingStrategy.MYBATIS3)); .render(RenderingStrategies.MYBATIS3));
if (lastBookIndices.size() > 0) { if (lastBookIndices.size() > 0) {
BookIndex lastBookIndex = lastBookIndices.get(0); BookIndex lastBookIndex = lastBookIndices.get(0);
lastIndexId = lastBookIndex.getId(); lastIndexId = lastBookIndex.getId();
@ -700,7 +701,7 @@ public class BookServiceImpl implements BookService {
List<BookIndex> bookIndices = bookIndexMapper.selectMany( List<BookIndex> bookIndices = bookIndexMapper.selectMany(
select(BookIndexDynamicSqlSupport.bookId, BookIndexDynamicSqlSupport.wordCount) select(BookIndexDynamicSqlSupport.bookId, BookIndexDynamicSqlSupport.wordCount)
.from(bookIndex) .from(bookIndex)
.where(BookIndexDynamicSqlSupport.id, isEqualTo(indexId)).build().render(RenderingStrategy.MYBATIS3)); .where(BookIndexDynamicSqlSupport.id, isEqualTo(indexId)).build().render(RenderingStrategies.MYBATIS3));
if (bookIndices.size() > 0) { if (bookIndices.size() > 0) {
BookIndex bookIndex = bookIndices.get(0); BookIndex bookIndex = bookIndices.get(0);
//获取小说ID //获取小说ID
@ -711,7 +712,7 @@ public class BookServiceImpl implements BookService {
.from(book) .from(book)
.where(id, isEqualTo(bookId)) .where(id, isEqualTo(bookId))
.build() .build()
.render(RenderingStrategy.MYBATIS3)); .render(RenderingStrategies.MYBATIS3));
if (books.size() > 0) { if (books.size() > 0) {
Book book = books.get(0); Book book = books.get(0);
//作者ID相同表明该小说是登录用户发布可以修改 //作者ID相同表明该小说是登录用户发布可以修改
@ -725,7 +726,7 @@ public class BookServiceImpl implements BookService {
.equalTo(new Date()) .equalTo(new Date())
.where(BookIndexDynamicSqlSupport.id, isEqualTo(indexId)) .where(BookIndexDynamicSqlSupport.id, isEqualTo(indexId))
.build() .build()
.render(RenderingStrategy.MYBATIS3)); .render(RenderingStrategies.MYBATIS3));
} }
@ -741,7 +742,7 @@ public class BookServiceImpl implements BookService {
List<BookIndex> bookIndices = bookIndexMapper.selectMany( List<BookIndex> bookIndices = bookIndexMapper.selectMany(
select(BookIndexDynamicSqlSupport.bookId, BookIndexDynamicSqlSupport.wordCount) select(BookIndexDynamicSqlSupport.bookId, BookIndexDynamicSqlSupport.wordCount)
.from(bookIndex) .from(bookIndex)
.where(BookIndexDynamicSqlSupport.id, isEqualTo(indexId)).build().render(RenderingStrategy.MYBATIS3)); .where(BookIndexDynamicSqlSupport.id, isEqualTo(indexId)).build().render(RenderingStrategies.MYBATIS3));
if (bookIndices.size() > 0) { if (bookIndices.size() > 0) {
BookIndex bookIndex = bookIndices.get(0); BookIndex bookIndex = bookIndices.get(0);
//获取小说ID //获取小说ID
@ -752,7 +753,7 @@ public class BookServiceImpl implements BookService {
.from(book) .from(book)
.where(id, isEqualTo(bookId)) .where(id, isEqualTo(bookId))
.build() .build()
.render(RenderingStrategy.MYBATIS3)); .render(RenderingStrategies.MYBATIS3));
if (books.size() > 0) { if (books.size() > 0) {
Book book = books.get(0); Book book = books.get(0);
//作者ID相同表明该小说是登录用户发布 //作者ID相同表明该小说是登录用户发布
@ -762,7 +763,7 @@ public class BookServiceImpl implements BookService {
.from(bookContent) .from(bookContent)
.where(BookContentDynamicSqlSupport.indexId, isEqualTo(indexId)) .where(BookContentDynamicSqlSupport.indexId, isEqualTo(indexId))
.limit(1) .limit(1)
.build().render(RenderingStrategy.MYBATIS3)) .build().render(RenderingStrategies.MYBATIS3))
.get(0).getContent(); .get(0).getContent();
} }
@ -779,7 +780,7 @@ public class BookServiceImpl implements BookService {
List<BookIndex> bookIndices = bookIndexMapper.selectMany( List<BookIndex> bookIndices = bookIndexMapper.selectMany(
select(BookIndexDynamicSqlSupport.bookId, BookIndexDynamicSqlSupport.wordCount) select(BookIndexDynamicSqlSupport.bookId, BookIndexDynamicSqlSupport.wordCount)
.from(bookIndex) .from(bookIndex)
.where(BookIndexDynamicSqlSupport.id, isEqualTo(indexId)).build().render(RenderingStrategy.MYBATIS3)); .where(BookIndexDynamicSqlSupport.id, isEqualTo(indexId)).build().render(RenderingStrategies.MYBATIS3));
if (bookIndices.size() > 0) { if (bookIndices.size() > 0) {
BookIndex bookIndex = bookIndices.get(0); BookIndex bookIndex = bookIndices.get(0);
//获取小说ID //获取小说ID
@ -790,7 +791,7 @@ public class BookServiceImpl implements BookService {
.from(book) .from(book)
.where(id, isEqualTo(bookId)) .where(id, isEqualTo(bookId))
.build() .build()
.render(RenderingStrategy.MYBATIS3)); .render(RenderingStrategies.MYBATIS3));
if (books.size() > 0) { if (books.size() > 0) {
Book book = books.get(0); Book book = books.get(0);
//作者ID相同表明该小说是登录用户发布可以修改 //作者ID相同表明该小说是登录用户发布可以修改
@ -799,11 +800,11 @@ public class BookServiceImpl implements BookService {
int wordCount = StringUtil.getStrValidWordCount(content); int wordCount = StringUtil.getStrValidWordCount(content);
//计算价格 //计算价格
int bookPrice = new BigDecimal(wordCount).divide(bookPriceConfig.getWordCount()).multiply(bookPriceConfig.getValue()).intValue(); int bookPrice = new BigDecimal(wordCount).multiply(bookPriceConfig.getValue()).divide(bookPriceConfig.getWordCount(),0,RoundingMode.DOWN).intValue();
//更新小说目录表 //更新小说目录表
int update = bookIndexMapper.update( bookIndexMapper.update(
update(BookIndexDynamicSqlSupport.bookIndex) update(BookIndexDynamicSqlSupport.bookIndex)
.set(BookIndexDynamicSqlSupport.indexName) .set(BookIndexDynamicSqlSupport.indexName)
.equalTo(indexName) .equalTo(indexName)
@ -814,7 +815,7 @@ public class BookServiceImpl implements BookService {
.set(BookIndexDynamicSqlSupport.updateTime) .set(BookIndexDynamicSqlSupport.updateTime)
.equalTo(currentDate) .equalTo(currentDate)
.where(BookIndexDynamicSqlSupport.id, isEqualTo(indexId)) .where(BookIndexDynamicSqlSupport.id, isEqualTo(indexId))
.build().render(RenderingStrategy.MYBATIS3)); .build().render(RenderingStrategies.MYBATIS3));
//更新小说内容表 //更新小说内容表
bookContentMapper.update( bookContentMapper.update(
@ -822,7 +823,7 @@ public class BookServiceImpl implements BookService {
.set(BookContentDynamicSqlSupport.content) .set(BookContentDynamicSqlSupport.content)
.equalTo(content) .equalTo(content)
.where(BookContentDynamicSqlSupport.indexId, isEqualTo(indexId)) .where(BookContentDynamicSqlSupport.indexId, isEqualTo(indexId))
.build().render(RenderingStrategy.MYBATIS3)); .build().render(RenderingStrategies.MYBATIS3));
} }
} }

View File

@ -0,0 +1,38 @@
package com.java2nb.novel.service.impl;
import com.java2nb.novel.entity.BookContent;
import com.java2nb.novel.mapper.BookContentDynamicSqlSupport;
import com.java2nb.novel.mapper.BookContentMapper;
import com.java2nb.novel.service.BookContentService;
import lombok.RequiredArgsConstructor;
import org.mybatis.dynamic.sql.render.RenderingStrategies;
import org.mybatis.dynamic.sql.select.render.SelectStatementProvider;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Service;
import java.util.List;
import static com.java2nb.novel.mapper.BookContentDynamicSqlSupport.bookContent;
import static org.mybatis.dynamic.sql.SqlBuilder.isEqualTo;
import static org.mybatis.dynamic.sql.SqlBuilder.update;
import static org.mybatis.dynamic.sql.select.SelectDSL.select;
@Service
@RequiredArgsConstructor
@ConditionalOnProperty(prefix = "txt.save", name = "storage", havingValue = "db")
public class DbBookContentServiceImpl implements BookContentService {
private final BookContentMapper bookContentMapper;
@Override
public BookContent queryBookContent(Long bookId, Long bookIndexId) {
SelectStatementProvider selectStatement = select(BookContentDynamicSqlSupport.id, BookContentDynamicSqlSupport.content)
.from(bookContent)
.where(BookContentDynamicSqlSupport.indexId, isEqualTo(bookIndexId))
.limit(1)
.build()
.render(RenderingStrategies.MYBATIS3);
return bookContentMapper.selectMany(selectStatement).get(0);
}
}

View File

@ -0,0 +1,39 @@
package com.java2nb.novel.service.impl;
import com.java2nb.novel.core.utils.FileUtil;
import com.java2nb.novel.entity.BookContent;
import com.java2nb.novel.service.BookContentService;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Service;
import java.io.BufferedReader;
import java.io.FileReader;
import java.util.List;
@Service
@RequiredArgsConstructor
@ConditionalOnProperty(prefix = "txt.save", name = "storage", havingValue = "file")
public class FileBookContentServiceImpl implements BookContentService {
@Value("${txt.save.path}")
private String fileSavePath;
@SneakyThrows
@Override
public BookContent queryBookContent(Long bookId, Long bookIndexId) {
BufferedReader in = new BufferedReader(new FileReader(fileSavePath + "/" + bookId + "/" + bookIndexId + ".txt"));
StringBuffer sb = new StringBuffer();
String str;
while ((str = in.readLine()) != null) {
sb.append(str);
}
in.close();
return new BookContent() {{
setIndexId(bookIndexId);
setContent(sb.toString());
}};
}
}

View File

@ -3,6 +3,7 @@ package com.java2nb.novel.service.impl;
import com.github.pagehelper.PageHelper; import com.github.pagehelper.PageHelper;
import com.java2nb.novel.core.bean.PageBean; import com.java2nb.novel.core.bean.PageBean;
import com.java2nb.novel.core.utils.BeanUtil; import com.java2nb.novel.core.utils.BeanUtil;
import com.java2nb.novel.mapper.FrontNewsMapper;
import com.java2nb.novel.service.NewsService; import com.java2nb.novel.service.NewsService;
import com.java2nb.novel.core.cache.CacheKey; import com.java2nb.novel.core.cache.CacheKey;
import com.java2nb.novel.core.cache.CacheService; import com.java2nb.novel.core.cache.CacheService;
@ -27,7 +28,7 @@ import static org.mybatis.dynamic.sql.select.SelectDSL.select;
@RequiredArgsConstructor @RequiredArgsConstructor
public class NewsServiceImpl implements NewsService { public class NewsServiceImpl implements NewsService {
private final NewsMapper newsMapper; private final FrontNewsMapper newsMapper;
private final CacheService cacheService; private final CacheService cacheService;
@ -72,4 +73,9 @@ public class NewsServiceImpl implements NewsService {
pageBean.setList(BeanUtil.copyList(news,NewsVO.class)); pageBean.setList(BeanUtil.copyList(news,NewsVO.class));
return pageBean; return pageBean;
} }
@Override
public void addReadCount(Integer newsId) {
newsMapper.addReadCount(newsId);
}
} }

View File

@ -1,6 +1,8 @@
package com.java2nb.novel.vo; package com.java2nb.novel.vo;
import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.java2nb.novel.core.serialize.CommentUserNameSerialize;
import com.java2nb.novel.entity.BookComment; import com.java2nb.novel.entity.BookComment;
import lombok.Data; import lombok.Data;
@ -13,6 +15,7 @@ import java.util.Date;
@Data @Data
public class BookCommentVO extends BookComment { public class BookCommentVO extends BookComment {
@JsonSerialize(using = CommentUserNameSerialize.class)
private String createUserName; private String createUserName;
private String createUserPhoto; private String createUserPhoto;

View File

@ -48,7 +48,7 @@ xss:
# 排除链接多个用逗号分隔 # 排除链接多个用逗号分隔
excludes: /system/notice/* excludes: /system/notice/*
# 匹配链接 多个用逗号分隔 # 匹配链接 多个用逗号分隔
urlPatterns: /book/addBookComment,/user/addFeedBack,/author/addBook,/author/addBookContent,/author/register.html urlPatterns: /book/addBookComment,/user/addFeedBack,/author/addBook,/author/addBookContent,/author/updateBookContent,/author/register.html
author: author:

View File

@ -0,0 +1,9 @@
<?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="com.java2nb.novel.mapper.FrontNewsMapper">
<update id="addReadCount">
update news set read_count = read_count + 1
where id = #{newsId}
</update>
</mapper>

View File

@ -18,6 +18,7 @@
.news_title h2 { font-size: 20px; } .news_title h2 { font-size: 20px; }
.news_title .from { color: #999; display: block; margin: 20px 0; } .news_title .from { color: #999; display: block; margin: 20px 0; }
.news_title .time { margin-left: 20px } .news_title .time { margin-left: 20px }
.news_title .click { margin-left: 40px }
.news_info { padding: 0 60px; line-height: 28px; font-size: 14px; min-height:400px } .news_info { padding: 0 60px; line-height: 28px; font-size: 14px; min-height:400px }
.news_info p { margin-bottom: 30px } .news_info p { margin-bottom: 30px }
.aboutBox h2 { font-size:16px; margin-bottom:15px } .aboutBox h2 { font-size:16px; margin-bottom:15px }

View File

@ -124,4 +124,36 @@ String.prototype.isNickName = function () {
function logout() { function logout() {
$.cookie('Authorization', null,{ path: '/' }); $.cookie('Authorization', null,{ path: '/' });
location.reload(); location.reload();
} }
function isImg(str) {
return !str.search("[.]+(jpg|jpeg|swf|gif|png|JPG|JPEG|SWF|GIF|PNG)$");
}
//校验图片上传
function checkPicUpload(file){
if(!isImg(file.value.substr(file.value.lastIndexOf(".")))){
layer.alert('只能上传图片格式的文件');
return false;
}
var fileSize = 0;
var isIE = /msie/i.test(navigator.userAgent) && !window.opera;
if (isIE && !file.files) {
var filePath = file.value;
var fileSystem = new ActiveXObject("Scripting.FileSystemfileect");
var file = fileSystem.GetFile (filePath);
fileSize = file.Size;
}else {
fileSize = file.files[0].size;
}
fileSize=Math.round(fileSize/1024*100)/100; //单位为KB
if(fileSize>=1024){
layer.alert('上传的图片大小不能超过1M');
return false;
}
return true;
}

View File

@ -3,16 +3,6 @@ var UserPay = {
czPayPalData: [[20, "10000屋币"], [50, "25000屋币"], [100, "50000屋币"], [80, "全站包年阅读"]], czPayPalData: [[20, "10000屋币"], [50, "25000屋币"], [100, "50000屋币"], [80, "全站包年阅读"]],
sendPay: function () { sendPay: function () {
$("#payform").submit(); $("#payform").submit();
},
GetPayState: function (payId) {
$.post("/api/book.aspx", { act: "getpaystatus", pid: payId }, function (data, textStatus) {
if (data == "1") {
location.href = '/pay/wx_return.aspx?out_trade_no=sc'+payId;
}
else {
setTimeout("UserPay.GetPayState("+payId+")",3000);
}
}, "html");
} }
} }
@ -46,20 +36,6 @@ $(function () {
$("#ulZFWXXJ").show(); $("#ulZFWXXJ").show();
} }
var postUrl = "";
switch (type)
{
case "1":
postUrl = "sendalipay.aspx";
break;
case "2":
postUrl = "sendwxpaynowqr.aspx";
break;
case "3":
postUrl = "sendpaypal.aspx";
break;
}
$("#payform").attr("action", postUrl);
}) })
$("#ulZFWX li").click(function () { $("#ulZFWX li").click(function () {

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 79 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 83 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 67 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 63 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 439 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Some files were not shown because too many files have changed in this diff Show More