mirror of
https://github.com/201206030/novel-plus.git
synced 2025-07-01 15:26:37 +00:00
Compare commits
75 Commits
release_3.
...
3.6.1
Author | SHA1 | Date | |
---|---|---|---|
6fc2df9b5a | |||
c45b81fbbf | |||
40a999f353 | |||
547bf00f46 | |||
d6849bc5a2 | |||
dc654086f3 | |||
303cc2051f | |||
fe90345f0b | |||
7ac4b62840 | |||
029cce959b | |||
7395cf63e5 | |||
906e7762c9 | |||
465e03a17b | |||
2a69a28a0c | |||
c1eb7b8954 | |||
16e381f384 | |||
094ac95428 | |||
96662fcb17 | |||
fecf03b3f5 | |||
e7f702ece0 | |||
b2c67c4f15 | |||
6a385877ac | |||
7cde6ebf61 | |||
78969f9fd1 | |||
b2eb6686e9 | |||
c537f6fb20 | |||
16e4c98a45 | |||
776083076c | |||
2bf945fe0e | |||
ede7aca66d | |||
396452b46e | |||
fc2ea40c6a | |||
bfe4d938fd | |||
7f4728191a | |||
80b393fdda | |||
e7897c988a | |||
750c8dee02 | |||
cbfd0b049f | |||
7f0331e095 | |||
3520200a87 | |||
4939bcf418 | |||
1cffbae495 | |||
b99b6ae4f2 | |||
2e2a58c84b | |||
4fe36a8f4f | |||
b5df86d5c7 | |||
9b3ba1d8c1 | |||
c4db754d23 | |||
8d3ce53dba | |||
d32d9d8410 | |||
05ae012e05 | |||
b60a0c9b40 | |||
3efaf8ce5f | |||
ebc4210774 | |||
655ec90906 | |||
f28dd867ef | |||
8e6842a495 | |||
928cb2417f | |||
625694ba1e | |||
d6c0337c09 | |||
689efc0807 | |||
4540c3781e | |||
9d2c453bb0 | |||
9de47ce697 | |||
c79974ff77 | |||
fb0098aef8 | |||
e83494cb17 | |||
419d7a971b | |||
83eda2a44d | |||
3182029bdd | |||
19d4a9960d | |||
2603150b33 | |||
f5e440390b | |||
91e525ec8e | |||
83afb9e6e2 |
1
.gitignore
vendored
1
.gitignore
vendored
@ -3,4 +3,5 @@
|
||||
**/cachedata
|
||||
**/target
|
||||
**/*.iml
|
||||
**/.DS_Store
|
||||
|
||||
|
212
README.md
212
README.md
@ -1,6 +1,4 @@
|
||||
[]( https://cloud.tencent.com/act/cps/redirect?redirect=1052&cps_key=736e609d66e0ac4e57813316cec6fd0b&from=console )
|
||||
|
||||
# 小说精品屋-plus
|
||||
[]( https://curl.qcloud.com/kgMaOjoq )
|
||||
|
||||
[](https://github.com/201206030/novel-plus)
|
||||
[](https://github.com/201206030/novel-plus)
|
||||
@ -9,41 +7,25 @@
|
||||
|
||||
#### 官网
|
||||
|
||||
https://xiongxyang.gitee.io
|
||||
https://201206030.github.io
|
||||
|
||||
#### 新项目:小说精品屋-微服务版
|
||||
#### 学习版
|
||||
|
||||
基于小说精品屋-plus构建的Spring Cloud 微服务小说门户平台。
|
||||
[基于 Spring Boot 3 + Vue 3 开发的前后端分离学习型小说项目。](https://github.com/201206030/novel)
|
||||
|
||||
GitHub仓库地址: https://github.com/201206030/novel-cloud
|
||||
#### 微服务版
|
||||
|
||||
Gitee仓库地址: https://gitee.com/novel_dev_team/novel-cloud
|
||||
[Github](https://github.com/201206030/novel-cloud) | [码云](https://gitee.com/novel_dev_team/novel-cloud)
|
||||
|
||||
#### 演示地址
|
||||
|
||||
[点击前往](http://47.106.243.172:8888/)
|
||||
|
||||
|
||||
#### 项目介绍
|
||||
|
||||
小说精品屋-plus是在[小说精品屋](https://github.com/201206030/fiction_house)的基础上,去除了漫画和弹幕模块,专注于小说,是一个多端(PC、WAP)阅读、功能完善的原创文学CMS系统,由前台门户系统、作家后台管理系统、平台后台管理系统、爬虫管理系统等多个子系统构成,支持会员充值、订阅模式、新闻发布和实时统计报表等功能。
|
||||
|
||||
小说精品屋-plus重新进行了数据库设计、代码重构和功能增强,提升了程序整体的可读性和性能,增加了很多商用特性。主要升级如下:
|
||||
|
||||
- [x] 数据库重新设计,结构调整。
|
||||
- [x] 服务端代码重构,MyBatis3升级为MyBatis3DynamicSql。
|
||||
- [x] 移动站与PC站站点分离,浏览器自动识别跳转。
|
||||
- [x] PC站UI更新。
|
||||
- [x] 支持前端模版自定义,内置多套模版。
|
||||
- [x] 新闻模块。
|
||||
- [x] 排行榜。
|
||||
- [x] 小说评论模块。
|
||||
- [x] 阅读主题模块。
|
||||
- [x] 作家专区。
|
||||
- [x] 充值。
|
||||
- [x] 订阅。
|
||||
- [x] 后台管理系统。
|
||||
- [x] 爬虫管理系统。
|
||||
novel-plus 是一个多端(PC、WAP)阅读,功能完善的原创文学 CMS
|
||||
系统。由前台门户系统、作家后台管理系统、平台后台管理系统和爬虫管理系统等多个子系统构成,包括小说推荐、作品检索、小说排行、小说阅读、小说评论、会员中心、作家专区等功能,支持自定义多模版、可拓展的多种小说内容存储方式(内置数据库分表存储和
|
||||
TXT 文本存储)、阅读主题切换、多爬虫源自动采集和更新数据、会员充值、订阅模式、新闻发布和实时统计报表。
|
||||
|
||||
#### 项目结构
|
||||
|
||||
@ -58,42 +40,32 @@ novel-plus -- 父工程
|
||||
|
||||
#### 技术选型
|
||||
|
||||
| 技术 | 说明
|
||||
| -------------------- | ---------------------------
|
||||
| SpringBoot | Spring应用快速开发脚手架
|
||||
| MyBatis | 持久层ORM框架
|
||||
| MyBatis Dynamic SQL | Mybatis动态sql
|
||||
| PageHelper | MyBatis分页插件
|
||||
| MyBatisGenerator | 持久层代码生成插件
|
||||
| Sharding-Jdbc | 代码层分库分表中间件
|
||||
| JJWT | JWT登录支持
|
||||
| SpringSecurity | 安全框架
|
||||
| Shiro | 安全框架
|
||||
| Ehcache | Java进程内缓存框架(默认缓存)
|
||||
| Redis | 分布式缓存(缓存替换方案,默认关闭,一行配置开启)
|
||||
| ElasticSearch | 搜索引擎(搜索增强方案,默认关闭,一行配置开启)
|
||||
| RabbitMq | 消息队列(流量削峰,默认关闭,一行配置开启)
|
||||
| OSS | 阿里云对象存储服务(图片存储方式之一,一行配置即可切换)
|
||||
| FastDfs |开源轻量级分布式文件系统(图片存储方式之一,一行配置即可切换)
|
||||
| Redisson | 实现分布式锁
|
||||
| Lombok | 简化对象封装工具
|
||||
| Docker | 应用容器引擎
|
||||
| Mysql | 数据库服务
|
||||
| Thymeleaf | 模板引擎
|
||||
| Layui | 前端UI
|
||||
|
||||
|
||||
#### 开发工具
|
||||
感谢Jetbrains公司提供的免费License。
|
||||
|
||||
[]( https://www.jetbrains.com/?from=小说精品屋)
|
||||
|
||||
|
||||
#### 接口文档
|
||||
|
||||
[点击查看接口文档示例](doc/api/api.md)
|
||||
| 技术 | 说明
|
||||
|---------------------| ---------------------------
|
||||
| Spring Boot | Spring 应用快速开发脚手架
|
||||
| MyBatis | 持久层 ORM 框架
|
||||
| MyBatis Dynamic SQL | Mybatis 动态 sql
|
||||
| PageHelper | MyBatis 分页插件
|
||||
| MyBatisGenerator | 持久层代码生成插件
|
||||
| Sharding-Jdbc | 代码层分库分表中间件
|
||||
| JJWT | JWT 登录支持
|
||||
| SpringSecurity | 安全框架
|
||||
| Shiro | 安全框架
|
||||
| Ehcache | Java 进程内缓存框架(默认缓存)
|
||||
| Redis | 分布式缓存(缓存替换方案,默认关闭,一行配置开启)
|
||||
| Elasticsearch | 搜索引擎(搜索增强方案,默认关闭,一行配置开启)
|
||||
| RabbitMQ | 消息队列(流量削峰,默认关闭,一行配置开启)
|
||||
| Aliyun OSS | 阿里云对象存储服务(图片存储方式之一,一行配置即可切换)
|
||||
| FastDFS | 开源轻量级分布式文件系统(图片存储方式之一,一行配置即可切换)
|
||||
| Redisson | 实现分布式锁
|
||||
| Lombok | 简化对象封装工具
|
||||
| Docker | 应用容器引擎
|
||||
| MySQL | 数据库服务
|
||||
| Thymeleaf | 模板引擎
|
||||
| Layui | 前端 UI 框架
|
||||
|
||||
#### 橙色主题模版截图
|
||||
|
||||
##### PC站截图
|
||||
|
||||
1. 首页
|
||||
@ -183,6 +155,7 @@ novel-plus -- 父工程
|
||||

|
||||
|
||||
#### 深色主题模版截图
|
||||
|
||||
##### PC站截图
|
||||
|
||||
1. 首页
|
||||
@ -190,6 +163,7 @@ novel-plus -- 父工程
|
||||

|
||||
|
||||
##### 手机站截图
|
||||
|
||||
1. 首页
|
||||
|
||||

|
||||
@ -208,88 +182,81 @@ novel-plus -- 父工程
|
||||
|
||||
#### 蓝色主题模版截图(更新中)
|
||||
|
||||

|
||||

|
||||
|
||||
#### 安装步骤(源码,小白请看其他安装教程)
|
||||
#### 源码安装教程
|
||||
|
||||
##### 数据库安装:
|
||||
- JDK 安装
|
||||
|
||||
1. 安装MySQL软件。
|
||||
2. 修改MySQL`max_allowed_packet `配置(建议100M)。
|
||||
3. 新建数据库,设置编码为utf8mb4。
|
||||
4. 执行doc/sql/novel_plus.sql脚本文件。
|
||||
建议[安装 JDK 8](https://docs.oracle.com/javase/8/docs/technotes/guides/install/linux_jdk.html)
|
||||
|
||||
##### 爬虫管理系统安装:
|
||||
- MySQL 安装:
|
||||
|
||||
1. 修改novel-common模块下application-common-dev.yml(dev环境,默认环境)或application-common-prod.yml(prod环境,需要在application.yml配置文件中切换)配置文件中的数据库配置。
|
||||
2. 修改novel-crawl模块下application.yml文件中的管理员账号密码。
|
||||
3. 启动程序,打开浏览器,默认8081端口访问。
|
||||
4. 选择已有或新增爬虫源(支持自定义爬虫规则),点击`开启`按钮,开始爬取小说数据。
|
||||
1. [安装 MySQL 服务](https://dev.mysql.com/doc/refman/8.0/en/linux-installation.html)
|
||||
2. 修改 MySQL`max_allowed_packet `配置(建议 100 M)
|
||||
3. 新建数据库,设置编码为 utf8mb4
|
||||
4. 执行 doc/sql/novel_plus.sql 脚本文件
|
||||
|
||||
##### 前台小说门户安装(dev环境跳过3、4步骤):
|
||||
- Maven 安装
|
||||
|
||||
1. 修改novel-common模块下application-common-dev.yml(dev环境,默认环境)或application-common-prod.yml(prod环境,需要在application.yml配置文件中切换)配置文件中的数据库配置。
|
||||
[安装 Apache Maven](https://maven.apache.org/install.html)
|
||||
|
||||
2. 修改novel-front模块下application-website配置文件中的网站信息。
|
||||
- 源码打包
|
||||
|
||||
```
|
||||
#网站配置
|
||||
website:
|
||||
#网站名
|
||||
name: 小说精品屋
|
||||
#域名
|
||||
domain: xiongxyang.gitee.io
|
||||
#SEO关键词
|
||||
keyword: ${website.name},小说,小说CMS,原创文学系统,开源小说系统,免费小说建站程序
|
||||
#SEO描述
|
||||
description: ${website.name}是一个多端(PC、WAP)阅读、功能完善的原创文学CMS系统,由前台门户系统、作家后台管理系统、平台后台管理系统、爬虫管理系统等多个子系统构成,支持会员充值、订阅模式、新闻发布和实时统计报表等功能,新书自动入库,老书自动更新。
|
||||
#联系QQ
|
||||
qq: 1179705413
|
||||
```
|
||||
novel-plus 根目录下执行打包命令`mvn clean package -Dmaven.test.skip`
|
||||
|
||||
3. prod环境下需要修改novel-front模块下application-prod.yml配置文件中的模版名为你需要使用的模版名(templates文件夹下的模版文件夹名,内置orange和dark两套模版,prod环境下才支持多模版)。
|
||||
- 爬虫安装
|
||||
|
||||
```
|
||||
#模版配置
|
||||
templates:
|
||||
#模版名
|
||||
name: orange
|
||||
```
|
||||
1. 上传 novel-crawl/target/build/novel-crawl.zip 压缩包到 Linux 服务器的 novel-crawl 目录
|
||||
2. 使用`unzip novel-crawl.zip`命令解压 novel-crawl.zip
|
||||
3. 修改 `config/application-common-prod.yml` 文件中的数据库配置
|
||||
4. 修改 `config/application-common-prod.yml` 文件中的管理员账号密码
|
||||
5. novel-crawl 目录下使用`bin/novel-crawl.sh start`命令启动爬虫程序
|
||||
6. 打开浏览器,默认`8083`端口访问
|
||||
7. 选择已有或新增爬虫源(支持自定义爬虫规则),点击`开启`按钮,开始采集小说数据
|
||||
8. novel-crawl 目录下使用`bin/novel-crawl.sh stop`命令停止爬虫程序
|
||||
9. novel-crawl 目录下使用`bin/novel-crawl.sh restart`命令重启爬虫程序
|
||||
10. novel-crawl 目录下使用`bin/novel-crawl.sh status`命令查看爬虫程序的运行状态
|
||||
|
||||
4. prod环境下的jar包形式部署时,需要复制templates文件夹到jar文件的相同目录下。
|
||||
- 前台安装
|
||||
|
||||
5. 启动程序,打开浏览器,默认8080端口访问。
|
||||
1. 上传 novel-front/target/build/novel-front.zip 压缩包到 Linux 服务器的 novel-front 目录
|
||||
2. 使用`unzip novel-front.zip`命令解压 novel-front.zip
|
||||
3. 修改 `config/application-common-prod.yml` 文件中的数据库配置
|
||||
4. 修改 `config/application-website.yml` 配置文件中的网站信息
|
||||
5. novel-front 目录下使用`bin/novel-front.sh start`命令启动前台程序
|
||||
6. 打开浏览器,默认`8085`端口访问
|
||||
7. novel-front 目录下使用`bin/novel-front.sh stop`命令停止前台程序
|
||||
8. novel-front 目录下使用`bin/novel-front.sh restart`命令重启前台程序
|
||||
9. novel-front 目录下使用`bin/novel-front.sh status`命令查看前台程序的运行状态
|
||||
|
||||
**喜欢此项目的可以给我的GitHub和Gitee加个Star支持一下 。**
|
||||
- 后台安装
|
||||
|
||||
#### 其他安装教程
|
||||
1. 上传 novel-admin/target/build/novel-admin.zip 压缩包到 Linux 服务器的 novel-admin 目录
|
||||
2. 使用`unzip novel-admin.zip`命令解压 novel-admin.zip
|
||||
3. 修改 `config/application-prod.yml` 文件中的数据库配置
|
||||
4. novel-admin 目录下使用`bin/novel-admin.sh start`命令启动后台程序
|
||||
5. 打开浏览器,默认`8088`端口访问
|
||||
6. novel-admin 目录下使用`bin/novel-admin.sh stop`命令停止后台程序
|
||||
7. novel-admin 目录下使用`bin/novel-admin.sh restart`命令重启后台程序
|
||||
8. novel-admin 目录下使用`bin/novel-admin.sh status`命令查看后台程序的运行状态
|
||||
|
||||
##### version>=3.5.0版本
|
||||
|
||||
包安装及低版本升级教程:[点击前往](https://my.oschina.net/java2nb/blog/4914688)
|
||||
|
||||
##### 3.3.0<=version<3.5.0版本
|
||||
|
||||
包安装教程:[点击前往](https://my.oschina.net/java2nb/blog/4842472)
|
||||
|
||||
##### version<3.3.0版本
|
||||
|
||||
包安装教程:[点击前往](https://my.oschina.net/java2nb/blog/4272630)
|
||||
|
||||
宝塔安装教程(非官方):[点击前往](https://www.daniao.org/9166.html)
|
||||
|
||||
docker安装教程:[点击前往](https://my.oschina.net/java2nb/blog/4271989)
|
||||
**注:部分环境(如新版 Mac OS 系统)获取不到主机 IP,需要手动修改 hosts 文件,增加 IP-主机名(通过 hostname 命令查看主机名)的映射。**
|
||||
|
||||
#### 代码仓库
|
||||
|
||||
GitHub仓库地址: https://github.com/201206030/novel-plus
|
||||
Github 仓库地址: https://github.com/201206030/novel-plus
|
||||
|
||||
Gitee仓库地址: https://gitee.com/novel_dev_team/novel-plus
|
||||
Gitee 仓库地址: https://gitee.com/novel_dev_team/novel-plus
|
||||
|
||||
#### QQ交流群
|
||||
#### QQ 交流群
|
||||
|
||||
[点击前往官网查看](https://xiongxyang.gitee.io/service.htm)
|
||||
|
||||
#### 微信交流群
|
||||
|
||||
微信群二维码会过期,所以每周在公众号更新一次,请关注公众号“**IT进阶**”回复关键词“**微信群**”获取。
|
||||
|
||||
问问题的三要素
|
||||
|
||||
1. 说明背景,使用了哪个模块,要做什么?
|
||||
@ -308,17 +275,14 @@ docker安装教程:[点击前往](https://my.oschina.net/java2nb/blog/4271989)
|
||||
|
||||
- 服务器的费用也是一笔开销
|
||||
- 为用户提供更好的开发环境
|
||||
- 一杯咖啡
|
||||
- 一杯咖啡
|
||||
|
||||

|
||||
|
||||
#### 免责声明
|
||||
|
||||
本项目提供的爬虫工具仅用于采集项目初期的测试数据,请勿用于商业盈利。
|
||||
用户使用本系统从事任何违法违规的事情,一切后果由用户自行承担,作者不承担任何责任。
|
||||
本项目提供的爬虫工具仅用于采集项目初期的测试数据,请勿用于商业盈利。 用户使用本系统从事任何违法违规的事情,一切后果由用户自行承担,作者不承担任何责任。
|
||||
|
||||
#### 备注
|
||||
|
||||
精品小说屋所有相关项目均已在开源中国公开,感兴趣的可进入[开源中国](https://www.oschina.net/p/fiction_house)按关键字`精品小说屋`搜索。
|
||||
|
||||
[](https://www.aliyun.com/minisite/goods?userCode=uf4nasee )
|
||||
|
1
doc/sql/20210726.sql
Normal file
1
doc/sql/20210726.sql
Normal file
@ -0,0 +1 @@
|
||||
alter table news add column `read_count` BIGINT NOT NULL DEFAULT '0' COMMENT '阅读量' after content;
|
3
doc/sql/20210913.sql
Normal file
3
doc/sql/20210913.sql
Normal file
@ -0,0 +1,3 @@
|
||||
alter table book_index add column storage_type varchar(10) NOT NULL DEFAULT 'db' COMMENT '存储方式' after book_price ;
|
||||
|
||||
|
@ -1836,4 +1836,11 @@ INSERT INTO `sys_role_menu`(`id`, `role_id`, `menu_id`) VALUES (4900, 1, 235);
|
||||
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');
|
||||
|
||||
alter table news add column `read_count` BIGINT NOT NULL DEFAULT '0' COMMENT '阅读量' after content;
|
||||
|
||||
|
||||
alter table book_index add column storage_type varchar(10) NOT NULL DEFAULT 'db' COMMENT '存储方式' after book_price ;
|
||||
|
@ -5,7 +5,7 @@
|
||||
|
||||
<groupId>com.java2nb</groupId>
|
||||
<artifactId>novel-admin</artifactId>
|
||||
<version>3.5.0</version>
|
||||
<version>3.6.1</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>novel-admin</name>
|
||||
@ -106,7 +106,7 @@
|
||||
<dependency>
|
||||
<groupId>org.apache.shiro</groupId>
|
||||
<artifactId>shiro-spring</artifactId>
|
||||
<version>1.3.2</version>
|
||||
<version>1.7.0</version>
|
||||
</dependency>
|
||||
<!-- shiro ehcache -->
|
||||
<dependency>
|
||||
@ -224,29 +224,73 @@
|
||||
<!--<scope>provided</scope>-->
|
||||
<!--</dependency>-->
|
||||
</dependencies>
|
||||
<!-- <build>
|
||||
<plugins>
|
||||
<!–<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<configuration>
|
||||
<executable>true</executable>
|
||||
</configuration>
|
||||
</plugin>–>
|
||||
<!–SpringBoot项目默认使用spring-boot-maven-plugin,要打成被其他项目引用的jar包,需要更换此插件–>
|
||||
<!– <plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<source>1.8</source>
|
||||
<target>1.8</target>
|
||||
<encoding>UTF-8</encoding>
|
||||
</configuration>
|
||||
</plugin>–>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>-->
|
||||
<build>
|
||||
<plugins>
|
||||
<!--<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<configuration>
|
||||
<executable>true</executable>
|
||||
</configuration>
|
||||
</plugin>-->
|
||||
<!--SpringBoot项目默认使用spring-boot-maven-plugin,要打成被其他项目引用的jar包,需要更换此插件-->
|
||||
<!-- <plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<source>1.8</source>
|
||||
<target>1.8</target>
|
||||
<encoding>UTF-8</encoding>
|
||||
</configuration>
|
||||
</plugin>-->
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-antrun-plugin</artifactId>
|
||||
<version>1.8</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>run</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<tasks>
|
||||
<!-- 文件夹 -->
|
||||
<copy todir="${project.build.directory}/build/config" overwrite="true">
|
||||
<fileset dir="${basedir}/src/main/build/config">
|
||||
<include name="*.*"/>
|
||||
</fileset>
|
||||
</copy>
|
||||
<copy file="${project.build.directory}/${project.artifactId}-${project.version}.jar"
|
||||
tofile="${project.build.directory}/build/${project.artifactId}.jar"/>
|
||||
|
||||
<fixcrlf srcdir="${basedir}/src/main/build/scripts" eol="unix"/>
|
||||
<copy todir="${project.build.directory}/build/bin">
|
||||
<fileset dir="${basedir}/src/main/build/scripts">
|
||||
<include name="*.sh"/>
|
||||
<include name="*.txt"/>
|
||||
<include name="*.bat"/>
|
||||
</fileset>
|
||||
</copy>
|
||||
<zip destfile='${project.build.directory}/build/${project.artifactId}.zip'>
|
||||
<zipfileset filemode="755" dir='${project.build.directory}/build/'/>
|
||||
</zip>
|
||||
</tasks>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<!--<distributionManagement>
|
||||
|
10
novel-admin/src/main/build/config/application-prod.yml
Normal file
10
novel-admin/src/main/build/config/application-prod.yml
Normal file
@ -0,0 +1,10 @@
|
||||
#端口号
|
||||
server:
|
||||
port: 8088
|
||||
spring:
|
||||
datasource:
|
||||
url: jdbc:mysql://127.0.0.1:3306/novel_plus?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai
|
||||
username: root
|
||||
password: test123456
|
||||
|
||||
|
94
novel-admin/src/main/build/scripts/novel-admin.sh
Normal file
94
novel-admin/src/main/build/scripts/novel-admin.sh
Normal file
@ -0,0 +1,94 @@
|
||||
#!/bin/sh
|
||||
APP_NAME=novel-admin
|
||||
JAR_NAME=$APP_NAME\.jar
|
||||
#PID 代表是PID文件
|
||||
PID=$APP_NAME\.pid
|
||||
|
||||
|
||||
#使用说明,用来提示输入参数
|
||||
usage() {
|
||||
echo "Usage: ./novel-admin.sh [start|stop|restart|status]"
|
||||
exit 1
|
||||
}
|
||||
|
||||
#检查程序是否在运行
|
||||
is_exist(){
|
||||
pid=`ps -ef|grep $JAR_NAME|grep -v grep|awk '{print $2}' `
|
||||
#如果不存在返回1,存在返回0
|
||||
if [ -z "${pid}" ]; then
|
||||
return 1
|
||||
else
|
||||
return 0
|
||||
fi
|
||||
}
|
||||
|
||||
#启动方法
|
||||
start(){
|
||||
is_exist
|
||||
if [ $? -eq "0" ]; then
|
||||
echo ">>> 小说精品屋后台正在运行 PID = ${pid} <<<"
|
||||
else
|
||||
echo ">>> 小说精品屋后台开始启动 <<<"
|
||||
nohup java -jar -Dspring.profiles.active=prod $JAR_NAME >/dev/null 2>&1 &
|
||||
sleep 20
|
||||
echo $! > $PID
|
||||
echo ">>> 小说精品屋后台启动完成 PID = $! <<<"
|
||||
status
|
||||
fi
|
||||
}
|
||||
|
||||
#停止方法
|
||||
stop(){
|
||||
#is_exist
|
||||
pidf=$(cat $PID)
|
||||
#echo "$pidf"
|
||||
echo ">>> 小说精品屋后台 PID = $pidf 开始停止 <<<"
|
||||
kill $pidf
|
||||
rm -rf $PID
|
||||
sleep 2
|
||||
is_exist
|
||||
if [ $? -eq "0" ]; then
|
||||
echo ">>> 小说精品屋后台 PID = $pid 开始强制停止 <<<"
|
||||
kill -9 $pid
|
||||
sleep 2
|
||||
status
|
||||
else
|
||||
status
|
||||
fi
|
||||
}
|
||||
|
||||
#输出运行状态
|
||||
status(){
|
||||
is_exist
|
||||
if [ $? -eq "0" ]; then
|
||||
echo ">>> 小说精品屋后台正在运行 PID = ${pid} <<<"
|
||||
else
|
||||
echo ">>> 小说精品屋后台没有运行 <<<"
|
||||
fi
|
||||
}
|
||||
|
||||
#重启
|
||||
restart(){
|
||||
stop
|
||||
start
|
||||
}
|
||||
|
||||
#根据输入参数,选择执行对应方法,不输入则执行使用说明
|
||||
case "$1" in
|
||||
"start")
|
||||
start
|
||||
;;
|
||||
"stop")
|
||||
stop
|
||||
;;
|
||||
"status")
|
||||
status
|
||||
;;
|
||||
"restart")
|
||||
restart
|
||||
;;
|
||||
*)
|
||||
usage
|
||||
;;
|
||||
esac
|
||||
exit 0
|
@ -1,12 +1,18 @@
|
||||
package com.java2nb;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.mybatis.spring.annotation.MapperScan;
|
||||
import org.springframework.boot.CommandLineRunner;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.web.servlet.ServletComponentScan;
|
||||
import org.springframework.cache.annotation.EnableCaching;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.transaction.annotation.EnableTransactionManagement;
|
||||
|
||||
import java.net.InetAddress;
|
||||
|
||||
|
||||
@EnableTransactionManagement
|
||||
@ServletComponentScan
|
||||
@ -15,9 +21,17 @@ import org.springframework.transaction.annotation.EnableTransactionManagement;
|
||||
org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration.class
|
||||
})
|
||||
@EnableCaching
|
||||
@Slf4j
|
||||
public class AdminApplication {
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(AdminApplication.class, args);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public CommandLineRunner commandLineRunner(ApplicationContext ctx) {
|
||||
return args -> {
|
||||
log.info("项目启动啦,访问路径:{}", "http://" + InetAddress.getLocalHost().getHostAddress() + ":" + ctx.getEnvironment().getProperty("server.port"));
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -75,7 +75,6 @@ public class ShiroConfig {
|
||||
filterChainDefinitionMap.put("/img/**", "anon");
|
||||
filterChainDefinitionMap.put("/docs/**", "anon");
|
||||
filterChainDefinitionMap.put("/layuimini/**", "anon");
|
||||
filterChainDefinitionMap.put("/druid/**", "anon");
|
||||
filterChainDefinitionMap.put("/upload/**", "anon");
|
||||
filterChainDefinitionMap.put("/files/**", "anon");
|
||||
filterChainDefinitionMap.put("/logout", "logout");
|
||||
|
@ -1,19 +1,17 @@
|
||||
package com.java2nb.novel.controller;
|
||||
|
||||
import com.java2nb.common.utils.DateUtils;
|
||||
import com.java2nb.common.utils.PageBean;
|
||||
import com.java2nb.common.utils.Query;
|
||||
import com.java2nb.common.utils.R;
|
||||
import com.java2nb.novel.domain.AuthorCodeDO;
|
||||
import com.java2nb.novel.service.*;
|
||||
import com.java2nb.test.service.OrderService;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import com.java2nb.novel.service.AuthorService;
|
||||
import com.java2nb.novel.service.BookService;
|
||||
import com.java2nb.novel.service.PayService;
|
||||
import com.java2nb.novel.service.UserService;
|
||||
import lombok.SneakyThrows;
|
||||
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
|
@ -1,135 +0,0 @@
|
||||
package com.java2nb.test.controller;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
|
||||
|
||||
import com.java2nb.test.domain.OrderDO;
|
||||
import com.java2nb.test.service.OrderService;
|
||||
import com.java2nb.common.utils.PageBean;
|
||||
import com.java2nb.common.utils.Query;
|
||||
import com.java2nb.common.utils.R;
|
||||
|
||||
/**
|
||||
* 付呗-订单信息表
|
||||
*
|
||||
* @author xiongxy
|
||||
* @email 1179705413@qq.com
|
||||
* @date 2019-11-25 11:57:16
|
||||
*/
|
||||
|
||||
@Controller
|
||||
@RequestMapping("/test/order")
|
||||
public class OrderController {
|
||||
@Autowired
|
||||
private OrderService orderService;
|
||||
|
||||
@GetMapping()
|
||||
@RequiresPermissions("test:order:order")
|
||||
String Order() {
|
||||
return "test/order/order";
|
||||
}
|
||||
|
||||
@ApiOperation(value = "获取付呗-订单信息表列表", notes = "获取付呗-订单信息表列表")
|
||||
@ResponseBody
|
||||
@GetMapping("/list")
|
||||
@RequiresPermissions("test:order:order")
|
||||
public R list(@RequestParam Map<String, Object> params) {
|
||||
//查询列表数据
|
||||
Query query = new Query(params);
|
||||
List<OrderDO> orderList = orderService.list(query);
|
||||
int total = orderService.count(query);
|
||||
PageBean pageBean = new PageBean(orderList, total);
|
||||
return R.ok().put("data", pageBean);
|
||||
}
|
||||
|
||||
@ApiOperation(value = "新增付呗-订单信息表页面", notes = "新增付呗-订单信息表页面")
|
||||
@GetMapping("/add")
|
||||
@RequiresPermissions("test:order:add")
|
||||
String add() {
|
||||
return "test/order/add";
|
||||
}
|
||||
|
||||
@ApiOperation(value = "修改付呗-订单信息表页面", notes = "修改付呗-订单信息表页面")
|
||||
@GetMapping("/edit/{id}")
|
||||
@RequiresPermissions("test:order:edit")
|
||||
String edit(@PathVariable("id") Long id, Model model) {
|
||||
OrderDO order = orderService.get(id);
|
||||
model.addAttribute("order", order);
|
||||
return "test/order/edit";
|
||||
}
|
||||
|
||||
@ApiOperation(value = "查看付呗-订单信息表页面", notes = "查看付呗-订单信息表页面")
|
||||
@GetMapping("/detail/{id}")
|
||||
@RequiresPermissions("test:order:detail")
|
||||
String detail(@PathVariable("id") Long id, Model model) {
|
||||
OrderDO order = orderService.get(id);
|
||||
model.addAttribute("order", order);
|
||||
return "test/order/detail";
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存
|
||||
*/
|
||||
@ApiOperation(value = "新增付呗-订单信息表", notes = "新增付呗-订单信息表")
|
||||
@ResponseBody
|
||||
@PostMapping("/save")
|
||||
@RequiresPermissions("test:order:add")
|
||||
public R save( OrderDO order) {
|
||||
if (orderService.save(order) > 0) {
|
||||
return R.ok();
|
||||
}
|
||||
return R.error();
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改
|
||||
*/
|
||||
@ApiOperation(value = "修改付呗-订单信息表", notes = "修改付呗-订单信息表")
|
||||
@ResponseBody
|
||||
@RequestMapping("/update")
|
||||
@RequiresPermissions("test:order:edit")
|
||||
public R update( OrderDO order) {
|
||||
orderService.update(order);
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除
|
||||
*/
|
||||
@ApiOperation(value = "删除付呗-订单信息表", notes = "删除付呗-订单信息表")
|
||||
@PostMapping("/remove")
|
||||
@ResponseBody
|
||||
@RequiresPermissions("test:order:remove")
|
||||
public R remove( Long id) {
|
||||
if (orderService.remove(id) > 0) {
|
||||
return R.ok();
|
||||
}
|
||||
return R.error();
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除
|
||||
*/
|
||||
@ApiOperation(value = "批量删除付呗-订单信息表", notes = "批量删除付呗-订单信息表")
|
||||
@PostMapping("/batchRemove")
|
||||
@ResponseBody
|
||||
@RequiresPermissions("test:order:batchRemove")
|
||||
public R remove(@RequestParam("ids[]") Long[] ids) {
|
||||
orderService.batchRemove(ids);
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
}
|
@ -1,32 +0,0 @@
|
||||
package com.java2nb.test.dao;
|
||||
|
||||
import com.java2nb.test.domain.OrderDO;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
/**
|
||||
* 付呗-订单信息表
|
||||
* @author xiongxy
|
||||
* @email 1179705413@qq.com
|
||||
* @date 2019-11-25 11:57:16
|
||||
*/
|
||||
@Mapper
|
||||
public interface OrderDao {
|
||||
|
||||
OrderDO get(Long id);
|
||||
|
||||
List<OrderDO> list(Map<String,Object> map);
|
||||
|
||||
int count(Map<String,Object> map);
|
||||
|
||||
int save(OrderDO order);
|
||||
|
||||
int update(OrderDO order);
|
||||
|
||||
int remove(Long id);
|
||||
|
||||
int batchRemove(Long[] ids);
|
||||
}
|
@ -1,475 +0,0 @@
|
||||
package com.java2nb.test.domain;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||
import com.java2nb.common.jsonserializer.LongToStringSerializer;
|
||||
|
||||
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
import java.util.Date;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 付呗-订单信息表
|
||||
*
|
||||
* @author xiongxy
|
||||
* @email 1179705413@qq.com
|
||||
* @date 2019-11-25 11:57:16
|
||||
*/
|
||||
public class OrderDO implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
|
||||
//主键
|
||||
//java中的long能表示的范围比js中number大,也就意味着部分数值在js中存不下(变成不准确的值)
|
||||
//所以通过序列化成字符串来解决
|
||||
@JsonSerialize(using = LongToStringSerializer.class)
|
||||
private Long id;
|
||||
//付呗商户号
|
||||
private String fbMerchantCode;
|
||||
//第三方商户的订单号
|
||||
private String merchantOrderSn;
|
||||
//付呗订单号
|
||||
private String orderSn;
|
||||
//平台方订单号
|
||||
private String platformOrderNo;
|
||||
//商户单号
|
||||
private String tradeNo;
|
||||
//订单状态,1:未支付,2:支付成功,3:支付失败,4:支付取消
|
||||
private Integer orderState;
|
||||
//蜂鸟优惠卷抵扣
|
||||
private Double fnCoupon;
|
||||
//红包抵扣
|
||||
private BigDecimal redPacket;
|
||||
//实收金额(元)
|
||||
private BigDecimal totalFee;
|
||||
//订单金额
|
||||
private BigDecimal orderPrice;
|
||||
//手续费(元)
|
||||
private BigDecimal fee;
|
||||
//对商品或交易的描述
|
||||
private String body;
|
||||
//附加数据
|
||||
private String attach;
|
||||
//付呗系统的门店id
|
||||
//java中的long能表示的范围比js中number大,也就意味着部分数值在js中存不下(变成不准确的值)
|
||||
//所以通过序列化成字符串来解决
|
||||
@JsonSerialize(using = LongToStringSerializer.class)
|
||||
private Long storeId;
|
||||
//付呗系统的收银员id
|
||||
//java中的long能表示的范围比js中number大,也就意味着部分数值在js中存不下(变成不准确的值)
|
||||
//所以通过序列化成字符串来解决
|
||||
@JsonSerialize(using = LongToStringSerializer.class)
|
||||
private Long cashierId;
|
||||
//设备终端号
|
||||
private String deviceNo;
|
||||
//微信顾客支付授权的“open_id”或者支付宝顾客的“buyer_user_id”
|
||||
private String userId;
|
||||
//支付宝顾客的账号
|
||||
private String userLogonId;
|
||||
//交易成功的时间
|
||||
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date payTime;
|
||||
//支付通道:1微信、2支付宝、3银联
|
||||
private Integer payChannel;
|
||||
//免充值代金券金额(元)
|
||||
private BigDecimal noCashCouponFee;
|
||||
//预充值代金券金额(元)
|
||||
private BigDecimal cashCouponFee;
|
||||
//顾客实际支付金额(元)
|
||||
private BigDecimal cashFee;
|
||||
//签名
|
||||
private String sign;
|
||||
//其它选项
|
||||
private String options;
|
||||
//创建时间
|
||||
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date createTime;
|
||||
//推送时间
|
||||
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date pushTime;
|
||||
//推送IP
|
||||
private String pushIp;
|
||||
//商户id
|
||||
private BigDecimal mchtId;
|
||||
//QR编号
|
||||
private String sn;
|
||||
|
||||
/**
|
||||
* 设置:主键
|
||||
*/
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
/**
|
||||
* 获取:主键
|
||||
*/
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
/**
|
||||
* 设置:付呗商户号
|
||||
*/
|
||||
public void setFbMerchantCode(String fbMerchantCode) {
|
||||
this.fbMerchantCode = fbMerchantCode;
|
||||
}
|
||||
/**
|
||||
* 获取:付呗商户号
|
||||
*/
|
||||
public String getFbMerchantCode() {
|
||||
return fbMerchantCode;
|
||||
}
|
||||
/**
|
||||
* 设置:第三方商户的订单号
|
||||
*/
|
||||
public void setMerchantOrderSn(String merchantOrderSn) {
|
||||
this.merchantOrderSn = merchantOrderSn;
|
||||
}
|
||||
/**
|
||||
* 获取:第三方商户的订单号
|
||||
*/
|
||||
public String getMerchantOrderSn() {
|
||||
return merchantOrderSn;
|
||||
}
|
||||
/**
|
||||
* 设置:付呗订单号
|
||||
*/
|
||||
public void setOrderSn(String orderSn) {
|
||||
this.orderSn = orderSn;
|
||||
}
|
||||
/**
|
||||
* 获取:付呗订单号
|
||||
*/
|
||||
public String getOrderSn() {
|
||||
return orderSn;
|
||||
}
|
||||
/**
|
||||
* 设置:平台方订单号
|
||||
*/
|
||||
public void setPlatformOrderNo(String platformOrderNo) {
|
||||
this.platformOrderNo = platformOrderNo;
|
||||
}
|
||||
/**
|
||||
* 获取:平台方订单号
|
||||
*/
|
||||
public String getPlatformOrderNo() {
|
||||
return platformOrderNo;
|
||||
}
|
||||
/**
|
||||
* 设置:商户单号
|
||||
*/
|
||||
public void setTradeNo(String tradeNo) {
|
||||
this.tradeNo = tradeNo;
|
||||
}
|
||||
/**
|
||||
* 获取:商户单号
|
||||
*/
|
||||
public String getTradeNo() {
|
||||
return tradeNo;
|
||||
}
|
||||
/**
|
||||
* 设置:订单状态,1:未支付,2:支付成功,3:支付失败,4:支付取消
|
||||
*/
|
||||
public void setOrderState(Integer orderState) {
|
||||
this.orderState = orderState;
|
||||
}
|
||||
/**
|
||||
* 获取:订单状态,1:未支付,2:支付成功,3:支付失败,4:支付取消
|
||||
*/
|
||||
public Integer getOrderState() {
|
||||
return orderState;
|
||||
}
|
||||
/**
|
||||
* 设置:蜂鸟优惠卷抵扣
|
||||
*/
|
||||
public void setFnCoupon(Double fnCoupon) {
|
||||
this.fnCoupon = fnCoupon;
|
||||
}
|
||||
/**
|
||||
* 获取:蜂鸟优惠卷抵扣
|
||||
*/
|
||||
public Double getFnCoupon() {
|
||||
return fnCoupon;
|
||||
}
|
||||
/**
|
||||
* 设置:红包抵扣
|
||||
*/
|
||||
public void setRedPacket(BigDecimal redPacket) {
|
||||
this.redPacket = redPacket;
|
||||
}
|
||||
/**
|
||||
* 获取:红包抵扣
|
||||
*/
|
||||
public BigDecimal getRedPacket() {
|
||||
return redPacket;
|
||||
}
|
||||
/**
|
||||
* 设置:实收金额(元)
|
||||
*/
|
||||
public void setTotalFee(BigDecimal totalFee) {
|
||||
this.totalFee = totalFee;
|
||||
}
|
||||
/**
|
||||
* 获取:实收金额(元)
|
||||
*/
|
||||
public BigDecimal getTotalFee() {
|
||||
return totalFee;
|
||||
}
|
||||
/**
|
||||
* 设置:订单金额
|
||||
*/
|
||||
public void setOrderPrice(BigDecimal orderPrice) {
|
||||
this.orderPrice = orderPrice;
|
||||
}
|
||||
/**
|
||||
* 获取:订单金额
|
||||
*/
|
||||
public BigDecimal getOrderPrice() {
|
||||
return orderPrice;
|
||||
}
|
||||
/**
|
||||
* 设置:手续费(元)
|
||||
*/
|
||||
public void setFee(BigDecimal fee) {
|
||||
this.fee = fee;
|
||||
}
|
||||
/**
|
||||
* 获取:手续费(元)
|
||||
*/
|
||||
public BigDecimal getFee() {
|
||||
return fee;
|
||||
}
|
||||
/**
|
||||
* 设置:对商品或交易的描述
|
||||
*/
|
||||
public void setBody(String body) {
|
||||
this.body = body;
|
||||
}
|
||||
/**
|
||||
* 获取:对商品或交易的描述
|
||||
*/
|
||||
public String getBody() {
|
||||
return body;
|
||||
}
|
||||
/**
|
||||
* 设置:附加数据
|
||||
*/
|
||||
public void setAttach(String attach) {
|
||||
this.attach = attach;
|
||||
}
|
||||
/**
|
||||
* 获取:附加数据
|
||||
*/
|
||||
public String getAttach() {
|
||||
return attach;
|
||||
}
|
||||
/**
|
||||
* 设置:付呗系统的门店id
|
||||
*/
|
||||
public void setStoreId(Long storeId) {
|
||||
this.storeId = storeId;
|
||||
}
|
||||
/**
|
||||
* 获取:付呗系统的门店id
|
||||
*/
|
||||
public Long getStoreId() {
|
||||
return storeId;
|
||||
}
|
||||
/**
|
||||
* 设置:付呗系统的收银员id
|
||||
*/
|
||||
public void setCashierId(Long cashierId) {
|
||||
this.cashierId = cashierId;
|
||||
}
|
||||
/**
|
||||
* 获取:付呗系统的收银员id
|
||||
*/
|
||||
public Long getCashierId() {
|
||||
return cashierId;
|
||||
}
|
||||
/**
|
||||
* 设置:设备终端号
|
||||
*/
|
||||
public void setDeviceNo(String deviceNo) {
|
||||
this.deviceNo = deviceNo;
|
||||
}
|
||||
/**
|
||||
* 获取:设备终端号
|
||||
*/
|
||||
public String getDeviceNo() {
|
||||
return deviceNo;
|
||||
}
|
||||
/**
|
||||
* 设置:微信顾客支付授权的“open_id”或者支付宝顾客的“buyer_user_id”
|
||||
*/
|
||||
public void setUserId(String userId) {
|
||||
this.userId = userId;
|
||||
}
|
||||
/**
|
||||
* 获取:微信顾客支付授权的“open_id”或者支付宝顾客的“buyer_user_id”
|
||||
*/
|
||||
public String getUserId() {
|
||||
return userId;
|
||||
}
|
||||
/**
|
||||
* 设置:支付宝顾客的账号
|
||||
*/
|
||||
public void setUserLogonId(String userLogonId) {
|
||||
this.userLogonId = userLogonId;
|
||||
}
|
||||
/**
|
||||
* 获取:支付宝顾客的账号
|
||||
*/
|
||||
public String getUserLogonId() {
|
||||
return userLogonId;
|
||||
}
|
||||
/**
|
||||
* 设置:交易成功的时间
|
||||
*/
|
||||
public void setPayTime(Date payTime) {
|
||||
this.payTime = payTime;
|
||||
}
|
||||
/**
|
||||
* 获取:交易成功的时间
|
||||
*/
|
||||
public Date getPayTime() {
|
||||
return payTime;
|
||||
}
|
||||
/**
|
||||
* 设置:支付通道:1微信、2支付宝、3银联
|
||||
*/
|
||||
public void setPayChannel(Integer payChannel) {
|
||||
this.payChannel = payChannel;
|
||||
}
|
||||
/**
|
||||
* 获取:支付通道:1微信、2支付宝、3银联
|
||||
*/
|
||||
public Integer getPayChannel() {
|
||||
return payChannel;
|
||||
}
|
||||
/**
|
||||
* 设置:免充值代金券金额(元)
|
||||
*/
|
||||
public void setNoCashCouponFee(BigDecimal noCashCouponFee) {
|
||||
this.noCashCouponFee = noCashCouponFee;
|
||||
}
|
||||
/**
|
||||
* 获取:免充值代金券金额(元)
|
||||
*/
|
||||
public BigDecimal getNoCashCouponFee() {
|
||||
return noCashCouponFee;
|
||||
}
|
||||
/**
|
||||
* 设置:预充值代金券金额(元)
|
||||
*/
|
||||
public void setCashCouponFee(BigDecimal cashCouponFee) {
|
||||
this.cashCouponFee = cashCouponFee;
|
||||
}
|
||||
/**
|
||||
* 获取:预充值代金券金额(元)
|
||||
*/
|
||||
public BigDecimal getCashCouponFee() {
|
||||
return cashCouponFee;
|
||||
}
|
||||
/**
|
||||
* 设置:顾客实际支付金额(元)
|
||||
*/
|
||||
public void setCashFee(BigDecimal cashFee) {
|
||||
this.cashFee = cashFee;
|
||||
}
|
||||
/**
|
||||
* 获取:顾客实际支付金额(元)
|
||||
*/
|
||||
public BigDecimal getCashFee() {
|
||||
return cashFee;
|
||||
}
|
||||
/**
|
||||
* 设置:签名
|
||||
*/
|
||||
public void setSign(String sign) {
|
||||
this.sign = sign;
|
||||
}
|
||||
/**
|
||||
* 获取:签名
|
||||
*/
|
||||
public String getSign() {
|
||||
return sign;
|
||||
}
|
||||
/**
|
||||
* 设置:其它选项
|
||||
*/
|
||||
public void setOptions(String options) {
|
||||
this.options = options;
|
||||
}
|
||||
/**
|
||||
* 获取:其它选项
|
||||
*/
|
||||
public String getOptions() {
|
||||
return options;
|
||||
}
|
||||
/**
|
||||
* 设置:创建时间
|
||||
*/
|
||||
public void setCreateTime(Date createTime) {
|
||||
this.createTime = createTime;
|
||||
}
|
||||
/**
|
||||
* 获取:创建时间
|
||||
*/
|
||||
public Date getCreateTime() {
|
||||
return createTime;
|
||||
}
|
||||
/**
|
||||
* 设置:推送时间
|
||||
*/
|
||||
public void setPushTime(Date pushTime) {
|
||||
this.pushTime = pushTime;
|
||||
}
|
||||
/**
|
||||
* 获取:推送时间
|
||||
*/
|
||||
public Date getPushTime() {
|
||||
return pushTime;
|
||||
}
|
||||
/**
|
||||
* 设置:推送IP
|
||||
*/
|
||||
public void setPushIp(String pushIp) {
|
||||
this.pushIp = pushIp;
|
||||
}
|
||||
/**
|
||||
* 获取:推送IP
|
||||
*/
|
||||
public String getPushIp() {
|
||||
return pushIp;
|
||||
}
|
||||
/**
|
||||
* 设置:商户id
|
||||
*/
|
||||
public void setMchtId(BigDecimal mchtId) {
|
||||
this.mchtId = mchtId;
|
||||
}
|
||||
/**
|
||||
* 获取:商户id
|
||||
*/
|
||||
public BigDecimal getMchtId() {
|
||||
return mchtId;
|
||||
}
|
||||
/**
|
||||
* 设置:QR编号
|
||||
*/
|
||||
public void setSn(String sn) {
|
||||
this.sn = sn;
|
||||
}
|
||||
/**
|
||||
* 获取:QR编号
|
||||
*/
|
||||
public String getSn() {
|
||||
return sn;
|
||||
}
|
||||
}
|
@ -1,30 +0,0 @@
|
||||
package com.java2nb.test.service;
|
||||
|
||||
import com.java2nb.test.domain.OrderDO;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 付呗-订单信息表
|
||||
*
|
||||
* @author xiongxy
|
||||
* @email 1179705413@qq.com
|
||||
* @date 2019-11-25 11:57:16
|
||||
*/
|
||||
public interface OrderService {
|
||||
|
||||
OrderDO get(Long id);
|
||||
|
||||
List<OrderDO> list(Map<String, Object> map);
|
||||
|
||||
int count(Map<String, Object> map);
|
||||
|
||||
int save(OrderDO order);
|
||||
|
||||
int update(OrderDO order);
|
||||
|
||||
int remove(Long id);
|
||||
|
||||
int batchRemove(Long[] ids);
|
||||
}
|
@ -1,55 +0,0 @@
|
||||
package com.java2nb.test.service.impl;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.java2nb.test.dao.OrderDao;
|
||||
import com.java2nb.test.domain.OrderDO;
|
||||
import com.java2nb.test.service.OrderService;
|
||||
|
||||
|
||||
|
||||
@Service
|
||||
public class OrderServiceImpl implements OrderService {
|
||||
@Autowired
|
||||
private OrderDao orderDao;
|
||||
|
||||
@Override
|
||||
public OrderDO get(Long id){
|
||||
return orderDao.get(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<OrderDO> list(Map<String, Object> map){
|
||||
return orderDao.list(map);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int count(Map<String, Object> map){
|
||||
return orderDao.count(map);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int save(OrderDO order){
|
||||
return orderDao.save(order);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int update(OrderDO order){
|
||||
return orderDao.update(order);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int remove(Long id){
|
||||
return orderDao.remove(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int batchRemove(Long[] ids){
|
||||
return orderDao.batchRemove(ids);
|
||||
}
|
||||
|
||||
}
|
@ -10,7 +10,7 @@ spring:
|
||||
datasource:
|
||||
type: com.alibaba.druid.pool.DruidDataSource
|
||||
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
|
||||
password: test123456
|
||||
#password:
|
||||
|
@ -10,7 +10,7 @@ spring:
|
||||
datasource:
|
||||
type: com.alibaba.druid.pool.DruidDataSource
|
||||
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
|
||||
password: test123456
|
||||
#password:
|
||||
|
@ -36,3 +36,7 @@ mybatis:
|
||||
typeAliasesPackage: com.java2nb.**.domain
|
||||
#[弃用]配置缓存和session存储方式,默认ehcache,可选redis,[弃用]调整至 spring cache type【shiro.用户,权限,session,spring.cache通用】
|
||||
#[弃用]cacheType: ehcache
|
||||
|
||||
|
||||
logging:
|
||||
config: classpath:logback-boot.xml
|
||||
|
@ -24,7 +24,7 @@
|
||||
<!-- RollingFileAppender:滚动记录文件,先将日志记录到指定文件,当符合某个条件时,将日志记录到其他文件 -->
|
||||
<!-- 以下的大概意思是:1.先按日期存日志,日期变了,将前一天的日志文件名重命名为XXX%日期%索引,新的日志仍然是demo.log -->
|
||||
<!-- 2.如果日期没有发生变化,但是当前日志的文件大小超过1KB时,对当前日志进行分割 重命名 -->
|
||||
<appender name="debug" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||
|
||||
<File>logs/debug.log</File>
|
||||
<!-- rollingPolicy:当发生滚动时,决定 RollingFileAppender 的行为,涉及文件移动和重命名。 -->
|
||||
@ -52,11 +52,13 @@
|
||||
<!-- 控制台输出日志级别 -->
|
||||
<root level="INFO">
|
||||
<appender-ref ref="STDOUT" />
|
||||
<appender-ref ref="FILE" />
|
||||
</root>
|
||||
<!-- 指定项目中某个包,当有日志操作行为时的日志记录级别 -->
|
||||
<!-- com.maijinjie.springboot 为根包,也就是只要是发生在这个根包下面的所有日志操作行为的权限都是DEBUG -->
|
||||
<!-- 级别依次为【从高到低】:FATAL > ERROR > WARN > INFO > DEBUG > TRACE -->
|
||||
<logger name="com.java2nb" level="DEBUG">
|
||||
<appender-ref ref="debug" />
|
||||
<logger name="com.java2nb" level="DEBUG" additivity="false">
|
||||
<appender-ref ref="STDOUT" />
|
||||
<appender-ref ref="FILE" />
|
||||
</logger>
|
||||
</configuration>
|
@ -1,283 +0,0 @@
|
||||
<?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.test.dao.OrderDao">
|
||||
|
||||
<select id="get" resultType="com.java2nb.test.domain.OrderDO">
|
||||
select `id`,`fb_merchant_code`,`merchant_order_sn`,`order_sn`,`platform_order_no`,`trade_no`,`order_state`,`fn_coupon`,`red_packet`,`total_fee`,`order_price`,`fee`,`body`,`attach`,`store_id`,`cashier_id`,`device_no`,`user_id`,`user_logon_id`,`pay_time`,`pay_channel`,`no_cash_coupon_fee`,`cash_coupon_fee`,`cash_fee`,`sign`,`options`,`create_time`,`push_time`,`push_ip`,`mcht_id`,`sn` from fb_order where id = #{value}
|
||||
</select>
|
||||
|
||||
<select id="list" resultType="com.java2nb.test.domain.OrderDO">
|
||||
select `id`,`fb_merchant_code`,`merchant_order_sn`,`order_sn`,`platform_order_no`,`trade_no`,`order_state`,`fn_coupon`,`red_packet`,`total_fee`,`order_price`,`fee`,`body`,`attach`,`store_id`,`cashier_id`,`device_no`,`user_id`,`user_logon_id`,`pay_time`,`pay_channel`,`no_cash_coupon_fee`,`cash_coupon_fee`,`cash_fee`,`sign`,`options`,`create_time`,`push_time`,`push_ip`,`mcht_id`,`sn` from fb_order
|
||||
<where>
|
||||
<if test="id != null and id != ''"> and id = #{id} </if>
|
||||
<if test="fbMerchantCode != null and fbMerchantCode != ''"> and fb_merchant_code = #{fbMerchantCode} </if>
|
||||
<if test="merchantOrderSn != null and merchantOrderSn != ''"> and merchant_order_sn = #{merchantOrderSn} </if>
|
||||
<if test="orderSn != null and orderSn != ''"> and order_sn = #{orderSn} </if>
|
||||
<if test="platformOrderNo != null and platformOrderNo != ''"> and platform_order_no = #{platformOrderNo} </if>
|
||||
<if test="tradeNo != null and tradeNo != ''"> and trade_no = #{tradeNo} </if>
|
||||
<if test="orderState != null and orderState != ''"> and order_state = #{orderState} </if>
|
||||
<if test="fnCoupon != null and fnCoupon != ''"> and fn_coupon = #{fnCoupon} </if>
|
||||
<if test="redPacket != null and redPacket != ''"> and red_packet = #{redPacket} </if>
|
||||
<if test="totalFee != null and totalFee != ''"> and total_fee = #{totalFee} </if>
|
||||
<if test="orderPrice != null and orderPrice != ''"> and order_price = #{orderPrice} </if>
|
||||
<if test="fee != null and fee != ''"> and fee = #{fee} </if>
|
||||
<if test="body != null and body != ''"> and body = #{body} </if>
|
||||
<if test="attach != null and attach != ''"> and attach = #{attach} </if>
|
||||
<if test="storeId != null and storeId != ''"> and store_id = #{storeId} </if>
|
||||
<if test="cashierId != null and cashierId != ''"> and cashier_id = #{cashierId} </if>
|
||||
<if test="deviceNo != null and deviceNo != ''"> and device_no = #{deviceNo} </if>
|
||||
<if test="userId != null and userId != ''"> and user_id = #{userId} </if>
|
||||
<if test="userLogonId != null and userLogonId != ''"> and user_logon_id = #{userLogonId} </if>
|
||||
<if test="payTime != null and payTime != ''"> and pay_time = #{payTime} </if>
|
||||
<if test="payChannel != null and payChannel != ''"> and pay_channel = #{payChannel} </if>
|
||||
<if test="noCashCouponFee != null and noCashCouponFee != ''"> and no_cash_coupon_fee = #{noCashCouponFee} </if>
|
||||
<if test="cashCouponFee != null and cashCouponFee != ''"> and cash_coupon_fee = #{cashCouponFee} </if>
|
||||
<if test="cashFee != null and cashFee != ''"> and cash_fee = #{cashFee} </if>
|
||||
<if test="sign != null and sign != ''"> and sign = #{sign} </if>
|
||||
<if test="options != null and options != ''"> and options = #{options} </if>
|
||||
<if test="createTime != null and createTime != ''"> and create_time = #{createTime} </if>
|
||||
<if test="pushTime != null and pushTime != ''"> and push_time = #{pushTime} </if>
|
||||
<if test="pushIp != null and pushIp != ''"> and push_ip = #{pushIp} </if>
|
||||
<if test="mchtId != null and mchtId != ''"> and mcht_id = #{mchtId} </if>
|
||||
<if test="sn != null and sn != ''"> and sn = #{sn} </if>
|
||||
</where>
|
||||
<choose>
|
||||
<when test="sort != null and sort.trim() != ''">
|
||||
order by ${sort} ${order}
|
||||
</when>
|
||||
<otherwise>
|
||||
order by id desc
|
||||
</otherwise>
|
||||
</choose>
|
||||
<if test="offset != null and limit != null">
|
||||
limit #{offset}, #{limit}
|
||||
</if>
|
||||
</select>
|
||||
|
||||
<select id="count" resultType="int">
|
||||
select count(*) from fb_order
|
||||
<where>
|
||||
<if test="id != null and id != ''"> and id = #{id} </if>
|
||||
<if test="fbMerchantCode != null and fbMerchantCode != ''"> and fb_merchant_code = #{fbMerchantCode} </if>
|
||||
<if test="merchantOrderSn != null and merchantOrderSn != ''"> and merchant_order_sn = #{merchantOrderSn} </if>
|
||||
<if test="orderSn != null and orderSn != ''"> and order_sn = #{orderSn} </if>
|
||||
<if test="platformOrderNo != null and platformOrderNo != ''"> and platform_order_no = #{platformOrderNo} </if>
|
||||
<if test="tradeNo != null and tradeNo != ''"> and trade_no = #{tradeNo} </if>
|
||||
<if test="orderState != null and orderState != ''"> and order_state = #{orderState} </if>
|
||||
<if test="fnCoupon != null and fnCoupon != ''"> and fn_coupon = #{fnCoupon} </if>
|
||||
<if test="redPacket != null and redPacket != ''"> and red_packet = #{redPacket} </if>
|
||||
<if test="totalFee != null and totalFee != ''"> and total_fee = #{totalFee} </if>
|
||||
<if test="orderPrice != null and orderPrice != ''"> and order_price = #{orderPrice} </if>
|
||||
<if test="fee != null and fee != ''"> and fee = #{fee} </if>
|
||||
<if test="body != null and body != ''"> and body = #{body} </if>
|
||||
<if test="attach != null and attach != ''"> and attach = #{attach} </if>
|
||||
<if test="storeId != null and storeId != ''"> and store_id = #{storeId} </if>
|
||||
<if test="cashierId != null and cashierId != ''"> and cashier_id = #{cashierId} </if>
|
||||
<if test="deviceNo != null and deviceNo != ''"> and device_no = #{deviceNo} </if>
|
||||
<if test="userId != null and userId != ''"> and user_id = #{userId} </if>
|
||||
<if test="userLogonId != null and userLogonId != ''"> and user_logon_id = #{userLogonId} </if>
|
||||
<if test="payTime != null and payTime != ''"> and pay_time = #{payTime} </if>
|
||||
<if test="payChannel != null and payChannel != ''"> and pay_channel = #{payChannel} </if>
|
||||
<if test="noCashCouponFee != null and noCashCouponFee != ''"> and no_cash_coupon_fee = #{noCashCouponFee} </if>
|
||||
<if test="cashCouponFee != null and cashCouponFee != ''"> and cash_coupon_fee = #{cashCouponFee} </if>
|
||||
<if test="cashFee != null and cashFee != ''"> and cash_fee = #{cashFee} </if>
|
||||
<if test="sign != null and sign != ''"> and sign = #{sign} </if>
|
||||
<if test="options != null and options != ''"> and options = #{options} </if>
|
||||
<if test="createTime != null and createTime != ''"> and create_time = #{createTime} </if>
|
||||
<if test="pushTime != null and pushTime != ''"> and push_time = #{pushTime} </if>
|
||||
<if test="pushIp != null and pushIp != ''"> and push_ip = #{pushIp} </if>
|
||||
<if test="mchtId != null and mchtId != ''"> and mcht_id = #{mchtId} </if>
|
||||
<if test="sn != null and sn != ''"> and sn = #{sn} </if>
|
||||
</where>
|
||||
</select>
|
||||
|
||||
<insert id="save" parameterType="com.java2nb.test.domain.OrderDO" useGeneratedKeys="true" keyProperty="id">
|
||||
insert into fb_order
|
||||
(
|
||||
`fb_merchant_code`,
|
||||
`merchant_order_sn`,
|
||||
`order_sn`,
|
||||
`platform_order_no`,
|
||||
`trade_no`,
|
||||
`order_state`,
|
||||
`fn_coupon`,
|
||||
`red_packet`,
|
||||
`total_fee`,
|
||||
`order_price`,
|
||||
`fee`,
|
||||
`body`,
|
||||
`attach`,
|
||||
`store_id`,
|
||||
`cashier_id`,
|
||||
`device_no`,
|
||||
`user_id`,
|
||||
`user_logon_id`,
|
||||
`pay_time`,
|
||||
`pay_channel`,
|
||||
`no_cash_coupon_fee`,
|
||||
`cash_coupon_fee`,
|
||||
`cash_fee`,
|
||||
`sign`,
|
||||
`options`,
|
||||
`create_time`,
|
||||
`push_time`,
|
||||
`push_ip`,
|
||||
`mcht_id`,
|
||||
`sn`
|
||||
)
|
||||
values
|
||||
(
|
||||
#{fbMerchantCode},
|
||||
#{merchantOrderSn},
|
||||
#{orderSn},
|
||||
#{platformOrderNo},
|
||||
#{tradeNo},
|
||||
#{orderState},
|
||||
#{fnCoupon},
|
||||
#{redPacket},
|
||||
#{totalFee},
|
||||
#{orderPrice},
|
||||
#{fee},
|
||||
#{body},
|
||||
#{attach},
|
||||
#{storeId},
|
||||
#{cashierId},
|
||||
#{deviceNo},
|
||||
#{userId},
|
||||
#{userLogonId},
|
||||
#{payTime},
|
||||
#{payChannel},
|
||||
#{noCashCouponFee},
|
||||
#{cashCouponFee},
|
||||
#{cashFee},
|
||||
#{sign},
|
||||
#{options},
|
||||
#{createTime},
|
||||
#{pushTime},
|
||||
#{pushIp},
|
||||
#{mchtId},
|
||||
#{sn}
|
||||
)
|
||||
</insert>
|
||||
|
||||
<insert id="saveSelective" parameterType="com.java2nb.test.domain.OrderDO" useGeneratedKeys="true" keyProperty="id">
|
||||
insert into fb_order
|
||||
(
|
||||
<if test="id != null"> `id`, </if>
|
||||
<if test="fbMerchantCode != null"> `fb_merchant_code`, </if>
|
||||
<if test="merchantOrderSn != null"> `merchant_order_sn`, </if>
|
||||
<if test="orderSn != null"> `order_sn`, </if>
|
||||
<if test="platformOrderNo != null"> `platform_order_no`, </if>
|
||||
<if test="tradeNo != null"> `trade_no`, </if>
|
||||
<if test="orderState != null"> `order_state`, </if>
|
||||
<if test="fnCoupon != null"> `fn_coupon`, </if>
|
||||
<if test="redPacket != null"> `red_packet`, </if>
|
||||
<if test="totalFee != null"> `total_fee`, </if>
|
||||
<if test="orderPrice != null"> `order_price`, </if>
|
||||
<if test="fee != null"> `fee`, </if>
|
||||
<if test="body != null"> `body`, </if>
|
||||
<if test="attach != null"> `attach`, </if>
|
||||
<if test="storeId != null"> `store_id`, </if>
|
||||
<if test="cashierId != null"> `cashier_id`, </if>
|
||||
<if test="deviceNo != null"> `device_no`, </if>
|
||||
<if test="userId != null"> `user_id`, </if>
|
||||
<if test="userLogonId != null"> `user_logon_id`, </if>
|
||||
<if test="payTime != null"> `pay_time`, </if>
|
||||
<if test="payChannel != null"> `pay_channel`, </if>
|
||||
<if test="noCashCouponFee != null"> `no_cash_coupon_fee`, </if>
|
||||
<if test="cashCouponFee != null"> `cash_coupon_fee`, </if>
|
||||
<if test="cashFee != null"> `cash_fee`, </if>
|
||||
<if test="sign != null"> `sign`, </if>
|
||||
<if test="options != null"> `options`, </if>
|
||||
<if test="createTime != null"> `create_time`, </if>
|
||||
<if test="pushTime != null"> `push_time`, </if>
|
||||
<if test="pushIp != null"> `push_ip`, </if>
|
||||
<if test="mchtId != null"> `mcht_id`, </if>
|
||||
<if test="sn != null"> `sn` </if>
|
||||
)
|
||||
values
|
||||
(
|
||||
<if test="id != null"> #{id}, </if>
|
||||
<if test="fbMerchantCode != null"> #{fbMerchantCode}, </if>
|
||||
<if test="merchantOrderSn != null"> #{merchantOrderSn}, </if>
|
||||
<if test="orderSn != null"> #{orderSn}, </if>
|
||||
<if test="platformOrderNo != null"> #{platformOrderNo}, </if>
|
||||
<if test="tradeNo != null"> #{tradeNo}, </if>
|
||||
<if test="orderState != null"> #{orderState}, </if>
|
||||
<if test="fnCoupon != null"> #{fnCoupon}, </if>
|
||||
<if test="redPacket != null"> #{redPacket}, </if>
|
||||
<if test="totalFee != null"> #{totalFee}, </if>
|
||||
<if test="orderPrice != null"> #{orderPrice}, </if>
|
||||
<if test="fee != null"> #{fee}, </if>
|
||||
<if test="body != null"> #{body}, </if>
|
||||
<if test="attach != null"> #{attach}, </if>
|
||||
<if test="storeId != null"> #{storeId}, </if>
|
||||
<if test="cashierId != null"> #{cashierId}, </if>
|
||||
<if test="deviceNo != null"> #{deviceNo}, </if>
|
||||
<if test="userId != null"> #{userId}, </if>
|
||||
<if test="userLogonId != null"> #{userLogonId}, </if>
|
||||
<if test="payTime != null"> #{payTime}, </if>
|
||||
<if test="payChannel != null"> #{payChannel}, </if>
|
||||
<if test="noCashCouponFee != null"> #{noCashCouponFee}, </if>
|
||||
<if test="cashCouponFee != null"> #{cashCouponFee}, </if>
|
||||
<if test="cashFee != null"> #{cashFee}, </if>
|
||||
<if test="sign != null"> #{sign}, </if>
|
||||
<if test="options != null"> #{options}, </if>
|
||||
<if test="createTime != null"> #{createTime}, </if>
|
||||
<if test="pushTime != null"> #{pushTime}, </if>
|
||||
<if test="pushIp != null"> #{pushIp}, </if>
|
||||
<if test="mchtId != null"> #{mchtId}, </if>
|
||||
<if test="sn != null"> #{sn} </if>
|
||||
)
|
||||
</insert>
|
||||
|
||||
<update id="update" parameterType="com.java2nb.test.domain.OrderDO">
|
||||
update fb_order
|
||||
<set>
|
||||
<if test="fbMerchantCode != null">`fb_merchant_code` = #{fbMerchantCode}, </if>
|
||||
<if test="merchantOrderSn != null">`merchant_order_sn` = #{merchantOrderSn}, </if>
|
||||
<if test="orderSn != null">`order_sn` = #{orderSn}, </if>
|
||||
<if test="platformOrderNo != null">`platform_order_no` = #{platformOrderNo}, </if>
|
||||
<if test="tradeNo != null">`trade_no` = #{tradeNo}, </if>
|
||||
<if test="orderState != null">`order_state` = #{orderState}, </if>
|
||||
<if test="fnCoupon != null">`fn_coupon` = #{fnCoupon}, </if>
|
||||
<if test="redPacket != null">`red_packet` = #{redPacket}, </if>
|
||||
<if test="totalFee != null">`total_fee` = #{totalFee}, </if>
|
||||
<if test="orderPrice != null">`order_price` = #{orderPrice}, </if>
|
||||
<if test="fee != null">`fee` = #{fee}, </if>
|
||||
<if test="body != null">`body` = #{body}, </if>
|
||||
<if test="attach != null">`attach` = #{attach}, </if>
|
||||
<if test="storeId != null">`store_id` = #{storeId}, </if>
|
||||
<if test="cashierId != null">`cashier_id` = #{cashierId}, </if>
|
||||
<if test="deviceNo != null">`device_no` = #{deviceNo}, </if>
|
||||
<if test="userId != null">`user_id` = #{userId}, </if>
|
||||
<if test="userLogonId != null">`user_logon_id` = #{userLogonId}, </if>
|
||||
<if test="payTime != null">`pay_time` = #{payTime}, </if>
|
||||
<if test="payChannel != null">`pay_channel` = #{payChannel}, </if>
|
||||
<if test="noCashCouponFee != null">`no_cash_coupon_fee` = #{noCashCouponFee}, </if>
|
||||
<if test="cashCouponFee != null">`cash_coupon_fee` = #{cashCouponFee}, </if>
|
||||
<if test="cashFee != null">`cash_fee` = #{cashFee}, </if>
|
||||
<if test="sign != null">`sign` = #{sign}, </if>
|
||||
<if test="options != null">`options` = #{options}, </if>
|
||||
<if test="createTime != null">`create_time` = #{createTime}, </if>
|
||||
<if test="pushTime != null">`push_time` = #{pushTime}, </if>
|
||||
<if test="pushIp != null">`push_ip` = #{pushIp}, </if>
|
||||
<if test="mchtId != null">`mcht_id` = #{mchtId}, </if>
|
||||
<if test="sn != null">`sn` = #{sn}</if>
|
||||
</set>
|
||||
where id = #{id}
|
||||
</update>
|
||||
|
||||
<delete id="remove">
|
||||
delete from fb_order where id = #{value}
|
||||
</delete>
|
||||
|
||||
<delete id="batchRemove">
|
||||
delete from fb_order where id in
|
||||
<foreach item="id" collection="array" open="(" separator="," close=")">
|
||||
#{id}
|
||||
</foreach>
|
||||
</delete>
|
||||
|
||||
</mapper>
|
@ -1,18 +0,0 @@
|
||||
-- 菜单SQL
|
||||
INSERT INTO `sys_menu` (`parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`)
|
||||
VALUES ('1', '付呗-订单信息表', 'test/order', 'test:order:order', '1', 'fa', '6');
|
||||
|
||||
-- 按钮父菜单ID
|
||||
set @parentId = @@identity;
|
||||
|
||||
-- 菜单对应按钮SQL
|
||||
INSERT INTO `sys_menu` (`parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`)
|
||||
SELECT @parentId, '查看', null, 'test:order:detail', '2', null, '6';
|
||||
INSERT INTO `sys_menu` (`parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`)
|
||||
SELECT @parentId, '新增', null, 'test:order:add', '2', null, '6';
|
||||
INSERT INTO `sys_menu` (`parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`)
|
||||
SELECT @parentId, '修改', null, 'test:order:edit', '2', null, '6';
|
||||
INSERT INTO `sys_menu` (`parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`)
|
||||
SELECT @parentId, '删除', null, 'test:order:remove', '2', null, '6';
|
||||
INSERT INTO `sys_menu` (`parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`)
|
||||
SELECT @parentId, '批量删除', null, 'test:order:batchRemove', '2', null, '6';
|
@ -1,25 +0,0 @@
|
||||
package com.java2nb.testDemo;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
@RestController()
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest
|
||||
public class TestDemo {
|
||||
@Autowired
|
||||
RedisTemplate redisTemplate;
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
redisTemplate.opsForValue().set("a", "b");
|
||||
System.out.println(redisTemplate.opsForValue().get("a"));
|
||||
}
|
||||
|
||||
;
|
||||
}
|
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>novel</artifactId>
|
||||
<groupId>com.java2nb</groupId>
|
||||
<version>3.5.1</version>
|
||||
<version>3.6.1</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@ -103,12 +103,6 @@
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-thymeleaf</artifactId>
|
||||
</dependency>
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>org.mybatis.dynamic-sql</groupId>
|
||||
<artifactId>mybatis-dynamic-sql</artifactId>
|
||||
@ -129,6 +123,24 @@
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.github.xxyopen</groupId>
|
||||
<artifactId>xxy-model</artifactId>
|
||||
<version>${xxyopen.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.github.xxyopen</groupId>
|
||||
<artifactId>xxy-web</artifactId>
|
||||
<version>${xxyopen.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.github.xxyopen</groupId>
|
||||
<artifactId>xxy-util</artifactId>
|
||||
<version>${xxyopen.version}</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
|
||||
</dependencies>
|
||||
|
@ -1,46 +0,0 @@
|
||||
package com.java2nb.novel.core.advice;
|
||||
|
||||
import com.java2nb.novel.core.bean.ResultBean;
|
||||
import com.java2nb.novel.core.enums.ResponseStatus;
|
||||
import com.java2nb.novel.core.exception.BusinessException;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.validation.BindException;
|
||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||
import org.springframework.web.bind.annotation.RestControllerAdvice;
|
||||
|
||||
/**
|
||||
* 通用的异常处理器
|
||||
*
|
||||
* @author 11797*/
|
||||
@Slf4j
|
||||
@RestControllerAdvice(basePackages = "com.java2nb.novel.controller")
|
||||
public class CommonExceptionHandler {
|
||||
|
||||
/**
|
||||
* 处理后台数据校验异常
|
||||
* */
|
||||
@ExceptionHandler(BindException.class)
|
||||
public ResultBean handlerBindException(BindException e){
|
||||
log.error(e.getMessage(),e);
|
||||
return ResultBean.fail(ResponseStatus.PARAM_ERROR);
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理业务异常
|
||||
* */
|
||||
@ExceptionHandler(BusinessException.class)
|
||||
public ResultBean handlerBusinessException(BusinessException e){
|
||||
log.error(e.getMessage(),e);
|
||||
return ResultBean.fail(e.getResStatus());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 处理系统异常
|
||||
* */
|
||||
@ExceptionHandler(Exception.class)
|
||||
public ResultBean handlerException(Exception e){
|
||||
log.error(e.getMessage(),e);
|
||||
return ResultBean.error();
|
||||
}
|
||||
}
|
@ -1,53 +0,0 @@
|
||||
package com.java2nb.novel.core.bean;
|
||||
|
||||
import com.github.pagehelper.PageInfo;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 封装通用分页数据,接收PageHelper、SpringData等框架的分页数据,转换成通用的PageBean对象
|
||||
* @author xiongxiaoyang
|
||||
* @version 1.0
|
||||
* @since 2021/2/4
|
||||
* @param <T> 分页集合类型
|
||||
*/
|
||||
@Data
|
||||
public class PageBean<T> {
|
||||
|
||||
private Integer pageNum;
|
||||
private Integer pageSize;
|
||||
private Long total;
|
||||
private List<? extends T> list;
|
||||
|
||||
|
||||
/**
|
||||
* 该构造函数用于PageHelper工具进行分页查询的场景
|
||||
* 接收PageHelper分页后的list
|
||||
*/
|
||||
public PageBean(List<T> list){
|
||||
PageInfo<T> pageInfo = new PageInfo<>(list);
|
||||
this.pageNum = pageInfo.getPageNum();
|
||||
this.pageSize = pageInfo.getPageSize();
|
||||
this.total = pageInfo.getTotal();
|
||||
this.list = pageInfo.getList();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 该构造函数用于通用分页查询的场景
|
||||
* 接收普通分页数据和普通集合
|
||||
*/
|
||||
public PageBean(Integer pageNum, Integer pageSize, Long total, List<T> list) {
|
||||
this.pageNum = pageNum;
|
||||
this.pageSize = pageSize;
|
||||
this.total = total;
|
||||
this.list = list;
|
||||
}
|
||||
|
||||
|
||||
//TODO 使用其他的分页工具或框架进行分页查询的场景
|
||||
|
||||
|
||||
|
||||
}
|
@ -1,73 +0,0 @@
|
||||
package com.java2nb.novel.core.bean;
|
||||
|
||||
|
||||
import com.java2nb.novel.core.enums.ResponseStatus;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 自定义响应结构
|
||||
* @author 11797
|
||||
* @param <T>
|
||||
*/
|
||||
@Data
|
||||
public class ResultBean<T> implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private int code = ResponseStatus.OK.getCode();
|
||||
|
||||
/**
|
||||
* 响应消息
|
||||
* */
|
||||
private String msg = ResponseStatus.OK.getMsg();
|
||||
/**
|
||||
* 响应中的数据
|
||||
* */
|
||||
private T data;
|
||||
|
||||
private ResultBean() {
|
||||
|
||||
}
|
||||
|
||||
private ResultBean(ResponseStatus ResponseStatus) {
|
||||
this.code = ResponseStatus.getCode();;
|
||||
this.msg = ResponseStatus.getMsg();
|
||||
}
|
||||
|
||||
private ResultBean(T data) {
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 业务处理成功,无数据返回
|
||||
* */
|
||||
public static ResultBean ok() {
|
||||
return new ResultBean();
|
||||
}
|
||||
|
||||
/**
|
||||
* 业务处理成功,有数据返回
|
||||
* */
|
||||
public static <T> ResultBean ok(T data) {
|
||||
return new ResultBean(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 业务处理失败
|
||||
* */
|
||||
public static ResultBean fail(ResponseStatus ResponseStatus) {
|
||||
return new ResultBean(ResponseStatus);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 系统错误
|
||||
* */
|
||||
public static ResultBean error() {
|
||||
return new ResultBean(ResponseStatus.ERROR);
|
||||
}
|
||||
}
|
||||
|
@ -65,4 +65,8 @@ public interface CacheKey {
|
||||
* 累积的小说点击量
|
||||
* */
|
||||
String BOOK_ADD_VISIT_COUNT = "bookAddVisitCount";
|
||||
}
|
||||
/**
|
||||
* 测试爬虫规则缓存
|
||||
*/
|
||||
String BOOK_TEST_PARSE = "testParse";
|
||||
}
|
||||
|
@ -16,108 +16,107 @@ import org.springframework.stereotype.Service;
|
||||
@RequiredArgsConstructor
|
||||
@Service
|
||||
public class EhCacheServiceImpl implements CacheService {
|
||||
|
||||
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);
|
||||
private final CacheManager cacheManager;
|
||||
|
||||
|
||||
}
|
||||
/**
|
||||
* 获得一个Cache,没有则创建一个。
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private Cache getCache() {
|
||||
|
||||
@Override
|
||||
public boolean contains(String key) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
Cache cache = cacheManager.getCache("util_cache");
|
||||
return cache;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 根据key获取缓存的Object类型数据
|
||||
*/
|
||||
@Override
|
||||
public Object getObject(String key) {
|
||||
Element element = getCache().get(key);
|
||||
return element==null?null:element.getObjectValue();
|
||||
}
|
||||
@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);
|
||||
|
||||
|
||||
/**
|
||||
* 设置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);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(String key) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 设置一个有过期时间的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);
|
||||
|
||||
}
|
||||
/**
|
||||
* 根据key获取缓存的Object类型数据
|
||||
*/
|
||||
@Override
|
||||
public Object getObject(String key) {
|
||||
Element element = getCache().get(key);
|
||||
return element == null ? null : element.getObjectValue();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 设置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);
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
package com.java2nb.novel.core.enums;
|
||||
|
||||
import io.github.xxyopen.model.resp.IResultCode;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
@ -11,27 +12,7 @@ import lombok.NoArgsConstructor;
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public enum ResponseStatus {
|
||||
|
||||
/**
|
||||
* 请求成功
|
||||
* */
|
||||
OK(200,"SUCCESS"),
|
||||
|
||||
/**
|
||||
* 服务器异常
|
||||
* */
|
||||
ERROR(500,"未知异常,请联系管理员!"),
|
||||
|
||||
/**
|
||||
* 参数错误
|
||||
* */
|
||||
PARAM_ERROR(400,"非法参数!"),
|
||||
|
||||
/**
|
||||
* 拒绝访问
|
||||
* */
|
||||
FORBIDDEN(403,"拒绝访问!"),
|
||||
public enum ResponseStatus implements IResultCode {
|
||||
|
||||
|
||||
/**
|
||||
@ -68,6 +49,12 @@ public enum ResponseStatus {
|
||||
* */
|
||||
ES_SEARCH_FAIL(9001,"搜索引擎查询错误!"),
|
||||
|
||||
/**
|
||||
* 文件相关错误
|
||||
* */
|
||||
FILE_DIR_MAKE_FAIL(10001,"目录创建失败"),
|
||||
FILE_NOT_IMAGE(10002,"请上传图片类型的文件"),
|
||||
FILE_SIZE_LIMIT(10003,"文件大小超出限制"),
|
||||
|
||||
/**
|
||||
* 其他通用错误
|
||||
|
@ -1,22 +0,0 @@
|
||||
package com.java2nb.novel.core.exception;
|
||||
|
||||
import com.java2nb.novel.core.enums.ResponseStatus;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 自定义业务异常,用于处理用户请求时,业务错误时抛出
|
||||
*/
|
||||
@Data
|
||||
public class BusinessException extends RuntimeException {
|
||||
|
||||
private ResponseStatus resStatus;
|
||||
|
||||
public BusinessException(ResponseStatus resStatus) {
|
||||
//不调用父类Throwable的fillInStackTrace()方法生成栈追踪信息,提高应用性能
|
||||
//构造器之间的调用必须在第一行
|
||||
super(resStatus.getMsg(), null, false, false);
|
||||
this.resStatus = resStatus;
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -1,33 +0,0 @@
|
||||
package com.java2nb.novel.core.utils;
|
||||
|
||||
import lombok.SneakyThrows;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Bean操作工具类
|
||||
* @author Administrator
|
||||
*/
|
||||
public class BeanUtil {
|
||||
|
||||
/**
|
||||
* 复制集合对象属性值,生成新类型集合
|
||||
* @param source 源集合
|
||||
* @param targetClass 目标集合类型
|
||||
* @return 新集合
|
||||
* */
|
||||
@SneakyThrows
|
||||
public static <T> List<T> copyList(List source,Class<T> targetClass){
|
||||
List<T> target = new ArrayList<>(source.size());
|
||||
for( int i = 0 ; i < source.size() ; i++){
|
||||
Object sourceItem = source.get(i);
|
||||
T targetItem = targetClass.newInstance();
|
||||
BeanUtils.copyProperties(sourceItem,targetItem);
|
||||
target.add(targetItem);
|
||||
}
|
||||
return target;
|
||||
|
||||
}
|
||||
}
|
@ -1,6 +1,8 @@
|
||||
package com.java2nb.novel.core.utils;
|
||||
|
||||
import io.github.xxyopen.util.UUIDUtil;
|
||||
import lombok.SneakyThrows;
|
||||
import lombok.experimental.UtilityClass;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.codec.Charsets;
|
||||
import org.apache.http.client.utils.DateUtils;
|
||||
@ -11,21 +13,24 @@ import org.springframework.http.HttpMethod;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.*;
|
||||
import java.util.Date;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* 文件操作工具类
|
||||
*
|
||||
* @author 11797
|
||||
*/
|
||||
@UtilityClass
|
||||
@Slf4j
|
||||
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;
|
||||
OutputStream out = null;
|
||||
try {
|
||||
@ -50,37 +55,70 @@ public class FileUtil {
|
||||
}
|
||||
|
||||
out.flush();
|
||||
if( ImageIO.read(picFile) == null){
|
||||
if (ImageIO.read(picFile) == null) {
|
||||
picSrc = "/images/default.gif";
|
||||
}
|
||||
|
||||
}catch (Exception e){
|
||||
log.error(e.getMessage(),e);
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
|
||||
picSrc = "/images/default.gif";
|
||||
}finally {
|
||||
if(input != null){
|
||||
try {
|
||||
input.close();
|
||||
} catch (IOException e) {
|
||||
log.error(e.getMessage(),e);
|
||||
}finally {
|
||||
if(out != null){
|
||||
try {
|
||||
out.close();
|
||||
} catch (IOException e) {
|
||||
log.error(e.getMessage(),e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
closeStream(input, out);
|
||||
}
|
||||
|
||||
|
||||
|
||||
return picSrc;
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
private void closeStream(InputStream input, OutputStream out) {
|
||||
if (input != null) {
|
||||
input.close();
|
||||
}
|
||||
if (out != null) {
|
||||
out.close();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 判断文件是否为图片
|
||||
*
|
||||
* @param file 需要判断的文件
|
||||
* @return true:是图片,false:不是图片
|
||||
*/
|
||||
@SneakyThrows
|
||||
public boolean isImage(File file) {
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -1,163 +0,0 @@
|
||||
package com.java2nb.novel.core.utils;
|
||||
|
||||
|
||||
import java.lang.management.ManagementFactory;
|
||||
import java.net.InetAddress;
|
||||
import java.net.NetworkInterface;
|
||||
|
||||
/**
|
||||
* <p>名称:IdWorker.java</p>
|
||||
* <p>描述:分布式自增长ID</p>
|
||||
* <pre>
|
||||
* Twitter的 Snowflake JAVA实现方案
|
||||
* </pre>
|
||||
* 核心代码为其IdWorker这个类实现,其原理结构如下,我分别用一个0表示一位,用—分割开部分的作用:
|
||||
* 1||0---0000000000 0000000000 0000000000 0000000000 0 --- 00000 ---00000 ---000000000000
|
||||
* 在上面的字符串中,第一位为未使用(实际上也可作为long的符号位),接下来的41位为毫秒级时间,
|
||||
* 然后5位datacenter标识位,5位机器ID(并不算标识符,实际是为线程标识),
|
||||
* 然后12位该毫秒内的当前毫秒内的计数,加起来刚好64位,为一个Long型。
|
||||
* 这样的好处是,整体上按照时间自增排序,并且整个分布式系统内不会产生ID碰撞(由datacenter和机器ID作区分),
|
||||
* 并且效率较高,经测试,snowflake每秒能够产生26万ID左右,完全满足需要。
|
||||
* <p>
|
||||
* 64位ID (42(毫秒)+5(机器ID)+5(业务编码)+12(重复累加))
|
||||
*
|
||||
*/
|
||||
public class IdWorker {
|
||||
// 时间起始标记点,作为基准,一般取系统的最近时间(一旦确定不能变动)
|
||||
private final static long twepoch = 1288834974657L;
|
||||
// 机器标识位数
|
||||
private final static long workerIdBits = 5L;
|
||||
// 数据中心标识位数
|
||||
private final static long datacenterIdBits = 5L;
|
||||
// 机器ID最大值
|
||||
private final static long maxWorkerId = -1L ^ (-1L << workerIdBits);
|
||||
// 数据中心ID最大值
|
||||
private final static long maxDatacenterId = -1L ^ (-1L << datacenterIdBits);
|
||||
// 毫秒内自增位
|
||||
private final static long sequenceBits = 12L;
|
||||
// 机器ID偏左移12位
|
||||
private final static long workerIdShift = sequenceBits;
|
||||
// 数据中心ID左移17位
|
||||
private final static long datacenterIdShift = sequenceBits + workerIdBits;
|
||||
// 时间毫秒左移22位
|
||||
private final static long timestampLeftShift = sequenceBits + workerIdBits + datacenterIdBits;
|
||||
|
||||
private final static long sequenceMask = -1L ^ (-1L << sequenceBits);
|
||||
/* 上次生产id时间戳 */
|
||||
private static long lastTimestamp = -1L;
|
||||
// 0,并发控制
|
||||
private long sequence = 0L;
|
||||
|
||||
private final long workerId;
|
||||
// 数据标识id部分
|
||||
private final long datacenterId;
|
||||
|
||||
public IdWorker(){
|
||||
this.datacenterId = getDatacenterId(maxDatacenterId);
|
||||
this.workerId = getMaxWorkerId(datacenterId, maxWorkerId);
|
||||
}
|
||||
/**
|
||||
* @param workerId
|
||||
* 工作机器ID
|
||||
* @param datacenterId
|
||||
* 序列号
|
||||
*/
|
||||
public IdWorker(long workerId, long datacenterId) {
|
||||
if (workerId > maxWorkerId || workerId < 0) {
|
||||
throw new IllegalArgumentException(String.format("worker Id can't be greater than %d or less than 0", maxWorkerId));
|
||||
}
|
||||
if (datacenterId > maxDatacenterId || datacenterId < 0) {
|
||||
throw new IllegalArgumentException(String.format("datacenter Id can't be greater than %d or less than 0", maxDatacenterId));
|
||||
}
|
||||
this.workerId = workerId;
|
||||
this.datacenterId = datacenterId;
|
||||
}
|
||||
/**
|
||||
* 获取下一个ID
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public synchronized long nextId() {
|
||||
long timestamp = timeGen();
|
||||
if (timestamp < lastTimestamp) {
|
||||
throw new RuntimeException(String.format("Clock moved backwards. Refusing to generate id for %d milliseconds", lastTimestamp - timestamp));
|
||||
}
|
||||
|
||||
if (lastTimestamp == timestamp) {
|
||||
// 当前毫秒内,则+1
|
||||
sequence = (sequence + 1) & sequenceMask;
|
||||
if (sequence == 0) {
|
||||
// 当前毫秒内计数满了,则等待下一秒
|
||||
timestamp = tilNextMillis(lastTimestamp);
|
||||
}
|
||||
} else {
|
||||
sequence = 0L;
|
||||
}
|
||||
lastTimestamp = timestamp;
|
||||
// ID偏移组合生成最终的ID,并返回ID
|
||||
long nextId = ((timestamp - twepoch) << timestampLeftShift)
|
||||
| (datacenterId << datacenterIdShift)
|
||||
| (workerId << workerIdShift) | sequence;
|
||||
|
||||
return nextId;
|
||||
}
|
||||
|
||||
private long tilNextMillis(final long lastTimestamp) {
|
||||
long timestamp = this.timeGen();
|
||||
while (timestamp <= lastTimestamp) {
|
||||
timestamp = this.timeGen();
|
||||
}
|
||||
return timestamp;
|
||||
}
|
||||
|
||||
private long timeGen() {
|
||||
return System.currentTimeMillis();
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 获取 maxWorkerId
|
||||
* </p>
|
||||
*/
|
||||
protected static long getMaxWorkerId(long datacenterId, long maxWorkerId) {
|
||||
StringBuffer mpid = new StringBuffer();
|
||||
mpid.append(datacenterId);
|
||||
String name = ManagementFactory.getRuntimeMXBean().getName();
|
||||
if (!name.isEmpty()) {
|
||||
/*
|
||||
* GET jvmPid
|
||||
*/
|
||||
mpid.append(name.split("@")[0]);
|
||||
}
|
||||
/*
|
||||
* MAC + PID 的 hashcode 获取16个低位
|
||||
*/
|
||||
return (mpid.toString().hashCode() & 0xffff) % (maxWorkerId + 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 数据标识id部分
|
||||
* </p>
|
||||
*/
|
||||
protected static long getDatacenterId(long maxDatacenterId) {
|
||||
long id = 0L;
|
||||
try {
|
||||
InetAddress ip = InetAddress.getLocalHost();
|
||||
NetworkInterface network = NetworkInterface.getByInetAddress(ip);
|
||||
if (network == null) {
|
||||
id = 1L;
|
||||
} else {
|
||||
byte[] mac = network.getHardwareAddress();
|
||||
id = ((0x000000FF & (long) mac[mac.length - 1])
|
||||
| (0x0000FF00 & (((long) mac[mac.length - 2]) << 8))) >> 6;
|
||||
id = id % (maxDatacenterId + 1);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
System.out.println(" getDatacenterId: " + e.getMessage());
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -1,61 +0,0 @@
|
||||
package com.java2nb.novel.core.utils;
|
||||
|
||||
|
||||
import lombok.SneakyThrows;
|
||||
import sun.misc.BASE64Encoder;
|
||||
|
||||
import java.security.MessageDigest;
|
||||
|
||||
/**
|
||||
* @author 11797
|
||||
*/
|
||||
public class MD5Util {
|
||||
|
||||
private static final String DEFAUL_CHARSET = "utf-8" ;
|
||||
|
||||
private static String byteArrayToHexString(byte[] b) {
|
||||
StringBuffer resultSb = new StringBuffer();
|
||||
for (int i = 0; i < b.length; i++) {
|
||||
resultSb.append(byteToHexString(b[i]));
|
||||
}
|
||||
|
||||
return resultSb.toString();
|
||||
}
|
||||
|
||||
private static String byteToHexString(byte b) {
|
||||
int n = b;
|
||||
if (n < 0) {
|
||||
n += 256;
|
||||
}
|
||||
int d1 = n / 16;
|
||||
int d2 = n % 16;
|
||||
return HEX_DIGITS[d1] + HEX_DIGITS[d2];
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public static String MD5Encode(String origin,String charsetname) {
|
||||
MessageDigest md = MessageDigest.getInstance("MD5");
|
||||
if (charsetname == null || "".equals(charsetname)) {
|
||||
return byteArrayToHexString(md.digest(origin
|
||||
.getBytes()));
|
||||
} else {
|
||||
return byteArrayToHexString(md.digest(origin
|
||||
.getBytes(charsetname)));
|
||||
}
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public static String MD5New(String str) {
|
||||
//首先利用MD5算法将密码加密,变成等长字节
|
||||
MessageDigest md = MessageDigest.getInstance("MD5");
|
||||
byte[] b1 = md.digest(str.getBytes());
|
||||
//将等长字节利用Base64算法转换成字符串
|
||||
BASE64Encoder encoder = new BASE64Encoder();
|
||||
return encoder.encode(b1);
|
||||
}
|
||||
|
||||
private static final String[] HEX_DIGITS = {"0", "1", "2", "3", "4", "5",
|
||||
"6", "7", "8", "9", "a", "b", "c", "d", "e", "f"};
|
||||
|
||||
|
||||
}
|
@ -1,52 +0,0 @@
|
||||
package com.java2nb.novel.core.utils;
|
||||
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* @author Administrator
|
||||
*/
|
||||
@Component
|
||||
public class SpringUtil implements ApplicationContextAware {
|
||||
|
||||
|
||||
|
||||
private static ApplicationContext applicationContext;
|
||||
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext applicationContext) {
|
||||
if (SpringUtil.applicationContext == null) {
|
||||
SpringUtil.applicationContext = applicationContext;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取applicationContext
|
||||
* */
|
||||
public static ApplicationContext getApplicationContext() {
|
||||
return applicationContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过name获取 Bean.
|
||||
* */
|
||||
public static Object getBean(String name) {
|
||||
return getApplicationContext().getBean(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过class获取Bean
|
||||
* */
|
||||
public static <T> T getBean(Class<T> clazz) {
|
||||
return getApplicationContext().getBean(clazz);
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过name,以及Clazz返回指定的Bean
|
||||
* */
|
||||
public static <T> T getBean(String name, Class<T> clazz) {
|
||||
return getApplicationContext().getBean(name, clazz);
|
||||
}
|
||||
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
package com.java2nb.novel.core.utils;
|
||||
|
||||
/**
|
||||
* 线程工具类
|
||||
* @author Administrator
|
||||
*/
|
||||
public class ThreadUtil {
|
||||
|
||||
/**
|
||||
* 根据线程ID获取线程
|
||||
* */
|
||||
public static Thread findThread(long threadId) {
|
||||
ThreadGroup group = Thread.currentThread().getThreadGroup();
|
||||
while(group != null) {
|
||||
Thread[] threads = new Thread[(int)(group.activeCount() * 1.2)];
|
||||
int count = group.enumerate(threads, true);
|
||||
for(int i = 0; i < count; i++) {
|
||||
if(threadId == threads[i].getId()) {
|
||||
return threads[i];
|
||||
}
|
||||
}
|
||||
group = group.getParent();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
@ -1,96 +0,0 @@
|
||||
package com.java2nb.novel.core.utils;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author Administrator
|
||||
*/
|
||||
public class UUIDUtil {
|
||||
|
||||
public static final String[] CHARS = new String[] { "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l",
|
||||
"m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "0", "1", "2", "3", "4", "5", "6",
|
||||
"7", "8", "9", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R",
|
||||
"S", "T", "U", "V", "W", "X", "Y", "Z" };
|
||||
|
||||
/**
|
||||
* 生成指定长度的uuid
|
||||
*
|
||||
* @param length
|
||||
* @return
|
||||
*/
|
||||
private static String getUUID(int length, UUID uuid) {
|
||||
int groupLength = 32 / length;
|
||||
StringBuilder sb = new StringBuilder();
|
||||
String id = uuid.toString().replace("-", "");
|
||||
for (int i = 0; i < length; i++) {
|
||||
String str = id.substring(i * groupLength, i * groupLength + groupLength);
|
||||
int x = Integer.parseInt(str, 16);
|
||||
sb.append(CHARS[x % 0x3E]);
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 8位UUID
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static String getUUID8() {
|
||||
return getUUID(8, UUID.randomUUID());
|
||||
}
|
||||
|
||||
/**
|
||||
* 8位UUID
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static String getUUID8(byte[] bytes) {
|
||||
return getUUID(8, UUID.nameUUIDFromBytes(bytes));
|
||||
}
|
||||
|
||||
/**
|
||||
* 8位UUID
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static String getUUID8(String fromString) {
|
||||
return getUUID(8, UUID.fromString(fromString));
|
||||
}
|
||||
|
||||
/**
|
||||
* 16位UUID
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static String getUUID16() {
|
||||
return getUUID(16, UUID.randomUUID());
|
||||
}
|
||||
|
||||
/**
|
||||
* 16位UUID
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static String getUUID16(String fromString) {
|
||||
return getUUID(16, UUID.fromString(fromString));
|
||||
}
|
||||
|
||||
/**
|
||||
* 16位UUID
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static String getUUID16(byte[] bytes) {
|
||||
return getUUID(16, UUID.nameUUIDFromBytes(bytes));
|
||||
}
|
||||
|
||||
/**
|
||||
* 32位UUID
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static String getUUID32() {
|
||||
return UUID.randomUUID().toString().replace("-", "");
|
||||
}
|
||||
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
package com.java2nb.novel.core.valid;
|
||||
|
||||
/**
|
||||
* 新增数据的校验分组
|
||||
* @author xiongxiaoyang
|
||||
*/
|
||||
public interface AddGroup {
|
||||
|
||||
|
||||
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
package com.java2nb.novel.core.valid;
|
||||
|
||||
/**
|
||||
* 更新数据的校验分组
|
||||
* @author xiongxiaoyang
|
||||
*/
|
||||
public interface UpdateGroup {
|
||||
|
||||
|
||||
|
||||
}
|
@ -25,6 +25,9 @@ public class BookIndex {
|
||||
@Generated("org.mybatis.generator.api.MyBatisGenerator")
|
||||
private Integer bookPrice;
|
||||
|
||||
@Generated("org.mybatis.generator.api.MyBatisGenerator")
|
||||
private String storageType;
|
||||
|
||||
@Generated("org.mybatis.generator.api.MyBatisGenerator")
|
||||
private Date createTime;
|
||||
|
||||
@ -101,6 +104,16 @@ public class BookIndex {
|
||||
this.bookPrice = bookPrice;
|
||||
}
|
||||
|
||||
@Generated("org.mybatis.generator.api.MyBatisGenerator")
|
||||
public String getStorageType() {
|
||||
return storageType;
|
||||
}
|
||||
|
||||
@Generated("org.mybatis.generator.api.MyBatisGenerator")
|
||||
public void setStorageType(String storageType) {
|
||||
this.storageType = storageType == null ? null : storageType.trim();
|
||||
}
|
||||
|
||||
@Generated("org.mybatis.generator.api.MyBatisGenerator")
|
||||
public Date getCreateTime() {
|
||||
return createTime;
|
||||
|
@ -1,11 +1,11 @@
|
||||
package com.java2nb.novel.entity;
|
||||
|
||||
|
||||
import javax.annotation.Generated;
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
import javax.annotation.Generated;
|
||||
|
||||
public class News implements Serializable {
|
||||
|
||||
@Generated("org.mybatis.generator.api.MyBatisGenerator")
|
||||
private Long id;
|
||||
|
||||
@ -21,6 +21,9 @@ public class News implements Serializable {
|
||||
@Generated("org.mybatis.generator.api.MyBatisGenerator")
|
||||
private String title;
|
||||
|
||||
@Generated("org.mybatis.generator.api.MyBatisGenerator")
|
||||
private Long readCount;
|
||||
|
||||
@Generated("org.mybatis.generator.api.MyBatisGenerator")
|
||||
private Date createTime;
|
||||
|
||||
@ -86,6 +89,16 @@ public class News implements Serializable {
|
||||
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")
|
||||
public Date getCreateTime() {
|
||||
return createTime;
|
||||
@ -135,4 +148,4 @@ public class News implements Serializable {
|
||||
public void setContent(String content) {
|
||||
this.content = content == null ? null : content.trim();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,11 +1,11 @@
|
||||
package com.java2nb.novel.entity;
|
||||
|
||||
import com.java2nb.novel.core.valid.AddGroup;
|
||||
import com.java2nb.novel.core.valid.UpdateGroup;
|
||||
import io.github.xxyopen.web.valid.AddGroup;
|
||||
import io.github.xxyopen.web.valid.UpdateGroup;
|
||||
|
||||
import java.util.Date;
|
||||
import javax.annotation.Generated;
|
||||
import javax.validation.constraints.*;
|
||||
import java.util.Date;
|
||||
|
||||
public class User {
|
||||
|
||||
|
@ -31,6 +31,9 @@ public final class BookIndexDynamicSqlSupport {
|
||||
@Generated("org.mybatis.generator.api.MyBatisGenerator")
|
||||
public static final SqlColumn<Integer> bookPrice = bookIndex.bookPrice;
|
||||
|
||||
@Generated("org.mybatis.generator.api.MyBatisGenerator")
|
||||
public static final SqlColumn<String> storageType = bookIndex.storageType;
|
||||
|
||||
@Generated("org.mybatis.generator.api.MyBatisGenerator")
|
||||
public static final SqlColumn<Date> createTime = bookIndex.createTime;
|
||||
|
||||
@ -53,6 +56,8 @@ public final class BookIndexDynamicSqlSupport {
|
||||
|
||||
public final SqlColumn<Integer> bookPrice = column("book_price", JDBCType.INTEGER);
|
||||
|
||||
public final SqlColumn<String> storageType = column("storage_type", JDBCType.VARCHAR);
|
||||
|
||||
public final SqlColumn<Date> createTime = column("create_time", JDBCType.TIMESTAMP);
|
||||
|
||||
public final SqlColumn<Date> updateTime = column("update_time", JDBCType.TIMESTAMP);
|
||||
|
@ -37,46 +37,47 @@ import org.mybatis.dynamic.sql.util.mybatis3.MyBatis3Utils;
|
||||
@Mapper
|
||||
public interface BookIndexMapper {
|
||||
@Generated("org.mybatis.generator.api.MyBatisGenerator")
|
||||
BasicColumn[] selectList = BasicColumn.columnList(id, bookId, indexNum, indexName, wordCount, isVip, bookPrice, createTime, updateTime);
|
||||
BasicColumn[] selectList = BasicColumn.columnList(id, bookId, indexNum, indexName, wordCount, isVip, bookPrice, storageType, createTime, updateTime);
|
||||
|
||||
@Generated("org.mybatis.generator.api.MyBatisGenerator")
|
||||
@SelectProvider(type = SqlProviderAdapter.class, method = "select")
|
||||
@SelectProvider(type=SqlProviderAdapter.class, method="select")
|
||||
long count(SelectStatementProvider selectStatement);
|
||||
|
||||
@Generated("org.mybatis.generator.api.MyBatisGenerator")
|
||||
@DeleteProvider(type = SqlProviderAdapter.class, method = "delete")
|
||||
@DeleteProvider(type=SqlProviderAdapter.class, method="delete")
|
||||
int delete(DeleteStatementProvider deleteStatement);
|
||||
|
||||
@Generated("org.mybatis.generator.api.MyBatisGenerator")
|
||||
@InsertProvider(type = SqlProviderAdapter.class, method = "insert")
|
||||
@InsertProvider(type=SqlProviderAdapter.class, method="insert")
|
||||
int insert(InsertStatementProvider<BookIndex> insertStatement);
|
||||
|
||||
@Generated("org.mybatis.generator.api.MyBatisGenerator")
|
||||
@InsertProvider(type = SqlProviderAdapter.class, method = "insertMultiple")
|
||||
@InsertProvider(type=SqlProviderAdapter.class, method="insertMultiple")
|
||||
int insertMultiple(MultiRowInsertStatementProvider<BookIndex> multipleInsertStatement);
|
||||
|
||||
@Generated("org.mybatis.generator.api.MyBatisGenerator")
|
||||
@SelectProvider(type = SqlProviderAdapter.class, method = "select")
|
||||
@SelectProvider(type=SqlProviderAdapter.class, method="select")
|
||||
@ResultMap("BookIndexResult")
|
||||
Optional<BookIndex> selectOne(SelectStatementProvider selectStatement);
|
||||
|
||||
@Generated("org.mybatis.generator.api.MyBatisGenerator")
|
||||
@SelectProvider(type = SqlProviderAdapter.class, method = "select")
|
||||
@Results(id = "BookIndexResult", value = {
|
||||
@Result(column = "id", property = "id", jdbcType = JdbcType.BIGINT, id = true),
|
||||
@Result(column = "book_id", property = "bookId", jdbcType = JdbcType.BIGINT),
|
||||
@Result(column = "index_num", property = "indexNum", jdbcType = JdbcType.INTEGER),
|
||||
@Result(column = "index_name", property = "indexName", jdbcType = JdbcType.VARCHAR),
|
||||
@Result(column = "word_count", property = "wordCount", jdbcType = JdbcType.INTEGER),
|
||||
@Result(column = "is_vip", property = "isVip", jdbcType = JdbcType.TINYINT),
|
||||
@Result(column = "book_price", property = "bookPrice", jdbcType = JdbcType.INTEGER),
|
||||
@Result(column = "create_time", property = "createTime", jdbcType = JdbcType.TIMESTAMP),
|
||||
@Result(column = "update_time", property = "updateTime", jdbcType = JdbcType.TIMESTAMP)
|
||||
@SelectProvider(type=SqlProviderAdapter.class, method="select")
|
||||
@Results(id="BookIndexResult", value = {
|
||||
@Result(column="id", property="id", jdbcType=JdbcType.BIGINT, id=true),
|
||||
@Result(column="book_id", property="bookId", jdbcType=JdbcType.BIGINT),
|
||||
@Result(column="index_num", property="indexNum", jdbcType=JdbcType.INTEGER),
|
||||
@Result(column="index_name", property="indexName", jdbcType=JdbcType.VARCHAR),
|
||||
@Result(column="word_count", property="wordCount", jdbcType=JdbcType.INTEGER),
|
||||
@Result(column="is_vip", property="isVip", jdbcType=JdbcType.TINYINT),
|
||||
@Result(column="book_price", property="bookPrice", jdbcType=JdbcType.INTEGER),
|
||||
@Result(column="storage_type", property="storageType", jdbcType=JdbcType.VARCHAR),
|
||||
@Result(column="create_time", property="createTime", jdbcType=JdbcType.TIMESTAMP),
|
||||
@Result(column="update_time", property="updateTime", jdbcType=JdbcType.TIMESTAMP)
|
||||
})
|
||||
List<BookIndex> selectMany(SelectStatementProvider selectStatement);
|
||||
|
||||
@Generated("org.mybatis.generator.api.MyBatisGenerator")
|
||||
@UpdateProvider(type = SqlProviderAdapter.class, method = "update")
|
||||
@UpdateProvider(type=SqlProviderAdapter.class, method="update")
|
||||
int update(UpdateStatementProvider updateStatement);
|
||||
|
||||
@Generated("org.mybatis.generator.api.MyBatisGenerator")
|
||||
@ -92,52 +93,55 @@ public interface BookIndexMapper {
|
||||
@Generated("org.mybatis.generator.api.MyBatisGenerator")
|
||||
default int deleteByPrimaryKey(Long id_) {
|
||||
return delete(c ->
|
||||
c.where(id, isEqualTo(id_))
|
||||
c.where(id, isEqualTo(id_))
|
||||
);
|
||||
}
|
||||
|
||||
@Generated("org.mybatis.generator.api.MyBatisGenerator")
|
||||
default int insert(BookIndex record) {
|
||||
return MyBatis3Utils.insert(this::insert, record, bookIndex, c ->
|
||||
c.map(id).toProperty("id")
|
||||
.map(bookId).toProperty("bookId")
|
||||
.map(indexNum).toProperty("indexNum")
|
||||
.map(indexName).toProperty("indexName")
|
||||
.map(wordCount).toProperty("wordCount")
|
||||
.map(isVip).toProperty("isVip")
|
||||
.map(bookPrice).toProperty("bookPrice")
|
||||
.map(createTime).toProperty("createTime")
|
||||
.map(updateTime).toProperty("updateTime")
|
||||
c.map(id).toProperty("id")
|
||||
.map(bookId).toProperty("bookId")
|
||||
.map(indexNum).toProperty("indexNum")
|
||||
.map(indexName).toProperty("indexName")
|
||||
.map(wordCount).toProperty("wordCount")
|
||||
.map(isVip).toProperty("isVip")
|
||||
.map(bookPrice).toProperty("bookPrice")
|
||||
.map(storageType).toProperty("storageType")
|
||||
.map(createTime).toProperty("createTime")
|
||||
.map(updateTime).toProperty("updateTime")
|
||||
);
|
||||
}
|
||||
|
||||
@Generated("org.mybatis.generator.api.MyBatisGenerator")
|
||||
default int insertMultiple(Collection<BookIndex> records) {
|
||||
return MyBatis3Utils.insertMultiple(this::insertMultiple, records, bookIndex, c ->
|
||||
c.map(id).toProperty("id")
|
||||
.map(bookId).toProperty("bookId")
|
||||
.map(indexNum).toProperty("indexNum")
|
||||
.map(indexName).toProperty("indexName")
|
||||
.map(wordCount).toProperty("wordCount")
|
||||
.map(isVip).toProperty("isVip")
|
||||
.map(bookPrice).toProperty("bookPrice")
|
||||
.map(createTime).toProperty("createTime")
|
||||
.map(updateTime).toProperty("updateTime")
|
||||
c.map(id).toProperty("id")
|
||||
.map(bookId).toProperty("bookId")
|
||||
.map(indexNum).toProperty("indexNum")
|
||||
.map(indexName).toProperty("indexName")
|
||||
.map(wordCount).toProperty("wordCount")
|
||||
.map(isVip).toProperty("isVip")
|
||||
.map(bookPrice).toProperty("bookPrice")
|
||||
.map(storageType).toProperty("storageType")
|
||||
.map(createTime).toProperty("createTime")
|
||||
.map(updateTime).toProperty("updateTime")
|
||||
);
|
||||
}
|
||||
|
||||
@Generated("org.mybatis.generator.api.MyBatisGenerator")
|
||||
default int insertSelective(BookIndex record) {
|
||||
return MyBatis3Utils.insert(this::insert, record, bookIndex, c ->
|
||||
c.map(id).toPropertyWhenPresent("id", record::getId)
|
||||
.map(bookId).toPropertyWhenPresent("bookId", record::getBookId)
|
||||
.map(indexNum).toPropertyWhenPresent("indexNum", record::getIndexNum)
|
||||
.map(indexName).toPropertyWhenPresent("indexName", record::getIndexName)
|
||||
.map(wordCount).toPropertyWhenPresent("wordCount", record::getWordCount)
|
||||
.map(isVip).toPropertyWhenPresent("isVip", record::getIsVip)
|
||||
.map(bookPrice).toPropertyWhenPresent("bookPrice", record::getBookPrice)
|
||||
.map(createTime).toPropertyWhenPresent("createTime", record::getCreateTime)
|
||||
.map(updateTime).toPropertyWhenPresent("updateTime", record::getUpdateTime)
|
||||
c.map(id).toPropertyWhenPresent("id", record::getId)
|
||||
.map(bookId).toPropertyWhenPresent("bookId", record::getBookId)
|
||||
.map(indexNum).toPropertyWhenPresent("indexNum", record::getIndexNum)
|
||||
.map(indexName).toPropertyWhenPresent("indexName", record::getIndexName)
|
||||
.map(wordCount).toPropertyWhenPresent("wordCount", record::getWordCount)
|
||||
.map(isVip).toPropertyWhenPresent("isVip", record::getIsVip)
|
||||
.map(bookPrice).toPropertyWhenPresent("bookPrice", record::getBookPrice)
|
||||
.map(storageType).toPropertyWhenPresent("storageType", record::getStorageType)
|
||||
.map(createTime).toPropertyWhenPresent("createTime", record::getCreateTime)
|
||||
.map(updateTime).toPropertyWhenPresent("updateTime", record::getUpdateTime)
|
||||
);
|
||||
}
|
||||
|
||||
@ -159,7 +163,7 @@ public interface BookIndexMapper {
|
||||
@Generated("org.mybatis.generator.api.MyBatisGenerator")
|
||||
default Optional<BookIndex> selectByPrimaryKey(Long id_) {
|
||||
return selectOne(c ->
|
||||
c.where(id, isEqualTo(id_))
|
||||
c.where(id, isEqualTo(id_))
|
||||
);
|
||||
}
|
||||
|
||||
@ -177,6 +181,7 @@ public interface BookIndexMapper {
|
||||
.set(wordCount).equalTo(record::getWordCount)
|
||||
.set(isVip).equalTo(record::getIsVip)
|
||||
.set(bookPrice).equalTo(record::getBookPrice)
|
||||
.set(storageType).equalTo(record::getStorageType)
|
||||
.set(createTime).equalTo(record::getCreateTime)
|
||||
.set(updateTime).equalTo(record::getUpdateTime);
|
||||
}
|
||||
@ -190,6 +195,7 @@ public interface BookIndexMapper {
|
||||
.set(wordCount).equalToWhenPresent(record::getWordCount)
|
||||
.set(isVip).equalToWhenPresent(record::getIsVip)
|
||||
.set(bookPrice).equalToWhenPresent(record::getBookPrice)
|
||||
.set(storageType).equalToWhenPresent(record::getStorageType)
|
||||
.set(createTime).equalToWhenPresent(record::getCreateTime)
|
||||
.set(updateTime).equalToWhenPresent(record::getUpdateTime);
|
||||
}
|
||||
@ -197,30 +203,32 @@ public interface BookIndexMapper {
|
||||
@Generated("org.mybatis.generator.api.MyBatisGenerator")
|
||||
default int updateByPrimaryKey(BookIndex record) {
|
||||
return update(c ->
|
||||
c.set(bookId).equalTo(record::getBookId)
|
||||
.set(indexNum).equalTo(record::getIndexNum)
|
||||
.set(indexName).equalTo(record::getIndexName)
|
||||
.set(wordCount).equalTo(record::getWordCount)
|
||||
.set(isVip).equalTo(record::getIsVip)
|
||||
.set(bookPrice).equalTo(record::getBookPrice)
|
||||
.set(createTime).equalTo(record::getCreateTime)
|
||||
.set(updateTime).equalTo(record::getUpdateTime)
|
||||
.where(id, isEqualTo(record::getId))
|
||||
c.set(bookId).equalTo(record::getBookId)
|
||||
.set(indexNum).equalTo(record::getIndexNum)
|
||||
.set(indexName).equalTo(record::getIndexName)
|
||||
.set(wordCount).equalTo(record::getWordCount)
|
||||
.set(isVip).equalTo(record::getIsVip)
|
||||
.set(bookPrice).equalTo(record::getBookPrice)
|
||||
.set(storageType).equalTo(record::getStorageType)
|
||||
.set(createTime).equalTo(record::getCreateTime)
|
||||
.set(updateTime).equalTo(record::getUpdateTime)
|
||||
.where(id, isEqualTo(record::getId))
|
||||
);
|
||||
}
|
||||
|
||||
@Generated("org.mybatis.generator.api.MyBatisGenerator")
|
||||
default int updateByPrimaryKeySelective(BookIndex record) {
|
||||
return update(c ->
|
||||
c.set(bookId).equalToWhenPresent(record::getBookId)
|
||||
.set(indexNum).equalToWhenPresent(record::getIndexNum)
|
||||
.set(indexName).equalToWhenPresent(record::getIndexName)
|
||||
.set(wordCount).equalToWhenPresent(record::getWordCount)
|
||||
.set(isVip).equalToWhenPresent(record::getIsVip)
|
||||
.set(bookPrice).equalToWhenPresent(record::getBookPrice)
|
||||
.set(createTime).equalToWhenPresent(record::getCreateTime)
|
||||
.set(updateTime).equalToWhenPresent(record::getUpdateTime)
|
||||
.where(id, isEqualTo(record::getId))
|
||||
c.set(bookId).equalToWhenPresent(record::getBookId)
|
||||
.set(indexNum).equalToWhenPresent(record::getIndexNum)
|
||||
.set(indexName).equalToWhenPresent(record::getIndexName)
|
||||
.set(wordCount).equalToWhenPresent(record::getWordCount)
|
||||
.set(isVip).equalToWhenPresent(record::getIsVip)
|
||||
.set(bookPrice).equalToWhenPresent(record::getBookPrice)
|
||||
.set(storageType).equalToWhenPresent(record::getStorageType)
|
||||
.set(createTime).equalToWhenPresent(record::getCreateTime)
|
||||
.set(updateTime).equalToWhenPresent(record::getUpdateTime)
|
||||
.where(id, isEqualTo(record::getId))
|
||||
);
|
||||
}
|
||||
}
|
@ -25,6 +25,9 @@ public final class NewsDynamicSqlSupport {
|
||||
@Generated("org.mybatis.generator.api.MyBatisGenerator")
|
||||
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")
|
||||
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<Long> readCount = column("read_count", JDBCType.BIGINT);
|
||||
|
||||
public final SqlColumn<Date> createTime = column("create_time", JDBCType.TIMESTAMP);
|
||||
|
||||
public final SqlColumn<Long> createUserId = column("create_user_id", JDBCType.BIGINT);
|
||||
|
@ -35,7 +35,7 @@ import org.mybatis.dynamic.sql.util.mybatis3.MyBatis3Utils;
|
||||
@Mapper
|
||||
public interface NewsMapper {
|
||||
@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")
|
||||
@SelectProvider(type=SqlProviderAdapter.class, method="select")
|
||||
@ -66,6 +66,7 @@ public interface NewsMapper {
|
||||
@Result(column="cat_name", property="catName", jdbcType=JdbcType.VARCHAR),
|
||||
@Result(column="source_name", property="sourceName", 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_user_id", property="createUserId", jdbcType=JdbcType.BIGINT),
|
||||
@Result(column="update_time", property="updateTime", jdbcType=JdbcType.TIMESTAMP),
|
||||
@ -103,6 +104,7 @@ public interface NewsMapper {
|
||||
.map(catName).toProperty("catName")
|
||||
.map(sourceName).toProperty("sourceName")
|
||||
.map(title).toProperty("title")
|
||||
.map(readCount).toProperty("readCount")
|
||||
.map(createTime).toProperty("createTime")
|
||||
.map(createUserId).toProperty("createUserId")
|
||||
.map(updateTime).toProperty("updateTime")
|
||||
@ -119,6 +121,7 @@ public interface NewsMapper {
|
||||
.map(catName).toProperty("catName")
|
||||
.map(sourceName).toProperty("sourceName")
|
||||
.map(title).toProperty("title")
|
||||
.map(readCount).toProperty("readCount")
|
||||
.map(createTime).toProperty("createTime")
|
||||
.map(createUserId).toProperty("createUserId")
|
||||
.map(updateTime).toProperty("updateTime")
|
||||
@ -135,6 +138,7 @@ public interface NewsMapper {
|
||||
.map(catName).toPropertyWhenPresent("catName", record::getCatName)
|
||||
.map(sourceName).toPropertyWhenPresent("sourceName", record::getSourceName)
|
||||
.map(title).toPropertyWhenPresent("title", record::getTitle)
|
||||
.map(readCount).toPropertyWhenPresent("readCount", record::getReadCount)
|
||||
.map(createTime).toPropertyWhenPresent("createTime", record::getCreateTime)
|
||||
.map(createUserId).toPropertyWhenPresent("createUserId", record::getCreateUserId)
|
||||
.map(updateTime).toPropertyWhenPresent("updateTime", record::getUpdateTime)
|
||||
@ -177,6 +181,7 @@ public interface NewsMapper {
|
||||
.set(catName).equalTo(record::getCatName)
|
||||
.set(sourceName).equalTo(record::getSourceName)
|
||||
.set(title).equalTo(record::getTitle)
|
||||
.set(readCount).equalTo(record::getReadCount)
|
||||
.set(createTime).equalTo(record::getCreateTime)
|
||||
.set(createUserId).equalTo(record::getCreateUserId)
|
||||
.set(updateTime).equalTo(record::getUpdateTime)
|
||||
@ -191,6 +196,7 @@ public interface NewsMapper {
|
||||
.set(catName).equalToWhenPresent(record::getCatName)
|
||||
.set(sourceName).equalToWhenPresent(record::getSourceName)
|
||||
.set(title).equalToWhenPresent(record::getTitle)
|
||||
.set(readCount).equalToWhenPresent(record::getReadCount)
|
||||
.set(createTime).equalToWhenPresent(record::getCreateTime)
|
||||
.set(createUserId).equalToWhenPresent(record::getCreateUserId)
|
||||
.set(updateTime).equalToWhenPresent(record::getUpdateTime)
|
||||
@ -205,6 +211,7 @@ public interface NewsMapper {
|
||||
.set(catName).equalTo(record::getCatName)
|
||||
.set(sourceName).equalTo(record::getSourceName)
|
||||
.set(title).equalTo(record::getTitle)
|
||||
.set(readCount).equalTo(record::getReadCount)
|
||||
.set(createTime).equalTo(record::getCreateTime)
|
||||
.set(createUserId).equalTo(record::getCreateUserId)
|
||||
.set(updateTime).equalTo(record::getUpdateTime)
|
||||
@ -221,6 +228,7 @@ public interface NewsMapper {
|
||||
.set(catName).equalToWhenPresent(record::getCatName)
|
||||
.set(sourceName).equalToWhenPresent(record::getSourceName)
|
||||
.set(title).equalToWhenPresent(record::getTitle)
|
||||
.set(readCount).equalToWhenPresent(record::getReadCount)
|
||||
.set(createTime).equalToWhenPresent(record::getCreateTime)
|
||||
.set(createUserId).equalToWhenPresent(record::getCreateUserId)
|
||||
.set(updateTime).equalToWhenPresent(record::getUpdateTime)
|
||||
|
@ -71,3 +71,7 @@ sharding:
|
||||
|
||||
|
||||
|
||||
content:
|
||||
save:
|
||||
storage: db #存储介质,db:数据库,file:txt文本
|
||||
path: /Users/xiongxiaoyang/books #txt小说文本保存路径
|
@ -74,7 +74,10 @@ logging:
|
||||
|
||||
|
||||
|
||||
|
||||
content:
|
||||
save:
|
||||
storage: db #存储介质,db:数据库,file:txt文本
|
||||
path: /Users/xiongxiaoyang/books #txt小说文本保存路径
|
||||
|
||||
|
||||
|
||||
|
@ -11,6 +11,11 @@ spring:
|
||||
generator:
|
||||
write-numbers-as-strings: true
|
||||
|
||||
#上传文件的最大值(1M)
|
||||
servlet:
|
||||
multipart:
|
||||
max-file-size: 1048576
|
||||
|
||||
#缓存类型,ehcache(默认)、redis
|
||||
cache:
|
||||
type: ehcache
|
||||
@ -26,3 +31,5 @@ logging:
|
||||
config: classpath:logback-boot.xml
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -44,7 +44,7 @@
|
||||
</javaClientGenerator>
|
||||
|
||||
<!--生成全部表tableName设为%-->
|
||||
<table tableName="book"/>
|
||||
<table tableName="book_index"/>
|
||||
|
||||
<!-- 指定数据库表 -->
|
||||
<!--<table schema="jly" tableName="job_position" domainObjectName="JobPositionTest"/>-->
|
||||
|
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>novel</artifactId>
|
||||
<groupId>com.java2nb</groupId>
|
||||
<version>3.5.1</version>
|
||||
<version>3.6.1</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@ -35,8 +35,44 @@
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-antrun-plugin</artifactId>
|
||||
<version>1.8</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>run</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<tasks>
|
||||
<!-- 文件夹 -->
|
||||
<copy todir="${project.build.directory}/build/config" overwrite="true">
|
||||
<fileset dir="${basedir}/src/main/build/config">
|
||||
<include name="*.*"/>
|
||||
</fileset>
|
||||
</copy>
|
||||
<copy file="${project.build.directory}/${project.artifactId}-${project.version}.jar"
|
||||
tofile="${project.build.directory}/build/${project.artifactId}.jar"/>
|
||||
|
||||
<fixcrlf srcdir="${basedir}/src/main/build/scripts" eol="unix"/>
|
||||
<copy todir="${project.build.directory}/build/bin">
|
||||
<fileset dir="${basedir}/src/main/build/scripts">
|
||||
<include name="*.sh"/>
|
||||
<include name="*.txt"/>
|
||||
<include name="*.bat"/>
|
||||
</fileset>
|
||||
</copy>
|
||||
<zip destfile='${project.build.directory}/build/${project.artifactId}.zip'>
|
||||
<zipfileset filemode="755" dir='${project.build.directory}/build/'/>
|
||||
</zip>
|
||||
</tasks>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
|
||||
</project>
|
||||
</project>
|
||||
|
@ -0,0 +1,39 @@
|
||||
#端口号
|
||||
server:
|
||||
port: 8083
|
||||
|
||||
#不分表的数据库配置
|
||||
spring:
|
||||
datasource:
|
||||
url: jdbc:mysql://127.0.0.1:3306/novel_plus?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai
|
||||
username: root
|
||||
password: root
|
||||
|
||||
####使用shardingJdbc时,
|
||||
####所有的jdbcType都不能是LONGVARCHAR,否则会导致java.io.NotSerializableException: java.io.StringReader错误
|
||||
##### 应该替换所有的 LONGVARCHAR 类型为VARCHAR
|
||||
sharding:
|
||||
jdbc:
|
||||
datasource:
|
||||
ds0:
|
||||
jdbc-url: jdbc:mysql://localhost:3306/novel_plus?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai
|
||||
username: root
|
||||
password: test123456
|
||||
|
||||
#登录用户名密码
|
||||
admin:
|
||||
username: admin
|
||||
password: admin
|
||||
#
|
||||
##爬虫自动更新的线程数
|
||||
##建议小说数量不多或者正在运行新书入库爬虫的情况下设置为1即可
|
||||
##随着小说数量的增多可以逐渐增加,但建议不要超出CPU的线程数
|
||||
crawl:
|
||||
update:
|
||||
thread: 1
|
||||
|
||||
#小说内容保存配置
|
||||
content:
|
||||
save:
|
||||
storage: db #存储介质,db:数据库,file:txt文本
|
||||
path: /Users/xiongxiaoyang/books #txt小说文本保存路径
|
94
novel-crawl/src/main/build/scripts/novel-crawl.sh
Normal file
94
novel-crawl/src/main/build/scripts/novel-crawl.sh
Normal file
@ -0,0 +1,94 @@
|
||||
#!/bin/sh
|
||||
APP_NAME=novel-crawl
|
||||
JAR_NAME=$APP_NAME\.jar
|
||||
#PID 代表是PID文件
|
||||
PID=$APP_NAME\.pid
|
||||
|
||||
|
||||
#使用说明,用来提示输入参数
|
||||
usage() {
|
||||
echo "Usage: ./novel-crawl.sh [start|stop|restart|status]"
|
||||
exit 1
|
||||
}
|
||||
|
||||
#检查程序是否在运行
|
||||
is_exist(){
|
||||
pid=`ps -ef|grep $JAR_NAME|grep -v grep|awk '{print $2}' `
|
||||
#如果不存在返回1,存在返回0
|
||||
if [ -z "${pid}" ]; then
|
||||
return 1
|
||||
else
|
||||
return 0
|
||||
fi
|
||||
}
|
||||
|
||||
#启动方法
|
||||
start(){
|
||||
is_exist
|
||||
if [ $? -eq "0" ]; then
|
||||
echo ">>> 小说精品屋爬虫正在运行 PID = ${pid} <<<"
|
||||
else
|
||||
echo ">>> 小说精品屋爬虫开始启动 <<<"
|
||||
nohup java -jar -Dspring.profiles.active=prod $JAR_NAME >/dev/null 2>&1 &
|
||||
sleep 10
|
||||
echo $! > $PID
|
||||
echo ">>> 小说精品屋爬虫启动完成 PID = $! <<<"
|
||||
status
|
||||
fi
|
||||
}
|
||||
|
||||
#停止方法
|
||||
stop(){
|
||||
#is_exist
|
||||
pidf=$(cat $PID)
|
||||
#echo "$pidf"
|
||||
echo ">>> 小说精品屋爬虫 PID = $pidf 开始停止 <<<"
|
||||
kill $pidf
|
||||
rm -rf $PID
|
||||
sleep 2
|
||||
is_exist
|
||||
if [ $? -eq "0" ]; then
|
||||
echo ">>> 小说精品屋爬虫 PID = $pid 开始强制停止 <<<"
|
||||
kill -9 $pid
|
||||
sleep 2
|
||||
status
|
||||
else
|
||||
status
|
||||
fi
|
||||
}
|
||||
|
||||
#输出运行状态
|
||||
status(){
|
||||
is_exist
|
||||
if [ $? -eq "0" ]; then
|
||||
echo ">>> 小说精品屋爬虫正在运行 PID = ${pid} <<<"
|
||||
else
|
||||
echo ">>> 小说精品屋爬虫没有运行 <<<"
|
||||
fi
|
||||
}
|
||||
|
||||
#重启
|
||||
restart(){
|
||||
stop
|
||||
start
|
||||
}
|
||||
|
||||
#根据输入参数,选择执行对应方法,不输入则执行使用说明
|
||||
case "$1" in
|
||||
"start")
|
||||
start
|
||||
;;
|
||||
"stop")
|
||||
stop
|
||||
;;
|
||||
"status")
|
||||
status
|
||||
;;
|
||||
"restart")
|
||||
restart
|
||||
;;
|
||||
*)
|
||||
usage
|
||||
;;
|
||||
esac
|
||||
exit 0
|
@ -1,12 +1,18 @@
|
||||
package com.java2nb.novel;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.mybatis.spring.annotation.MapperScan;
|
||||
import org.springframework.boot.CommandLineRunner;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.web.servlet.ServletComponentScan;
|
||||
import org.springframework.cache.annotation.EnableCaching;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.scheduling.annotation.EnableScheduling;
|
||||
|
||||
import java.net.InetAddress;
|
||||
|
||||
/**
|
||||
* @author Administrator
|
||||
*/
|
||||
@ -15,11 +21,19 @@ import org.springframework.scheduling.annotation.EnableScheduling;
|
||||
@EnableScheduling
|
||||
@ServletComponentScan
|
||||
@MapperScan(basePackages = {"com.java2nb.novel.mapper"})
|
||||
@Slf4j
|
||||
public class CrawlNovelApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(CrawlNovelApplication.class);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public CommandLineRunner commandLineRunner(ApplicationContext ctx) {
|
||||
return args -> {
|
||||
log.info("项目启动啦,访问路径:{}", "http://" + InetAddress.getLocalHost().getHostAddress() + ":" + ctx.getEnvironment().getProperty("server.port"));
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -1,16 +1,22 @@
|
||||
package com.java2nb.novel.controller;
|
||||
|
||||
import com.github.pagehelper.PageInfo;
|
||||
import com.java2nb.novel.core.bean.ResultBean;
|
||||
import com.java2nb.novel.core.utils.BeanUtil;
|
||||
import com.java2nb.novel.core.cache.CacheKey;
|
||||
import com.java2nb.novel.core.cache.CacheService;
|
||||
import com.java2nb.novel.core.utils.HttpUtil;
|
||||
import io.github.xxyopen.model.page.PageBean;
|
||||
|
||||
import com.java2nb.novel.entity.CrawlSingleTask;
|
||||
import com.java2nb.novel.entity.CrawlSource;
|
||||
import com.java2nb.novel.service.CrawlService;
|
||||
import com.java2nb.novel.vo.CrawlSingleTaskVO;
|
||||
import com.java2nb.novel.vo.CrawlSourceVO;
|
||||
import io.github.xxyopen.model.resp.RestResult;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* @author Administrator
|
||||
*/
|
||||
@ -21,15 +27,15 @@ public class CrawlController {
|
||||
|
||||
private final CrawlService crawlService;
|
||||
|
||||
|
||||
private final CacheService cacheService;
|
||||
/**
|
||||
* 新增爬虫源
|
||||
* */
|
||||
@PostMapping("addCrawlSource")
|
||||
public ResultBean addCrawlSource(CrawlSource source){
|
||||
public RestResult<Void> addCrawlSource(CrawlSource source){
|
||||
crawlService.addCrawlSource(source);
|
||||
|
||||
return ResultBean.ok();
|
||||
return RestResult.ok();
|
||||
|
||||
}
|
||||
|
||||
@ -37,30 +43,93 @@ public class CrawlController {
|
||||
* 爬虫源分页列表查询
|
||||
* */
|
||||
@GetMapping("listCrawlByPage")
|
||||
public ResultBean listCrawlByPage(@RequestParam(value = "curr", defaultValue = "1") int page, @RequestParam(value = "limit", defaultValue = "10") int pageSize){
|
||||
public RestResult<PageBean<CrawlSource>> listCrawlByPage(@RequestParam(value = "curr", defaultValue = "1") int page, @RequestParam(value = "limit", defaultValue = "10") int pageSize){
|
||||
|
||||
return RestResult.ok(crawlService.listCrawlByPage(page,pageSize));
|
||||
}
|
||||
/**
|
||||
* 获取爬虫源
|
||||
* */
|
||||
@GetMapping("getCrawlSource/{id}")
|
||||
public RestResult<CrawlSource> getCrawlSource(@PathVariable("id") Integer id){
|
||||
CrawlSource crawlSource= crawlService.getCrawlSource(id);
|
||||
return RestResult.ok(crawlSource);
|
||||
|
||||
return ResultBean.ok(crawlService.listCrawlByPage(page,pageSize));
|
||||
}
|
||||
|
||||
/**
|
||||
* 测试规则
|
||||
* @param rule
|
||||
* @param url
|
||||
* @param isRefresh
|
||||
* @return
|
||||
*/
|
||||
@PostMapping("testParse")
|
||||
public RestResult<Object> testParse(String rule,String url,String isRefresh){
|
||||
|
||||
Map<String,Object> resultMap=new HashMap<>();
|
||||
String html =null;
|
||||
if(url.startsWith("https://")||url.startsWith("http://")){
|
||||
String refreshCache="1";
|
||||
if(!refreshCache.equals(isRefresh)) {
|
||||
Object cache = cacheService.getObject(CacheKey.BOOK_TEST_PARSE + url);
|
||||
if (cache == null) {
|
||||
isRefresh="1";
|
||||
}else {
|
||||
html = (String) cache;
|
||||
}
|
||||
}
|
||||
if(refreshCache.equals(isRefresh)){
|
||||
html = HttpUtil.getByHttpClientWithChrome(url);
|
||||
if (html != null) {
|
||||
cacheService.setObject(CacheKey.BOOK_TEST_PARSE + url, html, 60 * 10);
|
||||
}else{
|
||||
resultMap.put("msg","html is null");
|
||||
return RestResult.ok(resultMap);
|
||||
}
|
||||
}
|
||||
}else{
|
||||
resultMap.put("html","url is null");
|
||||
return RestResult.ok(resultMap);
|
||||
}
|
||||
Pattern pattern = Pattern.compile(rule);
|
||||
Matcher matcher = pattern.matcher(html);
|
||||
boolean isFind = matcher.find();
|
||||
resultMap.put("是否匹配",isFind);
|
||||
if(isFind){
|
||||
resultMap.put("匹配结果",matcher.group(1));
|
||||
}
|
||||
// resultMap.put("url",url);
|
||||
return RestResult.ok(resultMap);
|
||||
}
|
||||
/**
|
||||
* 修改爬虫源
|
||||
* */
|
||||
@PostMapping("updateCrawlSource")
|
||||
public RestResult<Void> updateCrawlSource(CrawlSource source) {
|
||||
crawlService.updateCrawlSource(source);
|
||||
return RestResult.ok();
|
||||
|
||||
}
|
||||
/**
|
||||
* 开启或停止爬虫
|
||||
* */
|
||||
@PostMapping("openOrCloseCrawl")
|
||||
public ResultBean openOrCloseCrawl(Integer sourceId,Byte sourceStatus){
|
||||
public RestResult<Void> openOrCloseCrawl(Integer sourceId,Byte sourceStatus){
|
||||
|
||||
crawlService.openOrCloseCrawl(sourceId,sourceStatus);
|
||||
|
||||
return ResultBean.ok();
|
||||
return RestResult.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增单本采集任务
|
||||
* */
|
||||
@PostMapping("addCrawlSingleTask")
|
||||
public ResultBean addCrawlSingleTask(CrawlSingleTask singleTask){
|
||||
public RestResult<Void> addCrawlSingleTask(CrawlSingleTask singleTask){
|
||||
crawlService.addCrawlSingleTask(singleTask);
|
||||
|
||||
return ResultBean.ok();
|
||||
return RestResult.ok();
|
||||
|
||||
}
|
||||
|
||||
@ -68,20 +137,20 @@ public class CrawlController {
|
||||
* 单本采集任务分页列表查询
|
||||
* */
|
||||
@GetMapping("listCrawlSingleTaskByPage")
|
||||
public ResultBean listCrawlSingleTaskByPage(@RequestParam(value = "curr", defaultValue = "1") int page, @RequestParam(value = "limit", defaultValue = "10") int pageSize){
|
||||
public RestResult<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 RestResult.ok(crawlService.listCrawlSingleTaskByPage(page,pageSize));
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除采集任务
|
||||
* */
|
||||
@DeleteMapping("delCrawlSingleTask/{id}")
|
||||
public ResultBean delCrawlSingleTask(@PathVariable("id") Long id){
|
||||
public RestResult<Void> delCrawlSingleTask(@PathVariable("id") Long id){
|
||||
|
||||
crawlService.delCrawlSingleTask(id);
|
||||
|
||||
return ResultBean.ok();
|
||||
return RestResult.ok();
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,18 +1,11 @@
|
||||
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.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author 11797
|
||||
*/
|
||||
|
@ -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;
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
package com.java2nb.novel.core.crawl;
|
||||
|
||||
import com.java2nb.novel.entity.Book;
|
||||
|
||||
/**
|
||||
* 爬虫小说章节内容处理器
|
||||
* */
|
||||
public interface CrawlBookChapterHandler {
|
||||
|
||||
void handle(ChapterBean chapterBean);
|
||||
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
package com.java2nb.novel.core.crawl;
|
||||
|
||||
import com.java2nb.novel.entity.Book;
|
||||
|
||||
/**
|
||||
* 爬虫小说处理器
|
||||
* */
|
||||
public interface CrawlBookHandler {
|
||||
|
||||
void handle(Book book);
|
||||
|
||||
}
|
@ -1,14 +1,19 @@
|
||||
package com.java2nb.novel.core.crawl;
|
||||
|
||||
import com.java2nb.novel.core.utils.*;
|
||||
import com.java2nb.novel.core.utils.HttpUtil;
|
||||
import com.java2nb.novel.core.utils.RandomBookInfoUtil;
|
||||
import com.java2nb.novel.core.utils.RestTemplateUtil;
|
||||
import com.java2nb.novel.core.utils.StringUtil;
|
||||
import com.java2nb.novel.entity.Book;
|
||||
import com.java2nb.novel.entity.BookContent;
|
||||
import com.java2nb.novel.entity.BookIndex;
|
||||
import com.java2nb.novel.utils.Constants;
|
||||
import io.github.xxyopen.util.IdWorker;
|
||||
import lombok.SneakyThrows;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.http.*;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
@ -16,8 +21,6 @@ import java.util.*;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import static java.util.regex.Pattern.compile;
|
||||
|
||||
/**
|
||||
* 爬虫解析器
|
||||
*
|
||||
@ -26,30 +29,26 @@ import static java.util.regex.Pattern.compile;
|
||||
@Slf4j
|
||||
public class CrawlParser {
|
||||
|
||||
private static IdWorker idWorker = new IdWorker();
|
||||
private static final IdWorker idWorker = IdWorker.INSTANCE;
|
||||
|
||||
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 RestTemplate restTemplate = RestTemplateUtil.getInstance("utf-8");
|
||||
|
||||
private static ThreadLocal<Integer> retryCount = new ThreadLocal<>();
|
||||
private static final ThreadLocal<Integer> retryCount = new ThreadLocal<>();
|
||||
|
||||
@SneakyThrows
|
||||
public static Book parseBook(RuleBean ruleBean, String bookId) {
|
||||
public static void parseBook(RuleBean ruleBean, String bookId, CrawlBookHandler handler) {
|
||||
Book book = new Book();
|
||||
String bookDetailUrl = ruleBean.getBookDetailUrl().replace("{bookId}", bookId);
|
||||
String bookDetailHtml = getByHttpClientWithChrome(bookDetailUrl);
|
||||
if (bookDetailHtml != null) {
|
||||
Pattern bookNamePatten = compile(ruleBean.getBookNamePatten());
|
||||
Pattern bookNamePatten = PatternFactory.getPattern(ruleBean.getBookNamePatten());
|
||||
Matcher bookNameMatch = bookNamePatten.matcher(bookDetailHtml);
|
||||
boolean isFindBookName = bookNameMatch.find();
|
||||
if (isFindBookName) {
|
||||
String bookName = bookNameMatch.group(1);
|
||||
//设置小说名
|
||||
book.setBookName(bookName);
|
||||
Pattern authorNamePatten = compile(ruleBean.getAuthorNamePatten());
|
||||
Pattern authorNamePatten = PatternFactory.getPattern(ruleBean.getAuthorNamePatten());
|
||||
Matcher authorNameMatch = authorNamePatten.matcher(bookDetailHtml);
|
||||
boolean isFindAuthorName = authorNameMatch.find();
|
||||
if (isFindAuthorName) {
|
||||
@ -57,7 +56,7 @@ public class CrawlParser {
|
||||
//设置作者名
|
||||
book.setAuthorName(authorName);
|
||||
if (StringUtils.isNotBlank(ruleBean.getPicUrlPatten())) {
|
||||
Pattern picUrlPatten = compile(ruleBean.getPicUrlPatten());
|
||||
Pattern picUrlPatten = PatternFactory.getPattern(ruleBean.getPicUrlPatten());
|
||||
Matcher picUrlMatch = picUrlPatten.matcher(bookDetailHtml);
|
||||
boolean isFindPicUrl = picUrlMatch.find();
|
||||
if (isFindPicUrl) {
|
||||
@ -70,7 +69,7 @@ public class CrawlParser {
|
||||
}
|
||||
}
|
||||
if (StringUtils.isNotBlank(ruleBean.getScorePatten())) {
|
||||
Pattern scorePatten = compile(ruleBean.getScorePatten());
|
||||
Pattern scorePatten = PatternFactory.getPattern(ruleBean.getScorePatten());
|
||||
Matcher scoreMatch = scorePatten.matcher(bookDetailHtml);
|
||||
boolean isFindScore = scoreMatch.find();
|
||||
if (isFindScore) {
|
||||
@ -80,7 +79,7 @@ public class CrawlParser {
|
||||
}
|
||||
}
|
||||
if (StringUtils.isNotBlank(ruleBean.getVisitCountPatten())) {
|
||||
Pattern visitCountPatten = compile(ruleBean.getVisitCountPatten());
|
||||
Pattern visitCountPatten = PatternFactory.getPattern(ruleBean.getVisitCountPatten());
|
||||
Matcher visitCountMatch = visitCountPatten.matcher(bookDetailHtml);
|
||||
boolean isFindVisitCount = visitCountMatch.find();
|
||||
if (isFindVisitCount) {
|
||||
@ -101,7 +100,7 @@ public class CrawlParser {
|
||||
//设置书籍简介
|
||||
book.setBookDesc(desc);
|
||||
if (StringUtils.isNotBlank(ruleBean.getStatusPatten())) {
|
||||
Pattern bookStatusPatten = compile(ruleBean.getStatusPatten());
|
||||
Pattern bookStatusPatten = PatternFactory.getPattern(ruleBean.getStatusPatten());
|
||||
Matcher bookStatusMatch = bookStatusPatten.matcher(bookDetailHtml);
|
||||
boolean isFindBookStatus = bookStatusMatch.find();
|
||||
if (isFindBookStatus) {
|
||||
@ -114,7 +113,7 @@ public class CrawlParser {
|
||||
}
|
||||
|
||||
if (StringUtils.isNotBlank(ruleBean.getUpadateTimePatten()) && StringUtils.isNotBlank(ruleBean.getUpadateTimeFormatPatten())) {
|
||||
Pattern updateTimePatten = compile(ruleBean.getUpadateTimePatten());
|
||||
Pattern updateTimePatten = PatternFactory.getPattern(ruleBean.getUpadateTimePatten());
|
||||
Matcher updateTimeMatch = updateTimePatten.matcher(bookDetailHtml);
|
||||
boolean isFindUpdateTime = updateTimeMatch.find();
|
||||
if (isFindUpdateTime) {
|
||||
@ -139,13 +138,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) {
|
||||
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));
|
||||
public static boolean parseBookIndexAndContent(String sourceBookId, Book book, RuleBean ruleBean, Map<Integer, BookIndex> existBookIndexMap, CrawlBookChapterHandler handler) {
|
||||
|
||||
Date currentDate = new Date();
|
||||
|
||||
@ -160,10 +156,10 @@ public class CrawlParser {
|
||||
indexListHtml = indexListHtml.substring(indexListHtml.indexOf(ruleBean.getBookIndexStart()) + ruleBean.getBookIndexStart().length());
|
||||
}
|
||||
|
||||
Pattern indexIdPatten = compile(ruleBean.getIndexIdPatten());
|
||||
Pattern indexIdPatten = PatternFactory.getPattern(ruleBean.getIndexIdPatten());
|
||||
Matcher indexIdMatch = indexIdPatten.matcher(indexListHtml);
|
||||
|
||||
Pattern indexNamePatten = compile(ruleBean.getIndexNamePatten());
|
||||
Pattern indexNamePatten = PatternFactory.getPattern(ruleBean.getIndexNamePatten());
|
||||
Matcher indexNameMatch = indexNamePatten.matcher(indexListHtml);
|
||||
|
||||
boolean isFindIndex = indexIdMatch.find() & indexNameMatch.find();
|
||||
@ -171,11 +167,11 @@ public class CrawlParser {
|
||||
int indexNum = 0;
|
||||
|
||||
//总字数
|
||||
Integer totalWordCount = book.getWordCount() == null ? 0 : book.getWordCount();
|
||||
int totalWordCount = book.getWordCount() == null ? 0 : book.getWordCount();
|
||||
|
||||
while (isFindIndex) {
|
||||
|
||||
BookIndex hasIndex = hasIndexs.get(indexNum);
|
||||
BookIndex hasIndex = existBookIndexMap.get(indexNum);
|
||||
String indexName = indexNameMatch.group(1);
|
||||
|
||||
if (hasIndex == null || !StringUtils.deleteWhitespace(hasIndex.getIndexName()).equals(StringUtils.deleteWhitespace(indexName))) {
|
||||
@ -221,7 +217,7 @@ public class CrawlParser {
|
||||
BookIndex bookIndex = new BookIndex();
|
||||
bookIndex.setIndexName(indexName);
|
||||
bookIndex.setIndexNum(indexNum);
|
||||
Integer wordCount = StringUtil.getStrValidWordCount(content);
|
||||
int wordCount = StringUtil.getStrValidWordCount(content);
|
||||
bookIndex.setWordCount(wordCount);
|
||||
indexList.add(bookIndex);
|
||||
|
||||
@ -235,7 +231,7 @@ public class CrawlParser {
|
||||
bookContent.setIndexId(hasIndex.getId());
|
||||
|
||||
//计算总字数
|
||||
totalWordCount = (totalWordCount+wordCount-hasIndex.getWordCount());
|
||||
totalWordCount = (totalWordCount + wordCount - hasIndex.getWordCount());
|
||||
} else {
|
||||
//章节插入
|
||||
//设置目录和章节内容
|
||||
@ -253,7 +249,6 @@ public class CrawlParser {
|
||||
bookIndex.setUpdateTime(currentDate);
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -266,7 +261,7 @@ public class CrawlParser {
|
||||
if (indexList.size() > 0) {
|
||||
//如果有爬到最新章节,则设置小说主表的最新章节信息
|
||||
//获取爬取到的最新章节
|
||||
BookIndex lastIndex = indexList.get(indexList.size()-1);
|
||||
BookIndex lastIndex = indexList.get(indexList.size() - 1);
|
||||
book.setLastIndexId(lastIndex.getId());
|
||||
book.setLastIndexName(lastIndex.getIndexName());
|
||||
book.setLastIndexUpdateTime(currentDate);
|
||||
@ -277,15 +272,23 @@ public class CrawlParser {
|
||||
|
||||
if (indexList.size() == contentList.size() && indexList.size() > 0) {
|
||||
|
||||
result.put(BOOK_INDEX_LIST_KEY, indexList);
|
||||
result.put(BOOK_CONTENT_LIST_KEY, contentList);
|
||||
handler.handle(new ChapterBean() {{
|
||||
setBookIndexList(indexList);
|
||||
setBookContentList(contentList);
|
||||
}});
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
handler.handle(new ChapterBean() {{
|
||||
setBookIndexList(new ArrayList<>(0));
|
||||
setBookContentList(new ArrayList<>(0));
|
||||
}});
|
||||
return false;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@ -294,6 +297,7 @@ public class CrawlParser {
|
||||
ResponseEntity<String> forEntity = restTemplate.getForEntity(url, String.class);
|
||||
if (forEntity.getStatusCode() == HttpStatus.OK) {
|
||||
String body = forEntity.getBody();
|
||||
assert body != null;
|
||||
if (body.length() < Constants.INVALID_HTML_LENGTH) {
|
||||
return processErrorHttpResult(url);
|
||||
}
|
||||
|
@ -0,0 +1,30 @@
|
||||
package com.java2nb.novel.core.crawl;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* @author xiongxiaoyang
|
||||
*/
|
||||
public class PatternFactory {
|
||||
|
||||
private static final Map<String, Pattern> PATTERN_CACHED_MAP = new HashMap<>();
|
||||
|
||||
/**
|
||||
* 根据正则表达式获取一个预编译的Pattern对象
|
||||
*/
|
||||
public static Pattern getPattern(String regex) {
|
||||
Pattern pattern = PATTERN_CACHED_MAP.get(regex);
|
||||
if (Objects.isNull(pattern)) {
|
||||
pattern = Pattern.compile(regex);
|
||||
PATTERN_CACHED_MAP.put(regex, pattern);
|
||||
}
|
||||
return pattern;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -35,7 +35,7 @@ public class RuleBean {
|
||||
private String statusPatten;
|
||||
private String scorePatten;
|
||||
private String visitCountPatten;
|
||||
private String descStart;;
|
||||
private String descStart;
|
||||
private String descEnd;
|
||||
private String upadateTimePatten;
|
||||
private String upadateTimeFormatPatten;
|
||||
|
@ -1,6 +1,7 @@
|
||||
package com.java2nb.novel.core.listener;
|
||||
|
||||
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.RuleBean;
|
||||
import com.java2nb.novel.entity.*;
|
||||
@ -16,9 +17,9 @@ import javax.servlet.ServletContextEvent;
|
||||
import javax.servlet.ServletContextListener;
|
||||
import javax.servlet.annotation.WebListener;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* @author Administrator
|
||||
@ -55,26 +56,28 @@ public class StarterListener implements ServletContextListener {
|
||||
CrawlSource source = crawlService.queryCrawlSource(needUpdateBook.getCrawlSourceId());
|
||||
RuleBean ruleBean = new ObjectMapper().readValue(source.getCrawlRule(), RuleBean.class);
|
||||
//解析小说基本信息
|
||||
Book book = CrawlParser.parseBook(ruleBean, needUpdateBook.getCrawlBookId());
|
||||
//这里只做老书更新
|
||||
book.setId(needUpdateBook.getId());
|
||||
book.setWordCount(needUpdateBook.getWordCount());
|
||||
if (needUpdateBook.getPicUrl() != null && needUpdateBook.getPicUrl().contains(Constants.LOCAL_PIC_PREFIX)) {
|
||||
//本地图片则不更新
|
||||
book.setPicUrl(null);
|
||||
}
|
||||
//查询已存在的章节
|
||||
Map<Integer, BookIndex> existBookIndexMap = bookService.queryExistBookIndexMap(needUpdateBook.getId());
|
||||
//解析章节目录
|
||||
Map<Integer, List> indexAndContentList = CrawlParser.parseBookIndexAndContent(needUpdateBook.getCrawlBookId(), book, ruleBean, existBookIndexMap);
|
||||
bookService.updateBookAndIndexAndContent(book, (List<BookIndex>) indexAndContentList.get(CrawlParser.BOOK_INDEX_LIST_KEY), (List<BookContent>) indexAndContentList.get(CrawlParser.BOOK_CONTENT_LIST_KEY), existBookIndexMap);
|
||||
CrawlParser.parseBook(ruleBean, needUpdateBook.getCrawlBookId(),book -> {
|
||||
//这里只做老书更新
|
||||
book.setId(needUpdateBook.getId());
|
||||
book.setWordCount(needUpdateBook.getWordCount());
|
||||
if (needUpdateBook.getPicUrl() != null && needUpdateBook.getPicUrl().contains(Constants.LOCAL_PIC_PREFIX)) {
|
||||
//本地图片则不更新
|
||||
book.setPicUrl(null);
|
||||
}
|
||||
//查询已存在的章节
|
||||
Map<Integer, BookIndex> existBookIndexMap = bookService.queryExistBookIndexMap(needUpdateBook.getId());
|
||||
//解析章节目录
|
||||
CrawlParser.parseBookIndexAndContent(needUpdateBook.getCrawlBookId(), book, ruleBean, existBookIndexMap,chapter -> {
|
||||
bookService.updateBookAndIndexAndContent(book, chapter.getBookIndexList(), chapter.getBookContentList(), existBookIndexMap);
|
||||
});
|
||||
});
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Thread.sleep(1000 * 60 * 10);
|
||||
// 休眠10分钟
|
||||
TimeUnit.MINUTES.sleep(10);
|
||||
} catch (Exception 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) {
|
||||
log.error(e.getMessage(), e);
|
||||
|
@ -3,17 +3,15 @@ package com.java2nb.novel.core.schedule;
|
||||
|
||||
import com.java2nb.novel.core.cache.CacheKey;
|
||||
import com.java2nb.novel.core.cache.CacheService;
|
||||
import com.java2nb.novel.core.utils.ThreadUtil;
|
||||
import com.java2nb.novel.entity.CrawlSource;
|
||||
import com.java2nb.novel.service.CrawlService;
|
||||
import io.github.xxyopen.util.ThreadUtil;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.scheduling.annotation.EnableScheduling;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
|
@ -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);
|
||||
|
||||
|
||||
}
|
@ -72,6 +72,7 @@ public interface BookService {
|
||||
* 更新一下最后一次的抓取时间
|
||||
* @param bookId 小说ID
|
||||
* */
|
||||
@Deprecated
|
||||
void updateCrawlLastTime(Long bookId);
|
||||
|
||||
/**
|
||||
|
@ -1,11 +1,9 @@
|
||||
package com.java2nb.novel.service;
|
||||
|
||||
import com.github.pagehelper.PageInfo;
|
||||
import com.java2nb.novel.core.bean.PageBean;
|
||||
import io.github.xxyopen.model.page.PageBean;
|
||||
import com.java2nb.novel.core.crawl.RuleBean;
|
||||
import com.java2nb.novel.entity.CrawlSingleTask;
|
||||
import com.java2nb.novel.entity.CrawlSource;
|
||||
import com.java2nb.novel.vo.CrawlSourceVO;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@ -20,7 +18,11 @@ public interface CrawlService {
|
||||
* */
|
||||
void addCrawlSource(CrawlSource source);
|
||||
|
||||
|
||||
/**
|
||||
* 修改爬虫源
|
||||
* @param source
|
||||
*/
|
||||
void updateCrawlSource(CrawlSource source);
|
||||
/**
|
||||
* 爬虫源分页列表
|
||||
* @param page 当前页码
|
||||
@ -64,7 +66,7 @@ public interface CrawlService {
|
||||
* 根据分类ID和规则解析分类列表
|
||||
* @param catId 分类ID
|
||||
* @param ruleBean 规则对象
|
||||
* @param sourceId
|
||||
* @param sourceId 爬虫源ID
|
||||
*/
|
||||
void parseBookList(int catId, RuleBean ruleBean, Integer sourceId);
|
||||
|
||||
@ -108,4 +110,11 @@ public interface CrawlService {
|
||||
* @param status 采集状态
|
||||
* */
|
||||
void updateCrawlSingleTask(CrawlSingleTask task, Byte status);
|
||||
|
||||
/**
|
||||
* 获取采集规则详细
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
CrawlSource getCrawlSource(Integer id);
|
||||
}
|
||||
|
@ -4,10 +4,12 @@ import com.java2nb.novel.entity.Book;
|
||||
import com.java2nb.novel.entity.BookContent;
|
||||
import com.java2nb.novel.entity.BookIndex;
|
||||
import com.java2nb.novel.mapper.*;
|
||||
import com.java2nb.novel.service.BookContentService;
|
||||
import com.java2nb.novel.service.BookService;
|
||||
import com.java2nb.novel.utils.Constants;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.mybatis.dynamic.sql.render.RenderingStrategies;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@ -37,7 +39,10 @@ public class BookServiceImpl implements BookService {
|
||||
|
||||
private final CrawlBookIndexMapper bookIndexMapper;
|
||||
|
||||
private final BookContentMapper bookContentMapper;
|
||||
private final Map<String, BookContentService> bookContentServiceMap;
|
||||
|
||||
@Value("${content.save.storage}")
|
||||
private String storageType;
|
||||
|
||||
|
||||
@Override
|
||||
@ -46,7 +51,7 @@ public class BookServiceImpl implements BookService {
|
||||
return bookMapper.count(countFrom(BookDynamicSqlSupport.book).where(BookDynamicSqlSupport.bookName, isEqualTo(bookName))
|
||||
.and(BookDynamicSqlSupport.authorName, isEqualTo(authorName))
|
||||
.build()
|
||||
.render(RenderingStrategies.MYBATIS3))>0;
|
||||
.render(RenderingStrategies.MYBATIS3)) > 0;
|
||||
|
||||
}
|
||||
|
||||
@ -57,7 +62,7 @@ public class BookServiceImpl implements BookService {
|
||||
.equalTo(sourceId)
|
||||
.set(crawlBookId)
|
||||
.equalTo(bookId)
|
||||
.where(BookDynamicSqlSupport.id,isEqualTo(id))
|
||||
.where(BookDynamicSqlSupport.id, isEqualTo(id))
|
||||
.build()
|
||||
.render(RenderingStrategies.MYBATIS3));
|
||||
}
|
||||
@ -74,9 +79,9 @@ public class BookServiceImpl implements BookService {
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Override
|
||||
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) {
|
||||
|
||||
//保存小说主表
|
||||
|
||||
@ -84,8 +89,11 @@ public class BookServiceImpl implements BookService {
|
||||
bookMapper.insertSelective(book);
|
||||
|
||||
//批量保存目录和内容
|
||||
bookIndexList.forEach(bookIndex -> {
|
||||
bookIndex.setStorageType(storageType);
|
||||
});
|
||||
bookIndexMapper.insertMultiple(bookIndexList);
|
||||
bookContentMapper.insertMultiple(bookContentList);
|
||||
bookContentServiceMap.get(storageType).saveBookContent(bookContentList, book.getId());
|
||||
|
||||
}
|
||||
}
|
||||
@ -96,7 +104,7 @@ public class BookServiceImpl implements BookService {
|
||||
@Override
|
||||
public List<Book> queryNeedUpdateBook(Date startDate, int limit) {
|
||||
List<Book> books = bookMapper.queryNeedUpdateBook(startDate, limit);
|
||||
if(books.size()>0) {
|
||||
if (books.size() > 0) {
|
||||
//更新最后抓取时间为当前时间
|
||||
bookMapper.updateCrawlLastTime(books, new Date());
|
||||
}
|
||||
@ -105,38 +113,34 @@ public class BookServiceImpl implements BookService {
|
||||
|
||||
@Override
|
||||
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, BookIndexDynamicSqlSupport.storageType)
|
||||
.from(BookIndexDynamicSqlSupport.bookIndex)
|
||||
.where(BookIndexDynamicSqlSupport.bookId,isEqualTo(bookId))
|
||||
.where(BookIndexDynamicSqlSupport.bookId, isEqualTo(bookId))
|
||||
.build()
|
||||
.render(RenderingStrategies.MYBATIS3));
|
||||
if (bookIndexs.size() > 0) {
|
||||
return bookIndexs.stream().collect(Collectors.toMap(BookIndex::getIndexNum, Function.identity()));
|
||||
return bookIndexs.stream().collect(Collectors.toMap(BookIndex::getIndexNum, Function.identity()));
|
||||
}
|
||||
return new HashMap<>(0);
|
||||
}
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Override
|
||||
public void updateBookAndIndexAndContent(Book book, List<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++) {
|
||||
BookIndex bookIndex = bookIndexList.get(i);
|
||||
BookContent bookContent = bookContentList.get(i);
|
||||
|
||||
|
||||
if(!existBookIndexMap.containsKey(bookIndex.getIndexNum())) {
|
||||
if (!existBookIndexMap.containsKey(bookIndex.getIndexNum())) {
|
||||
//插入
|
||||
bookIndex.setStorageType(storageType);
|
||||
bookIndexMapper.insertSelective(bookIndex);
|
||||
bookContentMapper.insertSelective(bookContent);
|
||||
}else{
|
||||
bookContentServiceMap.get(storageType).saveBookContent(bookContent, book.getId());
|
||||
} else {
|
||||
//更新
|
||||
bookIndexMapper.updateByPrimaryKeySelective(bookIndex);
|
||||
bookContentMapper.update(update(BookContentDynamicSqlSupport.bookContent)
|
||||
.set(BookContentDynamicSqlSupport.content)
|
||||
.equalTo(bookContent.getContent())
|
||||
.where(BookContentDynamicSqlSupport.indexId,isEqualTo(bookContent.getIndexId()))
|
||||
.build()
|
||||
.render(RenderingStrategies.MYBATIS3));
|
||||
bookContentServiceMap.get(existBookIndexMap.get(bookIndex.getIndexNum()).getStorageType()).updateBookContent(bookContent, book.getId());
|
||||
}
|
||||
|
||||
|
||||
@ -145,7 +149,7 @@ public class BookServiceImpl implements BookService {
|
||||
//更新小说主表
|
||||
book.setBookName(null);
|
||||
book.setAuthorName(null);
|
||||
if(Constants.VISIT_COUNT_DEFAULT.equals(book.getVisitCount())) {
|
||||
if (Constants.VISIT_COUNT_DEFAULT.equals(book.getVisitCount())) {
|
||||
book.setVisitCount(null);
|
||||
}
|
||||
bookMapper.updateByPrimaryKeySelective(book);
|
||||
@ -168,7 +172,7 @@ public class BookServiceImpl implements BookService {
|
||||
.build()
|
||||
.render(RenderingStrategies.MYBATIS3));
|
||||
|
||||
if(books.size()>0){
|
||||
if (books.size() > 0) {
|
||||
return books.get(0);
|
||||
}
|
||||
|
||||
@ -176,19 +180,4 @@ public class BookServiceImpl implements BookService {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询最后的章节
|
||||
* */
|
||||
private BookIndex queryLastIndex(Long bookId) {
|
||||
return bookIndexMapper.queryLastIndex(bookId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询小说总字数
|
||||
* */
|
||||
private Integer queryTotalWordCount(Long bookId) {
|
||||
|
||||
return bookMapper.queryTotalWordCount(bookId);
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,27 +1,30 @@
|
||||
package com.java2nb.novel.service.impl;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.github.pagehelper.Page;
|
||||
import com.github.pagehelper.PageHelper;
|
||||
import com.github.pagehelper.PageInfo;
|
||||
import com.java2nb.novel.core.bean.PageBean;
|
||||
import io.github.xxyopen.model.page.PageBean;
|
||||
import com.java2nb.novel.core.cache.CacheKey;
|
||||
import com.java2nb.novel.core.cache.CacheService;
|
||||
import com.java2nb.novel.core.crawl.CrawlParser;
|
||||
import com.java2nb.novel.core.crawl.RuleBean;
|
||||
import com.java2nb.novel.core.enums.ResponseStatus;
|
||||
import com.java2nb.novel.core.exception.BusinessException;
|
||||
import com.java2nb.novel.core.utils.BeanUtil;
|
||||
import com.java2nb.novel.core.utils.IdWorker;
|
||||
import com.java2nb.novel.core.utils.SpringUtil;
|
||||
import com.java2nb.novel.core.utils.ThreadUtil;
|
||||
import com.java2nb.novel.entity.*;
|
||||
import io.github.xxyopen.model.page.builder.pagehelper.PageBuilder;
|
||||
import io.github.xxyopen.util.IdWorker;
|
||||
import io.github.xxyopen.util.ThreadUtil;
|
||||
import io.github.xxyopen.web.exception.BusinessException;
|
||||
import io.github.xxyopen.web.util.BeanUtil;
|
||||
import com.java2nb.novel.entity.Book;
|
||||
import com.java2nb.novel.entity.CrawlSingleTask;
|
||||
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.CrawlService;
|
||||
import com.java2nb.novel.vo.CrawlSingleTaskVO;
|
||||
import com.java2nb.novel.vo.CrawlSourceVO;
|
||||
import io.github.xxyopen.web.util.SpringUtil;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.SneakyThrows;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@ -29,18 +32,15 @@ import org.apache.commons.lang3.StringUtils;
|
||||
import org.mybatis.dynamic.sql.render.RenderingStrategies;
|
||||
import org.mybatis.dynamic.sql.select.render.SelectStatementProvider;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.regex.Matcher;
|
||||
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.mapper.BookDynamicSqlSupport.crawlBookId;
|
||||
import static com.java2nb.novel.mapper.BookDynamicSqlSupport.crawlSourceId;
|
||||
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;
|
||||
|
||||
/**
|
||||
@ -58,9 +58,10 @@ public class CrawlServiceImpl implements CrawlService {
|
||||
|
||||
private final BookService bookService;
|
||||
|
||||
|
||||
private final CacheService cacheService;
|
||||
|
||||
private final IdWorker idWorker = IdWorker.INSTANCE;
|
||||
|
||||
|
||||
@Override
|
||||
public void addCrawlSource(CrawlSource source) {
|
||||
@ -70,7 +71,24 @@ public class CrawlServiceImpl implements CrawlService {
|
||||
crawlSourceMapper.insertSelective(source);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateCrawlSource(CrawlSource source) {
|
||||
if(source.getId()!=null){
|
||||
Optional<CrawlSource> opt=crawlSourceMapper.selectByPrimaryKey(source.getId());
|
||||
if(opt.isPresent()) {
|
||||
CrawlSource crawlSource =opt.get();
|
||||
if (crawlSource.getSourceStatus() == (byte) 1) {
|
||||
//关闭
|
||||
openOrCloseCrawl(crawlSource.getId(),(byte)0);
|
||||
}
|
||||
Date currentDate = new Date();
|
||||
crawlSource.setUpdateTime(currentDate);
|
||||
crawlSource.setCrawlRule(source.getCrawlRule());
|
||||
crawlSource.setSourceName(source.getSourceName());
|
||||
crawlSourceMapper.updateByPrimaryKey(crawlSource);
|
||||
}
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public PageBean<CrawlSource> listCrawlByPage(int page, int pageSize) {
|
||||
PageHelper.startPage(page, pageSize);
|
||||
@ -80,7 +98,7 @@ public class CrawlServiceImpl implements CrawlService {
|
||||
.build()
|
||||
.render(RenderingStrategies.MYBATIS3);
|
||||
List<CrawlSource> crawlSources = crawlSourceMapper.selectMany(render);
|
||||
PageBean<CrawlSource> pageBean = new PageBean<>(crawlSources);
|
||||
PageBean<CrawlSource> pageBean = PageBuilder.build(crawlSources);
|
||||
pageBean.setList(BeanUtil.copyList(crawlSources, CrawlSourceVO.class));
|
||||
return pageBean;
|
||||
}
|
||||
@ -121,11 +139,7 @@ public class CrawlServiceImpl implements CrawlService {
|
||||
//按分类开始爬虫解析任务
|
||||
for (int i = 1; i < 8; i++) {
|
||||
final int catId = i;
|
||||
Thread thread = new Thread(() -> {
|
||||
|
||||
parseBookList(catId, ruleBean, sourceId);
|
||||
|
||||
});
|
||||
Thread thread = new Thread(() -> CrawlServiceImpl.this.parseBookList(catId, ruleBean, sourceId));
|
||||
thread.start();
|
||||
//thread加入到监控缓存中
|
||||
threadIds.add(thread.getId());
|
||||
@ -154,7 +168,7 @@ public class CrawlServiceImpl implements CrawlService {
|
||||
@Override
|
||||
public void addCrawlSingleTask(CrawlSingleTask singleTask) {
|
||||
|
||||
if(bookService.queryIsExistByBookNameAndAuthorName(singleTask.getBookName(),singleTask.getAuthorName())){
|
||||
if (bookService.queryIsExistByBookNameAndAuthorName(singleTask.getBookName(), singleTask.getAuthorName())) {
|
||||
throw new BusinessException(ResponseStatus.BOOK_EXISTS);
|
||||
|
||||
}
|
||||
@ -173,7 +187,7 @@ public class CrawlServiceImpl implements CrawlService {
|
||||
.build()
|
||||
.render(RenderingStrategies.MYBATIS3);
|
||||
List<CrawlSingleTask> crawlSingleTasks = crawlSingleTaskMapper.selectMany(render);
|
||||
PageBean<CrawlSingleTask> pageBean = new PageBean<>(crawlSingleTasks);
|
||||
PageBean<CrawlSingleTask> pageBean = PageBuilder.build(crawlSingleTasks);
|
||||
pageBean.setList(BeanUtil.copyList(crawlSingleTasks, CrawlSingleTaskVO.class));
|
||||
return pageBean;
|
||||
}
|
||||
@ -186,23 +200,23 @@ public class CrawlServiceImpl implements CrawlService {
|
||||
@Override
|
||||
public CrawlSingleTask getCrawlSingleTask() {
|
||||
|
||||
List<CrawlSingleTask> list = crawlSingleTaskMapper.selectMany(select(CrawlSingleTaskDynamicSqlSupport.crawlSingleTask.allColumns())
|
||||
List<CrawlSingleTask> list = crawlSingleTaskMapper.selectMany(select(CrawlSingleTaskDynamicSqlSupport.crawlSingleTask.allColumns())
|
||||
.from(CrawlSingleTaskDynamicSqlSupport.crawlSingleTask)
|
||||
.where(CrawlSingleTaskDynamicSqlSupport.taskStatus,isEqualTo((byte)2))
|
||||
.orderBy(CrawlSingleTaskDynamicSqlSupport.createTime)
|
||||
.limit(1)
|
||||
.where(CrawlSingleTaskDynamicSqlSupport.taskStatus, isEqualTo((byte) 2))
|
||||
.orderBy(CrawlSingleTaskDynamicSqlSupport.createTime)
|
||||
.limit(1)
|
||||
.build()
|
||||
.render(RenderingStrategies.MYBATIS3));
|
||||
|
||||
return list.size() > 0 ? list.get(0) : null;
|
||||
return list.size() > 0 ? list.get(0) : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateCrawlSingleTask(CrawlSingleTask task, Byte status) {
|
||||
byte excCount = task.getExcCount();
|
||||
excCount+=1;
|
||||
excCount += 1;
|
||||
task.setExcCount(excCount);
|
||||
if(status == 1 || excCount == 5){
|
||||
if (status == 1 || excCount == 5) {
|
||||
//当采集成功或者采集次数等于5,则更新采集最终状态,并停止采集
|
||||
task.setTaskStatus(status);
|
||||
}
|
||||
@ -210,6 +224,16 @@ public class CrawlServiceImpl implements CrawlService {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public CrawlSource getCrawlSource(Integer id) {
|
||||
Optional<CrawlSource> opt=crawlSourceMapper.selectByPrimaryKey(id);
|
||||
if(opt.isPresent()) {
|
||||
CrawlSource crawlSource =opt.get();
|
||||
return crawlSource;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析分类列表
|
||||
*/
|
||||
@ -224,7 +248,7 @@ public class CrawlServiceImpl implements CrawlService {
|
||||
|
||||
try {
|
||||
|
||||
if(StringUtils.isNotBlank(ruleBean.getCatIdRule().get("catId" + catId))) {
|
||||
if (StringUtils.isNotBlank(ruleBean.getCatIdRule().get("catId" + catId))) {
|
||||
//拼接分类URL
|
||||
String catBookListUrl = ruleBean.getBookListUrl()
|
||||
.replace("{catId}", ruleBean.getCatIdRule().get("catId" + catId))
|
||||
@ -240,7 +264,7 @@ public class CrawlServiceImpl implements CrawlService {
|
||||
//1.阻塞过程(使用了 sleep,同步锁的 wait,socket 中的 receiver,accept 等方法时)
|
||||
//捕获中断异常InterruptedException来退出线程。
|
||||
//2.非阻塞过程中通过判断中断标志来退出线程。
|
||||
if(Thread.currentThread().isInterrupted()){
|
||||
if (Thread.currentThread().isInterrupted()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -267,8 +291,8 @@ public class CrawlServiceImpl implements CrawlService {
|
||||
|
||||
}
|
||||
}
|
||||
}catch (Exception e){
|
||||
log.error(e.getMessage(),e);
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
}
|
||||
|
||||
page += 1;
|
||||
@ -279,39 +303,47 @@ public class CrawlServiceImpl implements CrawlService {
|
||||
|
||||
@Override
|
||||
public boolean parseBookAndSave(int catId, RuleBean ruleBean, Integer sourceId, String bookId) {
|
||||
Book book = CrawlParser.parseBook(ruleBean, bookId);
|
||||
if(book.getBookName() == null || book.getAuthorName() == null){
|
||||
return false;
|
||||
}
|
||||
//这里只做新书入库,查询是否存在这本书
|
||||
Book existBook = bookService.queryBookByBookNameAndAuthorName(book.getBookName(), book.getAuthorName());
|
||||
//如果该小说不存在,则可以解析入库,但是标记该小说正在入库,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);
|
||||
|
||||
final AtomicBoolean parseResult = new AtomicBoolean(false);
|
||||
|
||||
CrawlParser.parseBook(ruleBean, bookId, book -> {
|
||||
if (book.getBookName() == null || book.getAuthorName() == null) {
|
||||
return;
|
||||
}
|
||||
book.setCrawlBookId(bookId);
|
||||
book.setCrawlSourceId(sourceId);
|
||||
book.setCrawlLastTime(new Date());
|
||||
book.setId(new IdWorker().nextId());
|
||||
//解析章节目录
|
||||
Map<Integer, List> indexAndContentList = CrawlParser.parseBookIndexAndContent(bookId, book, ruleBean, new HashMap<>(0));
|
||||
//这里只做新书入库,查询是否存在这本书
|
||||
Book existBook = bookService.queryBookByBookNameAndAuthorName(book.getBookName(), book.getAuthorName());
|
||||
//如果该小说不存在,则可以解析入库,但是标记该小说正在入库,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.setCrawlLastTime(new Date());
|
||||
book.setId(idWorker.nextId());
|
||||
//解析章节目录
|
||||
boolean parseIndexContentResult = CrawlParser.parseBookIndexAndContent(bookId, book, ruleBean, new HashMap<>(0), chapter -> {
|
||||
bookService.saveBookAndIndexAndContent(book, chapter.getBookIndexList(), chapter.getBookContentList());
|
||||
});
|
||||
parseResult.set(parseIndexContentResult);
|
||||
|
||||
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
|
||||
|
@ -0,0 +1,43 @@
|
||||
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(value = "db")
|
||||
@RequiredArgsConstructor
|
||||
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));
|
||||
}
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
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(value = "txt")
|
||||
@RequiredArgsConstructor
|
||||
public class FileBookContentServiceImpl implements BookContentService {
|
||||
|
||||
@Value("${content.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());
|
||||
}
|
||||
}
|
@ -2,14 +2,15 @@ package com.java2nb.novel.vo;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import com.java2nb.novel.entity.CrawlSingleTask;
|
||||
import com.java2nb.novel.entity.CrawlSource;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* @author Administrator
|
||||
*/
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
public class CrawlSingleTaskVO extends CrawlSingleTask {
|
||||
|
||||
|
@ -3,13 +3,14 @@ package com.java2nb.novel.vo;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import com.java2nb.novel.entity.CrawlSource;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import javax.annotation.Generated;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* @author Administrator
|
||||
*/
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
public class CrawlSourceVO extends CrawlSource{
|
||||
|
||||
|
@ -57,8 +57,8 @@
|
||||
<!-- 指定项目中某个包,当有日志操作行为时的日志记录级别 -->
|
||||
<!-- com.maijinjie.springboot 为根包,也就是只要是发生在这个根包下面的所有日志操作行为的权限都是DEBUG -->
|
||||
<!-- 级别依次为【从高到低】:FATAL > ERROR > WARN > INFO > DEBUG > TRACE -->
|
||||
<logger name="com.java2nb" level="DEBUG">
|
||||
<logger name="com.java2nb" level="DEBUG" additivity="false">
|
||||
<appender-ref ref="STDOUT" />
|
||||
<appender-ref ref="FILE" />
|
||||
</logger>
|
||||
</configuration>
|
||||
</configuration>
|
||||
|
@ -30,6 +30,7 @@
|
||||
<ul class="log_list">
|
||||
<li><a class="link_1" href="/">爬虫源管理</a></li>
|
||||
<li><a class="link_1 on" href="/crawl/crawlSingleTask_list.html">单本采集管理</a></li>
|
||||
<li><a class="link_1" href="/crawl/crawlSource_test.html" target="_blank" >规则测试</a></li>
|
||||
<!--<li><a class="link_1 " href="/user/userinfo.html">批量小说爬取</a></li>
|
||||
<li><a class="link_4 " href="/user/favorites.html">单本小说爬取</a></li>-->
|
||||
</ul>
|
||||
|
@ -30,6 +30,7 @@
|
||||
<ul class="log_list">
|
||||
<li><a class="link_1" href="/">爬虫源管理</a></li>
|
||||
<li><a class="link_1 on" href="/crawl/crawlSingleTask_list.html">单本采集管理</a></li>
|
||||
<li><a class="link_1" href="/crawl/crawlSource_test.html" target="_blank" >规则测试</a></li>
|
||||
<!-- <li><a class="link_1 " href="/user/userinfo.html">批量小说爬取</a></li>
|
||||
<li><a class="link_4 " href="/user/favorites.html">单本小说爬取</a></li>-->
|
||||
</ul>
|
||||
|
@ -30,6 +30,7 @@
|
||||
<ul class="log_list">
|
||||
<li><a class="link_1 on" href="/">爬虫源管理</a></li>
|
||||
<li><a class="link_1" href="/crawl/crawlSingleTask_list.html">单本采集管理</a></li>
|
||||
<li><a class="link_1" href="/crawl/crawlSource_test.html" target="_blank" >规则测试</a></li>
|
||||
<!--<li><a class="link_1 " href="/user/userinfo.html">批量小说爬取</a></li>
|
||||
<li><a class="link_4 " href="/user/favorites.html">单本小说爬取</a></li>-->
|
||||
</ul>
|
||||
|
@ -29,6 +29,7 @@
|
||||
<ul class="log_list">
|
||||
<li><a class="link_1 on" href="/">爬虫源管理</a></li>
|
||||
<li><a class="link_1" href="/crawl/crawlSingleTask_list.html">单本采集管理</a></li>
|
||||
<li><a class="link_1" href="/crawl/crawlSource_test.html" target="_blank" >规则测试</a></li>
|
||||
<!-- <li><a class="link_1 " href="/user/userinfo.html">批量小说爬取</a></li>
|
||||
<li><a class="link_4 " href="/user/favorites.html">单本小说爬取</a></li>-->
|
||||
</ul>
|
||||
@ -38,7 +39,7 @@
|
||||
<div class="my_bookshelf">
|
||||
<div class="title cf">
|
||||
<h2 class="fl">爬虫源列表</h2>
|
||||
<div class="fr"><a href="/crawl/crawlSource_add.html" class="btn_red">增加爬虫源</a></div>
|
||||
<div class="fr"><a href="/crawl/crawlSource_add.html" class="btn_red">增加爬虫源</a>
|
||||
</div>
|
||||
|
||||
<div id="divData" class="updateTable">
|
||||
@ -119,6 +120,7 @@
|
||||
<script language="javascript" type="text/javascript">
|
||||
search(1, 10);
|
||||
|
||||
var pageCrawlSourceList=null;
|
||||
function search(curr, limit) {
|
||||
|
||||
$.ajax({
|
||||
@ -129,6 +131,7 @@
|
||||
success: function (data) {
|
||||
if (data.code == 200) {
|
||||
var crawlSourceList = data.data.list;
|
||||
pageCrawlSourceList=data.data.list;
|
||||
if (crawlSourceList.length > 0) {
|
||||
var crawlSourceListHtml = "";
|
||||
for(var i=0;i<crawlSourceList.length;i++){
|
||||
@ -147,7 +150,9 @@
|
||||
" <td class=\"goread\" id='sourceStatus"+crawlSource.id+"'>"+(crawlSource.sourceStatus==0?'停止运行':'正在运行')+
|
||||
" </td>\n" +
|
||||
|
||||
" <td class=\"goread\" id='opt"+crawlSource.id+"'><a href='javascript:openOrStopCrawl("+crawlSource.id+","+crawlSource.sourceStatus+")'>"+(crawlSource.sourceStatus==0?'开启':'关闭')+" </a></td> </tr>");
|
||||
" <td class=\"goread\" id='opt"+crawlSource.id+"'><a href='javascript:openOrStopCrawl("+crawlSource.id+","+crawlSource.sourceStatus+")'>"+(crawlSource.sourceStatus==0?'开启':'关闭')+" </a>" +
|
||||
"<a href='javascript:updateCrawlSource("+crawlSource.id+")'>修改 </a>" +
|
||||
"</td> </tr>");
|
||||
}
|
||||
$("#crawlSourceList").html(crawlSourceListHtml);
|
||||
|
||||
@ -196,7 +201,12 @@
|
||||
})
|
||||
|
||||
}
|
||||
function updateCrawlSource(crawlSourceId){
|
||||
|
||||
localStorage.setItem("crawlSourceId",crawlSourceId);
|
||||
window.location.href="/crawl/crawlSource_update.html";
|
||||
|
||||
}
|
||||
|
||||
function openOrStopCrawl(sourceId,status) {
|
||||
|
||||
|
@ -0,0 +1,171 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"/>
|
||||
<title>爬虫管理系统-小说精品屋</title>
|
||||
<link rel="stylesheet" href="/css/base.css?v=1"/>
|
||||
<link rel="stylesheet" href="/css/user.css"/>
|
||||
</head>
|
||||
</head>
|
||||
<body class="">
|
||||
|
||||
<div class="header">
|
||||
<div class="mainNav" id="mainNav">
|
||||
<div class="box_center cf"
|
||||
style="text-align: center;height: 44px;line-height: 48px;color: #fff;font-size: 16px;">
|
||||
|
||||
小说精品屋爬虫管理
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="main box_center cf">
|
||||
<div class="userBox cf">
|
||||
<div class="my_l">
|
||||
|
||||
<ul class="log_list">
|
||||
<li><a class="link_1 on" href="/">爬虫源管理</a></li>
|
||||
<li><a class="link_1" href="/crawl/crawlSingleTask_list.html">单本采集管理</a></li>
|
||||
<li><a class="link_1" href="/crawl/crawlSource_test.html" target="_blank" >规则测试</a></li>
|
||||
<!--<li><a class="link_1 " href="/user/userinfo.html">批量小说爬取</a></li>
|
||||
<li><a class="link_4 " href="/user/favorites.html">单本小说爬取</a></li>-->
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
<div class="my_r">
|
||||
<div class="my_bookshelf">
|
||||
|
||||
<div class="userBox cf">
|
||||
<form method="post" action="./register.html" id="form2">
|
||||
<div class="aspNetHidden">
|
||||
<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE"
|
||||
value="/wEPDwUKLTIzNjMxNDQxNw9kFgJmD2QWAmYPFgIeBFRleHQFqAE8YSBocmVmPSIvc2VhcmNoLmFzcHg/c2VhcmNoS2V5PeWWu+Wuiembr++8jOeLhOazve+8jOeBteW8gu+8jOWJjeS4luS7iueUn++8jOWGpeeOi+msvOWkqyIgdGFyZ2V0PSJfYmxhbmsiPuWWu+Wuiembr++8jOeLhOazve+8jOeBteW8gu+8jOWJjeS4luS7iueUn++8jOWGpeeOi+msvOWkqzwvYT5kZOquoASBvnvPbc/TYIQiLhSPJ8GKnYQrmk7jGhb5AC5Q">
|
||||
</div>
|
||||
|
||||
<div class="aspNetHidden">
|
||||
|
||||
<input type="hidden" name="__VIEWSTATEGENERATOR" id="__VIEWSTATEGENERATOR" value="23AA6834">
|
||||
<input type="hidden" name="__EVENTVALIDATION" id="__EVENTVALIDATION"
|
||||
value="/wEdAAVece19BIZ9HiByRfHz3pfnqKSXUE1UN51mNFrIuw38c3Y2+Mc6SrnAqio3oCKbxYZZ1lS+gZUZKpbsAea8j7ASAv40DHFcQ/NE7tJUnABeyQ3d9sFDIcFCYNqlVtprfLoh4JFy0U+R/CcMuyAiWTz7">
|
||||
</div>
|
||||
<div class="user_l">
|
||||
<div></div>
|
||||
<h3>爬虫源信息填写(示例均为顶点小说网:dingdiann.com)</h3>
|
||||
<ul class="log_list">
|
||||
<li><span id="LabErr"></span></li>
|
||||
示例:<b>http://m.xdingdiann.com/sort/{catId}/{page}.html</b> ({catId}代表分类ID,{page}代表分页页码)
|
||||
<li><input type="text" id="url" class="s_input icon_key"
|
||||
placeholder="url"></li>
|
||||
|
||||
示例:<b>value=\"(\\d+)/\\d+\"</b>
|
||||
<li><input type="text" id="rule" class="s_input icon_name" placeholder="规则"></li>
|
||||
示例:<b>1强制刷新 空或0使用缓存</b>
|
||||
<li><input type="text" id="isRefresh" class="s_input icon_name" placeholder="是否强制刷新"></li>
|
||||
|
||||
<li><textarea rows="20" cols="100" id="resultMap"></textarea></li>
|
||||
|
||||
|
||||
|
||||
<li><input type="button" onclick="testCrawlSource()" name="btnRegister" value="测试"
|
||||
id="btnRegister" class="btn_red"></li>
|
||||
</ul>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<!--<div id="divData" class="updateTable">
|
||||
<table cellpadding="0" cellspacing="0">
|
||||
<thead>
|
||||
<tr>
|
||||
|
||||
<th class="name">
|
||||
爬虫源(已开启的爬虫源)
|
||||
</th>
|
||||
<th class="chapter">
|
||||
成功爬取数量(websocket实现)
|
||||
</th>
|
||||
<th class="time">
|
||||
目标爬取数量
|
||||
</th>
|
||||
<th class="goread">
|
||||
状态(正在运行,已停止)(一次只能运行一个爬虫源)
|
||||
</th>
|
||||
<th class="goread">
|
||||
操作(启动,停止)
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="bookShelfList">
|
||||
|
||||
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="pageBox cf" id="shellPage">
|
||||
</div>
|
||||
</div>-->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</body>
|
||||
<script src="/javascript/jquery-1.8.0.min.js" type="text/javascript"></script>
|
||||
<script src="/layui/layui.all.js" type="text/javascript"></script>
|
||||
<script src="/javascript/header.js" type="text/javascript"></script>
|
||||
<script src="/javascript/user.js" type="text/javascript"></script>
|
||||
<script language="javascript" type="text/javascript">
|
||||
function load() {
|
||||
var testParseUrl= localStorage.getItem("testParseUrl");
|
||||
$("#url").val(testParseUrl);
|
||||
var testParseRule=localStorage.getItem("testParseRule");
|
||||
$("#rule").val(testParseRule);
|
||||
}
|
||||
function testCrawlSource() {
|
||||
|
||||
var data = {};
|
||||
|
||||
|
||||
var isRefresh = $("#isRefresh").val();
|
||||
data.isRefresh = isRefresh;
|
||||
var rule = $("#rule").val();
|
||||
if (rule.length == 0) {
|
||||
layer.alert("正则必填");
|
||||
return false;
|
||||
}
|
||||
data.rule = rule;
|
||||
var url = $("#url").val();
|
||||
if (url.length == 0) {
|
||||
layer.alert("url必填");
|
||||
return false;
|
||||
}
|
||||
data.url = url;
|
||||
|
||||
localStorage.setItem("testParseUrl",url);
|
||||
localStorage.setItem("testParseRule",rule);
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: "/crawl/testParse",
|
||||
data: data,
|
||||
dataType: "json",
|
||||
success: function (data) {
|
||||
if (data.code == 200) {
|
||||
$("#resultMap").val(JSON.stringify(data.data));
|
||||
} else {
|
||||
layer.alert(data.msg);
|
||||
}
|
||||
|
||||
},
|
||||
error: function () {
|
||||
layer.alert('网络异常');
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
</script>
|
||||
</html>
|
@ -0,0 +1,522 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"/>
|
||||
<title>爬虫管理系统-小说精品屋</title>
|
||||
<link rel="stylesheet" href="/css/base.css?v=1"/>
|
||||
<link rel="stylesheet" href="/css/user.css"/>
|
||||
</head>
|
||||
</head>
|
||||
<body class="">
|
||||
|
||||
<div class="header">
|
||||
<div class="mainNav" id="mainNav">
|
||||
<div class="box_center cf"
|
||||
style="text-align: center;height: 44px;line-height: 48px;color: #fff;font-size: 16px;">
|
||||
|
||||
小说精品屋爬虫管理
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="main box_center cf">
|
||||
<div class="userBox cf">
|
||||
<div class="my_l">
|
||||
|
||||
<ul class="log_list">
|
||||
<li><a class="link_1 on" href="/">爬虫源管理</a></li>
|
||||
<li><a class="link_1" href="/crawl/crawlSingleTask_list.html">单本采集管理</a></li>
|
||||
<li><a class="link_1" href="/crawl/crawlSource_test.html" target="_blank" >规则测试</a></li>
|
||||
<!--<li><a class="link_1 " href="/user/userinfo.html">批量小说爬取</a></li>
|
||||
<li><a class="link_4 " href="/user/favorites.html">单本小说爬取</a></li>-->
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
<div class="my_r">
|
||||
<div class="my_bookshelf">
|
||||
|
||||
<div class="userBox cf">
|
||||
<form method="post" action="./register.html" id="form2">
|
||||
<input type="hidden" name="id" id="sourceId"/>
|
||||
<div class="aspNetHidden">
|
||||
<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE"
|
||||
value="/wEPDwUKLTIzNjMxNDQxNw9kFgJmD2QWAmYPFgIeBFRleHQFqAE8YSBocmVmPSIvc2VhcmNoLmFzcHg/c2VhcmNoS2V5PeWWu+Wuiembr++8jOeLhOazve+8jOeBteW8gu+8jOWJjeS4luS7iueUn++8jOWGpeeOi+msvOWkqyIgdGFyZ2V0PSJfYmxhbmsiPuWWu+Wuiembr++8jOeLhOazve+8jOeBteW8gu+8jOWJjeS4luS7iueUn++8jOWGpeeOi+msvOWkqzwvYT5kZOquoASBvnvPbc/TYIQiLhSPJ8GKnYQrmk7jGhb5AC5Q">
|
||||
</div>
|
||||
|
||||
<div class="aspNetHidden">
|
||||
|
||||
<input type="hidden" name="__VIEWSTATEGENERATOR" id="__VIEWSTATEGENERATOR" value="23AA6834">
|
||||
<input type="hidden" name="__EVENTVALIDATION" id="__EVENTVALIDATION"
|
||||
value="/wEdAAVece19BIZ9HiByRfHz3pfnqKSXUE1UN51mNFrIuw38c3Y2+Mc6SrnAqio3oCKbxYZZ1lS+gZUZKpbsAea8j7ASAv40DHFcQ/NE7tJUnABeyQ3d9sFDIcFCYNqlVtprfLoh4JFy0U+R/CcMuyAiWTz7">
|
||||
</div>
|
||||
<div class="user_l">
|
||||
<div></div>
|
||||
<h3>爬虫源信息填写(示例均为顶点小说网:dingdiann.com)</h3>
|
||||
<ul class="log_list">
|
||||
<li><span id="LabErr"></span></li>
|
||||
示例:<b>新顶点小说网</b>
|
||||
<li><input type="text" id="sourceName" class="s_input icon_name" placeholder="源站名"></li>
|
||||
<!--示例:<b>https://m.xdingdiann.com/sort/0/1.html</b>
|
||||
<li><input type="text" id="updateBookListUrl" class="s_input icon_key"
|
||||
placeholder="小说更新列表url"></li>-->
|
||||
示例:<b>http://m.xdingdiann.com/sort/{catId}/{page}.html</b> ({catId}代表分类ID,{page}代表分页页码)
|
||||
<li><input type="text" id="bookListUrl" class="s_input icon_key"
|
||||
placeholder="分类列表页URL规则"></li>
|
||||
示例:<b>1</b>
|
||||
<li><input type="text" id="catId1" class="s_input icon_key" placeholder="玄幻奇幻分类ID"></li>
|
||||
示例:<b>2</b>
|
||||
<li><input type="text" id="catId2" class="s_input icon_key" placeholder="武侠仙侠分类ID"></li>
|
||||
示例:<b>3</b>
|
||||
<li><input type="text" id="catId3" class="s_input icon_key" placeholder="都市言情分类ID"></li>
|
||||
示例:<b>4</b>
|
||||
<li><input type="text" id="catId4" class="s_input icon_key" placeholder="历史军事分类ID"></li>
|
||||
示例:<b>5</b>
|
||||
<li><input type="text" id="catId5" class="s_input icon_key" placeholder="科幻灵异分类ID"></li>
|
||||
示例:<b>6</b>
|
||||
<li><input type="text" id="catId6" class="s_input icon_key" placeholder="网游竞技分类ID"></li>
|
||||
示例:<b>7</b>
|
||||
<li><input type="text" id="catId7" class="s_input icon_key" placeholder="女生频道分类ID"></li>
|
||||
示例:<b>href="/ddk(\d+)/"</b>
|
||||
<li><input type="text" id="bookIdPatten" class="s_input icon_key"
|
||||
placeholder="列表页小说ID正则表达式:"></li>
|
||||
<b>value="(\d+)/\d+"</b>
|
||||
<li><input type="text" id="pagePatten" class="s_input icon_key"
|
||||
placeholder="列表页当前分页页码正则表达式:"></li>
|
||||
<b>value="\d+/(\d+)"</b>
|
||||
<li><input type="text" id="totalPagePatten" class="s_input icon_key"
|
||||
placeholder="列表页分页总页数正则表达式:"></li>
|
||||
<b>http://m.xdingdiann.com/ddk{bookId}</b> (bookId代表小说ID)
|
||||
<li><input type="text" id="bookDetailUrl" class="s_input icon_key"
|
||||
placeholder="详情页URL规则:"></li>
|
||||
示例:<b><p class="title">([^/]+)</p></b>
|
||||
<li><input type="text" id="bookNamePatten" class="s_input icon_key"
|
||||
placeholder="小说名的正则表达式:"></li>
|
||||
示例:<b>作者:([^/]+)<</b>
|
||||
<li><input type="text" id="authorNamePatten" class="s_input icon_key"
|
||||
placeholder="小说作者的正则表达式:"></li>
|
||||
示例:<b><img src="([^>]+)"\s+onerror="this.src=</b>
|
||||
<li><input type="text" id="picUrlPatten" class="s_input icon_key"
|
||||
placeholder="小说图片路径的正则表达式:"></li>
|
||||
<b>可空,适用于图片路径为相对路径的源站,加上小说图片路径,则为完整的可访问的图片路径</b>
|
||||
<li><input type="text" id="picUrlPrefix" class="s_input icon_key"
|
||||
placeholder="小说图片访问路径前缀:"></li>
|
||||
示例:<b>状态:([^/]+)</li></b>
|
||||
<li><input type="text" id="statusPatten" class="s_input icon_key"
|
||||
placeholder="小说状态的正则表达式:"></li>
|
||||
示例:<b>连载</b>
|
||||
<li><input type="text" id="bookStatus0" class="s_input icon_key"
|
||||
placeholder="连载中的小说在此网站的具体表现值:"></li>
|
||||
示例:<b>完结</b>
|
||||
<li><input type="text" id="bookStatus1" class="s_input icon_key"
|
||||
placeholder="全本小说在此网站的具体表现值:"></li>
|
||||
示例:<b><div\s+class="score">(\d+\.\d+)分</div></b>
|
||||
<li><input type="text" id="scorePatten" class="s_input icon_key"
|
||||
placeholder="小说评分的正则表达式:"></li>
|
||||
示例:<b></b>
|
||||
<li><input type="text" id="visitCountPatten" class="s_input icon_key"
|
||||
placeholder="小说点击量的正则表达式:"></li>
|
||||
示例:<b><p class="review"></b>
|
||||
<li><input type="text" id="descStart" class="s_input icon_key"
|
||||
placeholder="小说简介开始截取字符串:"></li>
|
||||
示例:<b></p></b>
|
||||
<li><input type="text" id="descEnd" class="s_input icon_key" placeholder="小说简介结束截取字符串:">
|
||||
</li>
|
||||
示例:<b>更新:(\d+-\d+-\d+\s\d+:\d+:\d+)</a></b>
|
||||
<li><input type="text" id="upadateTimePatten" class="s_input icon_key"
|
||||
placeholder="小说更新时间的正则表达式:"></li>
|
||||
示例:<b>yyyy-MM-dd HH:mm:ss</b>
|
||||
<li><input type="text" id="upadateTimeFormatPatten" class="s_input icon_key"
|
||||
placeholder="小说更新时间在此网站的显示模式:"></li>
|
||||
示例:<b>http://m.xdingdiann.com/ddk{bookId}/all.html</b> (bookId代表小说ID)
|
||||
<li><input type="text" id="bookIndexUrl" class="s_input icon_key"
|
||||
placeholder="小说目录页的URL规则:"></li>
|
||||
<b>可空,适用于最新章节列表和全部章节列表在同一个页面的源站</b>
|
||||
<li><input type="text" id="bookIndexStart" class="s_input icon_key"
|
||||
placeholder="小说目录页内容开始截取字符串:"></li>
|
||||
示例:<b><a\s+style=""\s+href="/ddk\d+/(\d+)\.html">[^/]+</a></b>
|
||||
<li><input type="text" id="indexIdPatten" class="s_input icon_key"
|
||||
placeholder="目录页目录ID正则表达式:"></li>
|
||||
示例:<b><a\s+style=""\s+href="/ddk\d+/\d+\.html">([^/]+)</a></b>
|
||||
<li><input type="text" id="indexNamePatten" class="s_input icon_key"
|
||||
placeholder="目录页目录名的正则表达式:"></li>
|
||||
示例:<b>http://m.xdingdiann.com/ddk{bookId}/{indexId}.html</b>
|
||||
(bookId代表小说ID,{indexId}代表目录ID)
|
||||
<li><input type="text" id="bookContentUrl" class="s_input icon_key"
|
||||
placeholder="小说内容页的URL规则:"></li>
|
||||
示例:<b>id="content"></b>
|
||||
<li><input type="text" id="contentStart" class="s_input icon_key"
|
||||
placeholder="小说内容开始截取字符串:"></li>
|
||||
示例:<b><script></b>
|
||||
<li><input type="text" id="contentEnd" class="s_input icon_key"
|
||||
placeholder="小说内容结束截取字符串:"></li>
|
||||
|
||||
<li><input type="button" onclick="updateCrawlSource()" name="btnRegister" value="提交"
|
||||
id="btnRegister" class="btn_red"></li>
|
||||
</ul>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<!--<div id="divData" class="updateTable">
|
||||
<table cellpadding="0" cellspacing="0">
|
||||
<thead>
|
||||
<tr>
|
||||
|
||||
<th class="name">
|
||||
爬虫源(已开启的爬虫源)
|
||||
</th>
|
||||
<th class="chapter">
|
||||
成功爬取数量(websocket实现)
|
||||
</th>
|
||||
<th class="time">
|
||||
目标爬取数量
|
||||
</th>
|
||||
<th class="goread">
|
||||
状态(正在运行,已停止)(一次只能运行一个爬虫源)
|
||||
</th>
|
||||
<th class="goread">
|
||||
操作(启动,停止)
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="bookShelfList">
|
||||
|
||||
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="pageBox cf" id="shellPage">
|
||||
</div>
|
||||
</div>-->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</body>
|
||||
<script src="/javascript/jquery-1.8.0.min.js" type="text/javascript"></script>
|
||||
<script src="/layui/layui.all.js" type="text/javascript"></script>
|
||||
<script src="/javascript/header.js" type="text/javascript"></script>
|
||||
<script src="/javascript/user.js" type="text/javascript"></script>
|
||||
<script language="javascript" type="text/javascript">
|
||||
|
||||
function load(){
|
||||
var crawlSourceId = localStorage.getItem("crawlSourceId")
|
||||
if(crawlSourceId!=null){
|
||||
$.ajax({
|
||||
type: "GET",
|
||||
url: "/crawl/getCrawlSource/"+crawlSourceId,
|
||||
dataType: "json",
|
||||
success: function (data) {
|
||||
if (data.code == 200) {
|
||||
loadPage(data.data);
|
||||
} else if (data.code == 1001) {
|
||||
//未登录
|
||||
location.href = '/user/login.html?originUrl=' + decodeURIComponent(location.href);
|
||||
|
||||
}else {
|
||||
layer.alert(data.msg);
|
||||
}
|
||||
|
||||
},
|
||||
error: function () {
|
||||
layer.alert('网络异常');
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
function loadPage(data){
|
||||
$("#sourceId").val(data.id);
|
||||
$("#sourceName").val(data.sourceName);
|
||||
if(data.crawlRule){
|
||||
|
||||
|
||||
var crawlRule= JSON.parse(data.crawlRule);
|
||||
$("#bookListUrl").val(crawlRule.bookListUrl);
|
||||
var catIdRule = crawlRule.catIdRule;
|
||||
try{
|
||||
for (var i = 1; i <= 7; i++) {
|
||||
$("#catId" + i).val(catIdRule["catId" + i]);
|
||||
}
|
||||
}catch(e){
|
||||
}
|
||||
$("#bookIdPatten").val(crawlRule.bookIdPatten);
|
||||
$("#pagePatten").val(crawlRule.pagePatten);
|
||||
$("#totalPagePatten").val(crawlRule.totalPagePatten);
|
||||
$("#bookDetailUrl").val(crawlRule.bookDetailUrl);
|
||||
$("#bookNamePatten").val(crawlRule.bookNamePatten);
|
||||
$("#authorNamePatten").val(crawlRule.authorNamePatten);
|
||||
$("#picUrlPatten").val(crawlRule.picUrlPatten);
|
||||
$("#picUrlPrefix").val(crawlRule.picUrlPrefix);
|
||||
$("#statusPatten").val(crawlRule.statusPatten);
|
||||
try{
|
||||
var bookStatusRule = crawlRule.bookStatusRule;
|
||||
var i=0;
|
||||
for(var key in bookStatusRule){
|
||||
$("#bookStatus" + i).val(key);
|
||||
i++;
|
||||
}
|
||||
}catch (e) {
|
||||
|
||||
}
|
||||
$("#scorePatten").val(crawlRule.scorePatten);
|
||||
$("#visitCountPatten").val(crawlRule.visitCountPatten);
|
||||
$("#descStart").val(crawlRule.descStart);
|
||||
$("#descEnd").val(crawlRule.descEnd);
|
||||
$("#upadateTimePatten").val(crawlRule.upadateTimePatten);
|
||||
$("#upadateTimeFormatPatten").val(crawlRule.upadateTimeFormatPatten);
|
||||
$("#bookIndexUrl").val(crawlRule.bookIndexUrl);
|
||||
$("#bookIndexStart").val(crawlRule.bookIndexStart);
|
||||
$("#indexIdPatten").val(crawlRule.indexIdPatten);
|
||||
$("#indexNamePatten").val(crawlRule.indexNamePatten);
|
||||
$("#bookContentUrl").val(crawlRule.bookContentUrl);
|
||||
$("#contentStart").val(crawlRule.contentStart);
|
||||
$("#contentEnd").val(crawlRule.contentEnd);
|
||||
|
||||
}
|
||||
}
|
||||
load();
|
||||
|
||||
function updateCrawlSource() {
|
||||
|
||||
var crawlRule = {};
|
||||
var sourceId =$("#sourceId").val();
|
||||
|
||||
var sourceName = $("#sourceName").val();
|
||||
if (sourceName.length == 0) {
|
||||
layer.alert("源站名必填");
|
||||
return false;
|
||||
}
|
||||
|
||||
var bookListUrl = $("#bookListUrl").val();
|
||||
if (bookListUrl.length == 0) {
|
||||
layer.alert("分类列表页URL规则必填");
|
||||
return false;
|
||||
}
|
||||
crawlRule.bookListUrl = bookListUrl;
|
||||
|
||||
var catIdRule = {};
|
||||
|
||||
for (var i = 1; i <= 7; i++) {
|
||||
var catId = $("#catId" + i).val();
|
||||
if (catId.length > 0) {
|
||||
catIdRule["catId" + i] = catId;
|
||||
}
|
||||
}
|
||||
|
||||
if (Object.keys(catIdRule).length == 0) {
|
||||
layer.alert("分类ID至少要填一项");
|
||||
return false;
|
||||
}
|
||||
crawlRule.catIdRule = catIdRule;
|
||||
|
||||
|
||||
var bookIdPatten = $("#bookIdPatten").val();
|
||||
|
||||
|
||||
if (bookIdPatten.length == 0) {
|
||||
layer.alert("列表页小说ID正则表达式必填");
|
||||
return false;
|
||||
}
|
||||
|
||||
crawlRule.bookIdPatten = bookIdPatten;
|
||||
|
||||
var pagePatten = $("#pagePatten").val();
|
||||
|
||||
if (pagePatten.length > 0) {
|
||||
crawlRule.pagePatten = pagePatten;
|
||||
}
|
||||
|
||||
var totalPagePatten = $("#totalPagePatten").val();
|
||||
|
||||
if (totalPagePatten.length > 0) {
|
||||
crawlRule.totalPagePatten = totalPagePatten;
|
||||
}
|
||||
|
||||
var bookDetailUrl = $("#bookDetailUrl").val();
|
||||
|
||||
if (bookDetailUrl.length == 0) {
|
||||
layer.alert("详情页URL规则必填");
|
||||
return false;
|
||||
}
|
||||
|
||||
crawlRule.bookDetailUrl = bookDetailUrl;
|
||||
|
||||
var bookNamePatten = $("#bookNamePatten").val();
|
||||
|
||||
if (bookNamePatten.length == 0) {
|
||||
layer.alert("小说名的正则表达式必填");
|
||||
return false;
|
||||
}
|
||||
|
||||
crawlRule.bookNamePatten = bookNamePatten;
|
||||
|
||||
var authorNamePatten = $("#authorNamePatten").val();
|
||||
|
||||
if (authorNamePatten.length == 0) {
|
||||
layer.alert("小说作者的正则表达式必填");
|
||||
return false;
|
||||
}
|
||||
|
||||
crawlRule.authorNamePatten = authorNamePatten;
|
||||
|
||||
var picUrlPatten = $("#picUrlPatten").val();
|
||||
|
||||
if (picUrlPatten.length > 0) {
|
||||
crawlRule.picUrlPatten = picUrlPatten;
|
||||
}
|
||||
|
||||
var picUrlPrefix = $("#picUrlPrefix").val();
|
||||
|
||||
if (picUrlPrefix.length > 0) {
|
||||
crawlRule.picUrlPrefix = picUrlPrefix;
|
||||
}
|
||||
|
||||
var statusPatten = $("#statusPatten").val();
|
||||
if (statusPatten.length > 0) {
|
||||
crawlRule.statusPatten = statusPatten;
|
||||
}
|
||||
|
||||
var bookStatusRule = {};
|
||||
|
||||
for (var i = 0; i <= 1; i++) {
|
||||
var bookStatus = $("#bookStatus" + i).val();
|
||||
if (bookStatus.length > 0) {
|
||||
bookStatusRule[bookStatus] = i;
|
||||
}
|
||||
}
|
||||
|
||||
crawlRule.bookStatusRule = bookStatusRule;
|
||||
|
||||
var scorePatten = $("#scorePatten").val();
|
||||
|
||||
if (scorePatten.length > 0) {
|
||||
crawlRule.scorePatten = scorePatten;
|
||||
}
|
||||
|
||||
var visitCountPatten = $("#visitCountPatten").val();
|
||||
|
||||
if (visitCountPatten.length > 0) {
|
||||
crawlRule.visitCountPatten = visitCountPatten;
|
||||
}
|
||||
|
||||
var descStart = $("#descStart").val();
|
||||
|
||||
if (descStart.length == 0) {
|
||||
layer.alert("小说简介开始截取字符串必填");
|
||||
return false;
|
||||
}
|
||||
|
||||
crawlRule.descStart = descStart;
|
||||
|
||||
var descEnd = $("#descEnd").val();
|
||||
|
||||
if (descEnd.length == 0) {
|
||||
layer.alert("小说简介结束截取字符串必填");
|
||||
return false;
|
||||
}
|
||||
|
||||
crawlRule.descEnd = descEnd;
|
||||
|
||||
var upadateTimePatten = $("#upadateTimePatten").val();
|
||||
|
||||
if (upadateTimePatten.length > 0) {
|
||||
crawlRule.upadateTimePatten = upadateTimePatten;
|
||||
}
|
||||
|
||||
var upadateTimeFormatPatten = $("#upadateTimeFormatPatten").val();
|
||||
|
||||
if (upadateTimeFormatPatten.length > 0) {
|
||||
crawlRule.upadateTimeFormatPatten = upadateTimeFormatPatten;
|
||||
}
|
||||
|
||||
var bookIndexUrl = $("#bookIndexUrl").val();
|
||||
|
||||
if (bookIndexUrl.length == 0) {
|
||||
layer.alert("小说目录页的URL规则必填");
|
||||
return false;
|
||||
}
|
||||
|
||||
crawlRule.bookIndexUrl = bookIndexUrl;
|
||||
|
||||
|
||||
var bookIndexStart = $("#bookIndexStart").val();
|
||||
|
||||
if (bookIndexStart.length > 0) {
|
||||
crawlRule.bookIndexStart = bookIndexStart;
|
||||
}
|
||||
|
||||
var indexIdPatten = $("#indexIdPatten").val();
|
||||
|
||||
if (indexIdPatten.length == 0) {
|
||||
layer.alert("小说目录页的目录ID正则表达式必填");
|
||||
return false;
|
||||
}
|
||||
|
||||
crawlRule.indexIdPatten = indexIdPatten;
|
||||
|
||||
var indexNamePatten = $("#indexNamePatten").val();
|
||||
|
||||
if (indexNamePatten.length == 0) {
|
||||
layer.alert("小说目录页的目录名正则表达式必填");
|
||||
return false;
|
||||
}
|
||||
|
||||
crawlRule.indexNamePatten = indexNamePatten;
|
||||
|
||||
var bookContentUrl = $("#bookContentUrl").val();
|
||||
|
||||
if (bookContentUrl.length == 0) {
|
||||
layer.alert("小说内容页的URL规则必填");
|
||||
return false;
|
||||
}
|
||||
|
||||
crawlRule.bookContentUrl = bookContentUrl;
|
||||
|
||||
var contentStart = $("#contentStart").val();
|
||||
|
||||
if (contentStart.length == 0) {
|
||||
layer.alert("小说内容开始截取字符串必填");
|
||||
return false;
|
||||
}
|
||||
crawlRule.contentStart = contentStart;
|
||||
|
||||
var contentEnd = $("#contentEnd").val();
|
||||
|
||||
if (contentEnd.length == 0) {
|
||||
layer.alert("小说内容结束截取字符串必填");
|
||||
return false;
|
||||
}
|
||||
|
||||
crawlRule.contentEnd = contentEnd;
|
||||
|
||||
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: "/crawl/updateCrawlSource",
|
||||
data: {'id':sourceId,'sourceName': sourceName, 'crawlRule': JSON.stringify(crawlRule)},
|
||||
dataType: "json",
|
||||
success: function (data) {
|
||||
if (data.code == 200) {
|
||||
|
||||
window.location.href = '/crawl/crawlSource_list.html';
|
||||
|
||||
|
||||
} else {
|
||||
layer.alert(data.msg);
|
||||
}
|
||||
|
||||
},
|
||||
error: function () {
|
||||
layer.alert('网络异常');
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
</script>
|
||||
</html>
|
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>novel</artifactId>
|
||||
<groupId>com.java2nb</groupId>
|
||||
<version>3.5.1</version>
|
||||
<version>3.6.1</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@ -70,14 +70,12 @@
|
||||
</dependency>
|
||||
|
||||
|
||||
|
||||
|
||||
<!--引入redisson分布式锁-->
|
||||
<!-- <dependency>
|
||||
<groupId>org.redisson</groupId>
|
||||
<artifactId>redisson-spring-boot-starter</artifactId>
|
||||
<version>${redisson.version}</version>
|
||||
</dependency>-->
|
||||
<!-- <dependency>
|
||||
<groupId>org.redisson</groupId>
|
||||
<artifactId>redisson-spring-boot-starter</artifactId>
|
||||
<version>${redisson.version}</version>
|
||||
</dependency>-->
|
||||
|
||||
|
||||
<dependency>
|
||||
@ -93,8 +91,159 @@
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-antrun-plugin</artifactId>
|
||||
<version>1.8</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>run</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<tasks>
|
||||
<!-- 文件夹 -->
|
||||
<copy todir="${project.build.directory}/build/config" overwrite="true">
|
||||
<fileset dir="${basedir}/src/main/build/config">
|
||||
<include name="*.*"/>
|
||||
</fileset>
|
||||
<fileset dir="${basedir}/src/main/resources">
|
||||
<include name="application-alipay.yml"/>
|
||||
<include name="application-website.yml"/>
|
||||
</fileset>
|
||||
</copy>
|
||||
<copy todir="${project.build.directory}/build/templates" overwrite="true">
|
||||
<fileset dir="${basedir}/../templates">
|
||||
<include name="**/*.*"/>
|
||||
</fileset>
|
||||
</copy>
|
||||
<copy file="${project.build.directory}/${project.artifactId}-${project.version}.jar"
|
||||
tofile="${project.build.directory}/build/${project.artifactId}.jar"/>
|
||||
|
||||
<fixcrlf srcdir="${basedir}/src/main/build/scripts" eol="unix"/>
|
||||
<copy todir="${project.build.directory}/build/bin">
|
||||
<fileset dir="${basedir}/src/main/build/scripts">
|
||||
<include name="*.sh"/>
|
||||
<include name="*.txt"/>
|
||||
<include name="*.bat"/>
|
||||
</fileset>
|
||||
</copy>
|
||||
<zip destfile='${project.build.directory}/build/${project.artifactId}.zip'>
|
||||
<zipfileset filemode="755" dir='${project.build.directory}/build/'/>
|
||||
</zip>
|
||||
</tasks>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<!-- <build>-->
|
||||
<!-- <plugins>-->
|
||||
<!-- <!– 将相同groupId的依赖模块打包进来 –>-->
|
||||
<!-- <plugin>-->
|
||||
<!-- <groupId>org.apache.maven.plugins</groupId>-->
|
||||
<!-- <artifactId>maven-shade-plugin</artifactId>-->
|
||||
<!-- <configuration>-->
|
||||
<!-- <createDependencyReducedPom>false</createDependencyReducedPom>-->
|
||||
<!-- </configuration>-->
|
||||
<!-- <executions>-->
|
||||
<!-- <execution>-->
|
||||
<!-- <phase>package</phase>-->
|
||||
<!-- <goals>-->
|
||||
<!-- <goal>shade</goal>-->
|
||||
<!-- </goals>-->
|
||||
<!-- <configuration>-->
|
||||
<!-- <artifactSet>-->
|
||||
<!-- <includes>-->
|
||||
<!-- <include>${project.groupId}:*:*</include>-->
|
||||
<!-- </includes>-->
|
||||
<!-- </artifactSet>-->
|
||||
<!-- </configuration>-->
|
||||
<!-- </execution>-->
|
||||
<!-- </executions>-->
|
||||
<!-- </plugin>-->
|
||||
<!-- <plugin>-->
|
||||
<!-- <!–打包时去除第三方依赖–>-->
|
||||
<!-- <groupId>org.springframework.boot</groupId>-->
|
||||
<!-- <artifactId>spring-boot-maven-plugin</artifactId>-->
|
||||
<!-- <configuration>-->
|
||||
<!-- <layout>ZIP</layout>-->
|
||||
<!-- <includes>-->
|
||||
<!-- <include>-->
|
||||
<!-- <groupId>non-exists</groupId>-->
|
||||
<!-- <artifactId>non-exists</artifactId>-->
|
||||
<!-- </include>-->
|
||||
<!-- </includes>-->
|
||||
<!-- </configuration>-->
|
||||
<!-- </plugin>-->
|
||||
<!-- <!–拷贝第三方依赖文件到指定目录–>-->
|
||||
<!-- <plugin>-->
|
||||
<!-- <groupId>org.apache.maven.plugins</groupId>-->
|
||||
<!-- <artifactId>maven-dependency-plugin</artifactId>-->
|
||||
<!-- <executions>-->
|
||||
<!-- <execution>-->
|
||||
<!-- <id>copy-dependencies</id>-->
|
||||
<!-- <phase>package</phase>-->
|
||||
<!-- <goals>-->
|
||||
<!-- <goal>copy-dependencies</goal>-->
|
||||
<!-- </goals>-->
|
||||
<!-- <configuration>-->
|
||||
<!-- <!–target/lib是依赖jar包的输出目录,根据自己喜好配置–>-->
|
||||
<!-- <outputDirectory>target/lib</outputDirectory>-->
|
||||
<!-- <excludeTransitive>false</excludeTransitive>-->
|
||||
<!-- <stripVersion>false</stripVersion>-->
|
||||
<!-- <includeScope>runtime</includeScope>-->
|
||||
<!-- <excludeGroupIds>${project.groupId}</excludeGroupIds>-->
|
||||
<!-- </configuration>-->
|
||||
<!-- </execution>-->
|
||||
<!-- </executions>-->
|
||||
<!-- </plugin>-->
|
||||
<!-- <plugin>-->
|
||||
<!-- <artifactId>maven-antrun-plugin</artifactId>-->
|
||||
<!-- <version>1.8</version>-->
|
||||
<!-- <executions>-->
|
||||
<!-- <execution>-->
|
||||
<!-- <phase>package</phase>-->
|
||||
<!-- <goals>-->
|
||||
<!-- <goal>run</goal>-->
|
||||
<!-- </goals>-->
|
||||
<!-- <configuration>-->
|
||||
<!-- <tasks>-->
|
||||
<!-- <!– 文件夹 –>-->
|
||||
<!-- <copy todir="${project.build.directory}/build/conf" overwrite="true">-->
|
||||
<!-- <fileset dir="${basedir}/src/main/resources">-->
|
||||
<!-- <include name="**/*.*"/>-->
|
||||
<!-- <exclude name="mybatis/*/*.*"/>-->
|
||||
<!-- </fileset>-->
|
||||
<!-- <fileset dir="${basedir}/../novel-common/src/main/resources">-->
|
||||
<!-- <include name="**/*.*"/>-->
|
||||
<!-- <exclude name="mybatis/**"/>-->
|
||||
<!-- </fileset>-->
|
||||
<!-- </copy>-->
|
||||
<!-- <move todir="${project.build.directory}/build/lib">-->
|
||||
<!-- <fileset dir="target/lib"/>-->
|
||||
<!-- </move>-->
|
||||
<!-- <copy file="${project.build.directory}/${project.artifactId}-${project.version}.jar"-->
|
||||
<!-- tofile="${project.build.directory}/build/${project.artifactId}.jar" />-->
|
||||
|
||||
<!-- <fixcrlf srcdir="${basedir}/src/main/build/scripts" eol="unix"/>-->
|
||||
<!-- <copy todir="${project.build.directory}/build/bin">-->
|
||||
<!-- <fileset dir="${basedir}/src/main/build/scripts">-->
|
||||
<!-- <include name="*.sh" />-->
|
||||
<!-- <include name="*.txt" />-->
|
||||
<!-- <include name="*.bat" />-->
|
||||
<!-- </fileset>-->
|
||||
<!-- </copy>-->
|
||||
<!-- <zip destfile='${project.build.directory}/build/${project.artifactId}.zip'>-->
|
||||
<!-- <zipfileset filemode="755" dir= '${project.build.directory}/build/' />-->
|
||||
<!-- </zip>-->
|
||||
<!-- </tasks>-->
|
||||
<!-- </configuration>-->
|
||||
<!-- </execution>-->
|
||||
<!-- </executions>-->
|
||||
<!-- </plugin>-->
|
||||
<!-- </plugins>-->
|
||||
<!-- </build>-->
|
||||
|
||||
</project>
|
||||
</project>
|
||||
|
@ -0,0 +1,45 @@
|
||||
#端口号
|
||||
server:
|
||||
port: 8085
|
||||
|
||||
#不分表的数据库配置
|
||||
spring:
|
||||
datasource:
|
||||
url: jdbc:mysql://127.0.0.1:3306/novel_plus?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai
|
||||
username: root
|
||||
password: root
|
||||
|
||||
|
||||
####使用shardingJdbc时,
|
||||
####所有的jdbcType都不能是LONGVARCHAR,否则会导致java.io.NotSerializableException: java.io.StringReader错误
|
||||
##### 应该替换所有的 LONGVARCHAR 类型为VARCHAR
|
||||
sharding:
|
||||
jdbc:
|
||||
datasource:
|
||||
ds0:
|
||||
jdbc-url: jdbc:mysql://localhost:3306/novel_plus?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai
|
||||
username: root
|
||||
password: test123456
|
||||
|
||||
pic:
|
||||
save:
|
||||
#图片保存方式, 1不保存,使用网络图片 ,2本地保存
|
||||
type: 2
|
||||
#图片保存路径
|
||||
path: /var/pic
|
||||
|
||||
|
||||
#模版配置
|
||||
templates:
|
||||
name: orange
|
||||
|
||||
#小说内容保存配置
|
||||
content:
|
||||
save:
|
||||
storage: db #存储介质,db:数据库,file:txt文本
|
||||
path: /Users/xiongxiaoyang/books #txt小说文本保存路径
|
||||
|
||||
|
||||
|
||||
|
||||
|
94
novel-front/src/main/build/scripts/novel-front.sh
Normal file
94
novel-front/src/main/build/scripts/novel-front.sh
Normal file
@ -0,0 +1,94 @@
|
||||
#!/bin/sh
|
||||
APP_NAME=novel-front
|
||||
JAR_NAME=$APP_NAME\.jar
|
||||
#PID 代表是PID文件
|
||||
PID=$APP_NAME\.pid
|
||||
|
||||
|
||||
#使用说明,用来提示输入参数
|
||||
usage() {
|
||||
echo "Usage: ./novel-front.sh [start|stop|restart|status]"
|
||||
exit 1
|
||||
}
|
||||
|
||||
#检查程序是否在运行
|
||||
is_exist(){
|
||||
pid=`ps -ef|grep $JAR_NAME|grep -v grep|awk '{print $2}' `
|
||||
#如果不存在返回1,存在返回0
|
||||
if [ -z "${pid}" ]; then
|
||||
return 1
|
||||
else
|
||||
return 0
|
||||
fi
|
||||
}
|
||||
|
||||
#启动方法
|
||||
start(){
|
||||
is_exist
|
||||
if [ $? -eq "0" ]; then
|
||||
echo ">>> 小说精品屋前台正在运行 PID = ${pid} <<<"
|
||||
else
|
||||
echo ">>> 小说精品屋前台开始启动 <<<"
|
||||
nohup java -jar -Dspring.profiles.active=prod $JAR_NAME >/dev/null 2>&1 &
|
||||
sleep 20
|
||||
echo $! > $PID
|
||||
echo ">>> 小说精品屋前台启动完成 PID = $! <<<"
|
||||
status
|
||||
fi
|
||||
}
|
||||
|
||||
#停止方法
|
||||
stop(){
|
||||
#is_exist
|
||||
pidf=$(cat $PID)
|
||||
#echo "$pidf"
|
||||
echo ">>> 小说精品屋前台 PID = $pidf 开始停止 <<<"
|
||||
kill $pidf
|
||||
rm -rf $PID
|
||||
sleep 2
|
||||
is_exist
|
||||
if [ $? -eq "0" ]; then
|
||||
echo ">>> 小说精品屋前台 PID = $pid 开始强制停止 <<<"
|
||||
kill -9 $pid
|
||||
sleep 2
|
||||
status
|
||||
else
|
||||
status
|
||||
fi
|
||||
}
|
||||
|
||||
#输出运行状态
|
||||
status(){
|
||||
is_exist
|
||||
if [ $? -eq "0" ]; then
|
||||
echo ">>> 小说精品屋前台正在运行 PID = ${pid} <<<"
|
||||
else
|
||||
echo ">>> 小说精品屋前台没有运行 <<<"
|
||||
fi
|
||||
}
|
||||
|
||||
#重启
|
||||
restart(){
|
||||
stop
|
||||
start
|
||||
}
|
||||
|
||||
#根据输入参数,选择执行对应方法,不输入则执行使用说明
|
||||
case "$1" in
|
||||
"start")
|
||||
start
|
||||
;;
|
||||
"stop")
|
||||
stop
|
||||
;;
|
||||
"status")
|
||||
status
|
||||
;;
|
||||
"restart")
|
||||
restart
|
||||
;;
|
||||
*)
|
||||
usage
|
||||
;;
|
||||
esac
|
||||
exit 0
|
@ -1,12 +1,14 @@
|
||||
package com.java2nb.novel;
|
||||
|
||||
import com.github.tobato.fastdfs.FdfsClientConfig;
|
||||
import io.shardingsphere.shardingjdbc.spring.boot.SpringBootConfiguration;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.mybatis.spring.annotation.MapperScan;
|
||||
import org.springframework.boot.CommandLineRunner;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.web.servlet.ServletComponentScan;
|
||||
import org.springframework.cache.annotation.EnableCaching;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.scheduling.TaskScheduler;
|
||||
@ -14,6 +16,8 @@ import org.springframework.scheduling.annotation.EnableScheduling;
|
||||
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
|
||||
import org.springframework.transaction.annotation.EnableTransactionManagement;
|
||||
|
||||
import java.net.InetAddress;
|
||||
|
||||
/**
|
||||
* @author Administrator
|
||||
*/
|
||||
@ -24,15 +28,23 @@ import org.springframework.transaction.annotation.EnableTransactionManagement;
|
||||
@ServletComponentScan
|
||||
@MapperScan(basePackages = {"com.java2nb.novel.mapper"})
|
||||
@Import(FdfsClientConfig.class)
|
||||
@Slf4j
|
||||
public class FrontNovelApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(FrontNovelApplication.class);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public CommandLineRunner commandLineRunner(ApplicationContext ctx) {
|
||||
return args -> {
|
||||
log.info("项目启动啦,访问路径:{}", "http://" + InetAddress.getLocalHost().getHostAddress() + ":" + ctx.getEnvironment().getProperty("server.port"));
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 解决同一时间只能一个定时任务执行的问题
|
||||
* */
|
||||
*/
|
||||
@Bean
|
||||
public TaskScheduler taskScheduler() {
|
||||
ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
|
||||
|
@ -1,22 +1,22 @@
|
||||
package com.java2nb.novel.controller;
|
||||
|
||||
import com.github.pagehelper.PageInfo;
|
||||
import com.java2nb.novel.core.bean.ResultBean;
|
||||
import io.github.xxyopen.model.page.PageBean;
|
||||
|
||||
import com.java2nb.novel.core.bean.UserDetails;
|
||||
import com.java2nb.novel.core.enums.ResponseStatus;
|
||||
import com.java2nb.novel.core.exception.BusinessException;
|
||||
import com.java2nb.novel.core.utils.BeanUtil;
|
||||
import io.github.xxyopen.model.resp.RestResult;
|
||||
import io.github.xxyopen.web.exception.BusinessException;
|
||||
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.service.AuthorService;
|
||||
import com.java2nb.novel.service.BookService;
|
||||
import com.java2nb.novel.service.FriendLinkService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
@ -36,25 +36,25 @@ public class AuthorController extends BaseController{
|
||||
* 校验笔名是否存在
|
||||
* */
|
||||
@GetMapping("checkPenName")
|
||||
public ResultBean checkPenName(String penName){
|
||||
public RestResult<Boolean> checkPenName(String penName){
|
||||
|
||||
return ResultBean.ok(authorService.checkPenName(penName));
|
||||
return RestResult.ok(authorService.checkPenName(penName));
|
||||
}
|
||||
|
||||
/**
|
||||
* 作家发布小说分页列表查询
|
||||
* */
|
||||
@GetMapping("listBookByPage")
|
||||
public ResultBean listBookByPage(@RequestParam(value = "curr", defaultValue = "1") int page, @RequestParam(value = "limit", defaultValue = "10") int pageSize ,HttpServletRequest request){
|
||||
public RestResult<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 RestResult.ok(bookService.listBookPageByUserId(getUserDetails(request).getId(),page,pageSize));
|
||||
}
|
||||
|
||||
/**
|
||||
* 发布小说
|
||||
* */
|
||||
@PostMapping("addBook")
|
||||
public ResultBean addBook(@RequestParam("bookDesc") String bookDesc,Book book,HttpServletRequest request){
|
||||
public RestResult<Void> addBook(@RequestParam("bookDesc") String bookDesc,Book book,HttpServletRequest request){
|
||||
|
||||
Author author = checkAuthor(request);
|
||||
|
||||
@ -65,20 +65,20 @@ public class AuthorController extends BaseController{
|
||||
//发布小说
|
||||
bookService.addBook(book,author.getId(),author.getPenName());
|
||||
|
||||
return ResultBean.ok();
|
||||
return RestResult.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新小说状态,上架或下架
|
||||
* */
|
||||
@PostMapping("updateBookStatus")
|
||||
public ResultBean updateBookStatus(Long bookId,Byte status,HttpServletRequest request){
|
||||
public RestResult<Void> updateBookStatus(Long bookId,Byte status,HttpServletRequest request){
|
||||
Author author = checkAuthor(request);
|
||||
|
||||
//更新小说状态,上架或下架
|
||||
bookService.updateBookStatus(bookId,status,author.getId());
|
||||
|
||||
return ResultBean.ok();
|
||||
return RestResult.ok();
|
||||
}
|
||||
|
||||
|
||||
@ -87,28 +87,28 @@ public class AuthorController extends BaseController{
|
||||
* 删除章节
|
||||
*/
|
||||
@DeleteMapping("deleteIndex/{indexId}")
|
||||
public ResultBean deleteIndex(@PathVariable("indexId") Long indexId, HttpServletRequest request) {
|
||||
public RestResult<Void> deleteIndex(@PathVariable("indexId") Long indexId, HttpServletRequest request) {
|
||||
|
||||
Author author = checkAuthor(request);
|
||||
|
||||
//删除章节
|
||||
bookService.deleteIndex(indexId, author.getId());
|
||||
|
||||
return ResultBean.ok();
|
||||
return RestResult.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新章节名
|
||||
*/
|
||||
@PostMapping("updateIndexName")
|
||||
public ResultBean updateIndexName(Long indexId, String indexName, HttpServletRequest request) {
|
||||
public RestResult<Void> updateIndexName(Long indexId, String indexName, HttpServletRequest request) {
|
||||
|
||||
Author author = checkAuthor(request);
|
||||
|
||||
//更新章节名
|
||||
bookService.updateIndexName(indexId, indexName, author.getId());
|
||||
|
||||
return ResultBean.ok();
|
||||
return RestResult.ok();
|
||||
}
|
||||
|
||||
|
||||
@ -118,7 +118,7 @@ public class AuthorController extends BaseController{
|
||||
* 发布章节内容
|
||||
*/
|
||||
@PostMapping("addBookContent")
|
||||
public ResultBean addBookContent(Long bookId, String indexName, String content,Byte isVip, HttpServletRequest request) {
|
||||
public RestResult<Void> addBookContent(Long bookId, String indexName, String content,Byte isVip, HttpServletRequest request) {
|
||||
Author author = checkAuthor(request);
|
||||
|
||||
content = content.replaceAll("\\n", "<br>")
|
||||
@ -126,14 +126,14 @@ public class AuthorController extends BaseController{
|
||||
//发布章节内容
|
||||
bookService.addBookContent(bookId, indexName, content,isVip, author.getId());
|
||||
|
||||
return ResultBean.ok();
|
||||
return RestResult.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询章节内容
|
||||
*/
|
||||
@GetMapping("queryIndexContent/{indexId}")
|
||||
public ResultBean queryIndexContent(@PathVariable("indexId") Long indexId, HttpServletRequest request) {
|
||||
public RestResult<String> queryIndexContent(@PathVariable("indexId") Long indexId, HttpServletRequest request) {
|
||||
|
||||
Author author = checkAuthor(request);
|
||||
|
||||
@ -142,14 +142,14 @@ public class AuthorController extends BaseController{
|
||||
content = content.replaceAll("<br>", "\n")
|
||||
.replaceAll(" ", " ");
|
||||
|
||||
return ResultBean.ok(content);
|
||||
return RestResult.ok(content);
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新章节内容
|
||||
*/
|
||||
@PostMapping("updateBookContent")
|
||||
public ResultBean updateBookContent(Long indexId, String indexName, String content, HttpServletRequest request) {
|
||||
public RestResult<Void> updateBookContent(Long indexId, String indexName, String content, HttpServletRequest request) {
|
||||
Author author = checkAuthor(request);
|
||||
|
||||
content = content.replaceAll("\\n", "<br>")
|
||||
@ -157,21 +157,32 @@ public class AuthorController extends BaseController{
|
||||
//更新章节内容
|
||||
bookService.updateBookContent(indexId, indexName, content, author.getId());
|
||||
|
||||
return ResultBean.ok();
|
||||
return RestResult.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改小说封面
|
||||
*/
|
||||
@PostMapping("updateBookPic")
|
||||
public RestResult<Void> updateBookPic(@RequestParam("bookId") Long bookId,@RequestParam("bookPic") String bookPic,HttpServletRequest request) {
|
||||
Author author = checkAuthor(request);
|
||||
bookService.updateBookPic(bookId,bookPic, author.getId());
|
||||
return RestResult.ok();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 作家日收入统计数据分页列表查询
|
||||
* */
|
||||
@GetMapping("listIncomeDailyByPage")
|
||||
public ResultBean listIncomeDailyByPage(@RequestParam(value = "curr", defaultValue = "1") int page,
|
||||
@RequestParam(value = "limit", defaultValue = "10") int pageSize ,
|
||||
@RequestParam(value = "bookId", defaultValue = "0") Long bookId,
|
||||
@RequestParam(value = "startTime",defaultValue = "2020-05-01") Date startTime,
|
||||
@RequestParam(value = "endTime",defaultValue = "2030-01-01") Date endTime,
|
||||
HttpServletRequest request){
|
||||
public RestResult<PageBean<AuthorIncomeDetail>> listIncomeDailyByPage(@RequestParam(value = "curr", defaultValue = "1") int page,
|
||||
@RequestParam(value = "limit", defaultValue = "10") int pageSize ,
|
||||
@RequestParam(value = "bookId", defaultValue = "0") Long bookId,
|
||||
@RequestParam(value = "startTime",defaultValue = "2020-05-01") Date startTime,
|
||||
@RequestParam(value = "endTime",defaultValue = "2030-01-01") Date endTime,
|
||||
HttpServletRequest request){
|
||||
|
||||
return ResultBean.ok(authorService.listIncomeDailyByPage(page,pageSize,getUserDetails(request).getId(),bookId,startTime,endTime));
|
||||
return RestResult.ok(authorService.listIncomeDailyByPage(page,pageSize,getUserDetails(request).getId(),bookId,startTime,endTime));
|
||||
}
|
||||
|
||||
|
||||
@ -179,12 +190,12 @@ public class AuthorController extends BaseController{
|
||||
* 作家月收入统计数据分页列表查询
|
||||
* */
|
||||
@GetMapping("listIncomeMonthByPage")
|
||||
public ResultBean listIncomeMonthByPage(@RequestParam(value = "curr", defaultValue = "1") int page,
|
||||
@RequestParam(value = "limit", defaultValue = "10") int pageSize ,
|
||||
@RequestParam(value = "bookId", defaultValue = "0") Long bookId,
|
||||
HttpServletRequest request){
|
||||
public RestResult<PageBean<AuthorIncome>> listIncomeMonthByPage(@RequestParam(value = "curr", defaultValue = "1") int page,
|
||||
@RequestParam(value = "limit", defaultValue = "10") int pageSize ,
|
||||
@RequestParam(value = "bookId", defaultValue = "0") Long bookId,
|
||||
HttpServletRequest request){
|
||||
|
||||
return ResultBean.ok(authorService.listIncomeMonthByPage(page,pageSize,getUserDetails(request).getId(),bookId));
|
||||
return RestResult.ok(authorService.listIncomeMonthByPage(page,pageSize,getUserDetails(request).getId(),bookId));
|
||||
}
|
||||
|
||||
private Author checkAuthor(HttpServletRequest request) {
|
||||
|
@ -1,15 +1,20 @@
|
||||
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.UserDetails;
|
||||
import com.java2nb.novel.core.enums.ResponseStatus;
|
||||
import com.java2nb.novel.entity.Book;
|
||||
import com.java2nb.novel.entity.BookCategory;
|
||||
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.service.BookService;
|
||||
import com.java2nb.novel.vo.BookVO;
|
||||
import io.github.xxyopen.model.page.PageBean;
|
||||
import io.github.xxyopen.model.page.builder.pagehelper.PageBuilder;
|
||||
import io.github.xxyopen.model.resp.RestResult;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.amqp.rabbit.core.RabbitTemplate;
|
||||
@ -18,6 +23,7 @@ import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
@ -27,158 +33,157 @@ import java.util.Map;
|
||||
@RestController
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
public class BookController extends BaseController{
|
||||
public class BookController extends BaseController {
|
||||
|
||||
private final BookService bookService;
|
||||
|
||||
private final RabbitTemplate rabbitTemplate;
|
||||
|
||||
private final Map<String, BookContentService> bookContentServiceMap;
|
||||
|
||||
@Value("${spring.rabbitmq.enable}")
|
||||
private Integer enableMq;
|
||||
|
||||
|
||||
/**
|
||||
* 查询首页小说设置列表数据
|
||||
* */
|
||||
*/
|
||||
@GetMapping("listBookSetting")
|
||||
public ResultBean listBookSetting(){
|
||||
return ResultBean.ok(bookService.listBookSettingVO());
|
||||
public RestResult<Map<Byte, List<BookSettingVO>>> listBookSetting() {
|
||||
return RestResult.ok(bookService.listBookSettingVO());
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询首页点击榜单数据
|
||||
* */
|
||||
*/
|
||||
@GetMapping("listClickRank")
|
||||
public ResultBean listClickRank(){
|
||||
return ResultBean.ok(bookService.listClickRank());
|
||||
public RestResult<List<Book>> listClickRank() {
|
||||
return RestResult.ok(bookService.listClickRank());
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询首页新书榜单数据
|
||||
* */
|
||||
*/
|
||||
@GetMapping("listNewRank")
|
||||
public ResultBean listNewRank(){
|
||||
return ResultBean.ok(bookService.listNewRank());
|
||||
public RestResult<List<Book>> listNewRank() {
|
||||
return RestResult.ok(bookService.listNewRank());
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询首页更新榜单数据
|
||||
* */
|
||||
*/
|
||||
@GetMapping("listUpdateRank")
|
||||
public ResultBean listUpdateRank(){
|
||||
return ResultBean.ok(bookService.listUpdateRank());
|
||||
public RestResult<List<BookVO>> listUpdateRank() {
|
||||
return RestResult.ok(bookService.listUpdateRank());
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询小说分类列表
|
||||
* */
|
||||
*/
|
||||
@GetMapping("listBookCategory")
|
||||
public ResultBean listBookCategory(){
|
||||
return ResultBean.ok(bookService.listBookCategory());
|
||||
public RestResult<List<BookCategory>> listBookCategory() {
|
||||
return RestResult.ok(bookService.listBookCategory());
|
||||
}
|
||||
|
||||
/**
|
||||
* 分页搜索
|
||||
* */
|
||||
*/
|
||||
@GetMapping("searchByPage")
|
||||
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));
|
||||
public RestResult<?> searchByPage(BookSpVO bookSP, @RequestParam(value = "curr", defaultValue = "1") int page, @RequestParam(value = "limit", defaultValue = "20") int pageSize) {
|
||||
return RestResult.ok(bookService.searchByPage(bookSP, page, pageSize));
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询小说详情信息
|
||||
* */
|
||||
*/
|
||||
@GetMapping("queryBookDetail/{id}")
|
||||
public ResultBean queryBookDetail(@PathVariable("id") Long id){
|
||||
return ResultBean.ok(bookService.queryBookDetail(id));
|
||||
public RestResult<Book> queryBookDetail(@PathVariable("id") Long id) {
|
||||
return RestResult.ok(bookService.queryBookDetail(id));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 查询小说排行信息
|
||||
* */
|
||||
*/
|
||||
@GetMapping("listRank")
|
||||
public ResultBean listRank(@RequestParam(value = "type",defaultValue = "0") Byte type,@RequestParam(value = "limit",defaultValue = "30") Integer limit){
|
||||
return ResultBean.ok(bookService.listRank(type,limit));
|
||||
public RestResult<List<Book>> listRank(@RequestParam(value = "type", defaultValue = "0") Byte type, @RequestParam(value = "limit", defaultValue = "30") Integer limit) {
|
||||
return RestResult.ok(bookService.listRank(type, limit));
|
||||
}
|
||||
|
||||
/**
|
||||
* 增加点击次数
|
||||
* */
|
||||
*/
|
||||
@PostMapping("addVisitCount")
|
||||
public ResultBean addVisitCount(Long bookId){
|
||||
if(enableMq == 1) {
|
||||
public RestResult<Void> addVisitCount(Long bookId) {
|
||||
if (enableMq == 1) {
|
||||
rabbitTemplate.convertAndSend("ADD-BOOK-VISIT-EXCHANGE", null, bookId);
|
||||
}else {
|
||||
} else {
|
||||
bookService.addVisitCount(bookId, 1);
|
||||
}
|
||||
return ResultBean.ok();
|
||||
return RestResult.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询章节相关信息
|
||||
* */
|
||||
*/
|
||||
@GetMapping("queryBookIndexAbout")
|
||||
public ResultBean queryBookIndexAbout(Long bookId,Long lastBookIndexId) {
|
||||
Map<String,Object> data = new HashMap<>(2);
|
||||
data.put("bookIndexCount",bookService.queryIndexCount(bookId));
|
||||
String lastBookContent = bookService.queryBookContent(lastBookIndexId).getContent();
|
||||
if(lastBookContent.length()>42){
|
||||
lastBookContent=lastBookContent.substring(0,42);
|
||||
public RestResult<Map<String, Object>> queryBookIndexAbout(Long bookId, Long lastBookIndexId) {
|
||||
Map<String, Object> data = new HashMap<>(2);
|
||||
data.put("bookIndexCount", bookService.queryIndexCount(bookId));
|
||||
BookIndex bookIndex = bookService.queryBookIndex(lastBookIndexId);
|
||||
String lastBookContent = bookContentServiceMap.get(bookIndex.getStorageType()).queryBookContent(bookId,lastBookIndexId).getContent();
|
||||
if (lastBookContent.length() > 42) {
|
||||
lastBookContent = lastBookContent.substring(0, 42);
|
||||
}
|
||||
data.put("lastBookContent",lastBookContent);
|
||||
return ResultBean.ok(data);
|
||||
data.put("lastBookContent", lastBookContent);
|
||||
return RestResult.ok(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据分类id查询同类推荐书籍
|
||||
* */
|
||||
*/
|
||||
@GetMapping("listRecBookByCatId")
|
||||
public ResultBean listRecBookByCatId(Integer catId) {
|
||||
return ResultBean.ok(bookService.listRecBookByCatId(catId));
|
||||
public RestResult<List<Book>> listRecBookByCatId(Integer catId) {
|
||||
return RestResult.ok(bookService.listRecBookByCatId(catId));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*分页查询书籍评论列表
|
||||
* */
|
||||
* 分页查询书籍评论列表
|
||||
*/
|
||||
@GetMapping("listCommentByPage")
|
||||
public ResultBean 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));
|
||||
public RestResult<PageBean<BookCommentVO>> listCommentByPage(@RequestParam("bookId") Long bookId, @RequestParam(value = "curr", defaultValue = "1") int page, @RequestParam(value = "limit", defaultValue = "5") int pageSize) {
|
||||
return RestResult.ok(bookService.listCommentByPage(null, bookId, page, pageSize));
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增评价
|
||||
* */
|
||||
*/
|
||||
@PostMapping("addBookComment")
|
||||
public ResultBean addBookComment(BookComment comment, HttpServletRequest request) {
|
||||
public RestResult<?> addBookComment(BookComment comment, HttpServletRequest request) {
|
||||
UserDetails userDetails = getUserDetails(request);
|
||||
if (userDetails == null) {
|
||||
return ResultBean.fail(ResponseStatus.NO_LOGIN);
|
||||
return RestResult.fail(ResponseStatus.NO_LOGIN);
|
||||
}
|
||||
bookService.addBookComment(userDetails.getId(),comment);
|
||||
return ResultBean.ok();
|
||||
bookService.addBookComment(userDetails.getId(), comment);
|
||||
return RestResult.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据小说ID查询小说前十条最新更新目录集合
|
||||
* */
|
||||
*/
|
||||
@GetMapping("queryNewIndexList")
|
||||
public ResultBean queryNewIndexList(Long bookId){
|
||||
return ResultBean.ok(bookService.queryIndexList(bookId,"index_num desc",1,10));
|
||||
public RestResult<List<BookIndex>> queryNewIndexList(Long bookId) {
|
||||
return RestResult.ok(bookService.queryIndexList(bookId, "index_num desc", 1, 10));
|
||||
}
|
||||
|
||||
/**
|
||||
* 目录页
|
||||
* */
|
||||
*/
|
||||
@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) {
|
||||
return ResultBean.ok(new PageBean<>(bookService.queryIndexList(bookId,orderBy,page,pageSize)));
|
||||
public RestResult<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 RestResult.ok(PageBuilder.build(bookService.queryIndexList(bookId, orderBy, page, pageSize)));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
@ -1,12 +1,13 @@
|
||||
package com.java2nb.novel.controller;
|
||||
|
||||
import com.java2nb.novel.core.bean.ResultBean;
|
||||
|
||||
import com.java2nb.novel.core.cache.CacheKey;
|
||||
import com.java2nb.novel.core.cache.CacheService;
|
||||
import com.java2nb.novel.core.enums.ResponseStatus;
|
||||
import com.java2nb.novel.service.BookService;
|
||||
import com.java2nb.novel.service.FriendLinkService;
|
||||
import com.java2nb.novel.service.NewsService;
|
||||
import io.github.xxyopen.model.resp.RestResult;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
@ -40,9 +41,9 @@ public class CacheController {
|
||||
* @param type 缓存类型,1:首页书籍推荐,2:首页新闻,3:首页友情链接
|
||||
* */
|
||||
@GetMapping("refresh/{pass}/{type}")
|
||||
public ResultBean refreshCache(@PathVariable("type") Byte type, @PathVariable("pass") String pass){
|
||||
public RestResult<Void> refreshCache(@PathVariable("type") Byte type, @PathVariable("pass") String pass){
|
||||
if(!cacheManagerPass.equals(pass)){
|
||||
return ResultBean.fail(ResponseStatus.PASSWORD_ERROR);
|
||||
return RestResult.fail(ResponseStatus.PASSWORD_ERROR);
|
||||
}
|
||||
switch (type){
|
||||
case 1:{
|
||||
@ -69,7 +70,7 @@ public class CacheController {
|
||||
|
||||
}
|
||||
|
||||
return ResultBean.ok();
|
||||
return RestResult.ok();
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,32 +1,27 @@
|
||||
package com.java2nb.novel.controller;
|
||||
|
||||
import com.java2nb.novel.core.bean.ResultBean;
|
||||
|
||||
import com.java2nb.novel.core.cache.CacheService;
|
||||
import com.java2nb.novel.core.enums.ResponseStatus;
|
||||
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.RestTemplateUtil;
|
||||
import com.java2nb.novel.core.utils.UUIDUtil;
|
||||
import io.github.xxyopen.model.resp.RestResult;
|
||||
import io.github.xxyopen.util.UUIDUtil;
|
||||
import io.github.xxyopen.web.exception.BusinessException;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.SneakyThrows;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.codec.Charsets;
|
||||
import org.apache.http.client.utils.DateUtils;
|
||||
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.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.servlet.http.HttpSession;
|
||||
import java.io.*;
|
||||
import java.io.File;
|
||||
import java.util.Date;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* @author 11797
|
||||
@ -63,29 +58,35 @@ public class FileController {
|
||||
}
|
||||
|
||||
/**
|
||||
* 文件上传
|
||||
* 图片上传
|
||||
* @return
|
||||
*/
|
||||
@SneakyThrows
|
||||
@ResponseBody
|
||||
@PostMapping("/upload")
|
||||
ResultBean upload(@RequestParam("file") MultipartFile file) {
|
||||
@PostMapping("/picUpload")
|
||||
RestResult<String> upload(@RequestParam("file") MultipartFile file) {
|
||||
Date currentDate = new Date();
|
||||
try {
|
||||
String savePath =
|
||||
Constants.LOCAL_PIC_PREFIX + DateUtils.formatDate(currentDate, "yyyy") + "/" +
|
||||
DateUtils.formatDate(currentDate, "MM") + "/" +
|
||||
DateUtils.formatDate(currentDate, "dd") ;
|
||||
String oriName = file.getOriginalFilename();
|
||||
String saveFileName = UUIDUtil.getUUID32() + oriName.substring(oriName.lastIndexOf("."));
|
||||
File saveFile = new File( picSavePath + savePath, saveFileName);
|
||||
if (!saveFile.getParentFile().exists()) {
|
||||
saveFile.getParentFile().mkdirs();
|
||||
String savePath =
|
||||
Constants.LOCAL_PIC_PREFIX + DateUtils.formatDate(currentDate, "yyyy") + "/" +
|
||||
DateUtils.formatDate(currentDate, "MM") + "/" +
|
||||
DateUtils.formatDate(currentDate, "dd");
|
||||
String oriName = file.getOriginalFilename();
|
||||
assert oriName != null;
|
||||
String saveFileName = UUIDUtil.getUUID32() + oriName.substring(oriName.lastIndexOf("."));
|
||||
File saveFile = new File(picSavePath + savePath, saveFileName);
|
||||
if (!saveFile.getParentFile().exists()) {
|
||||
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 RestResult.ok(savePath + "/" + saveFileName);
|
||||
|
||||
}
|
||||
|
||||
|
@ -1,14 +1,17 @@
|
||||
package com.java2nb.novel.controller;
|
||||
|
||||
import com.java2nb.novel.core.bean.ResultBean;
|
||||
|
||||
import com.java2nb.novel.entity.FriendLink;
|
||||
import com.java2nb.novel.service.FriendLinkService;
|
||||
import io.github.xxyopen.model.resp.RestResult;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author 11797
|
||||
*/
|
||||
@ -24,8 +27,8 @@ public class FriendLinkController {
|
||||
* 查询首页友情链接
|
||||
* */
|
||||
@GetMapping("listIndexLink")
|
||||
public ResultBean listIndexLink(){
|
||||
return ResultBean.ok(friendLinkService.listIndexLink());
|
||||
public RestResult<List<FriendLink>> listIndexLink(){
|
||||
return RestResult.ok(friendLinkService.listIndexLink());
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,12 +1,16 @@
|
||||
package com.java2nb.novel.controller;
|
||||
|
||||
import com.github.pagehelper.PageInfo;
|
||||
import com.java2nb.novel.core.bean.ResultBean;
|
||||
import io.github.xxyopen.model.page.PageBean;
|
||||
import com.java2nb.novel.entity.News;
|
||||
import com.java2nb.novel.service.NewsService;
|
||||
import io.github.xxyopen.model.resp.RestResult;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author 11797
|
||||
*/
|
||||
@ -22,16 +26,25 @@ public class NewsController {
|
||||
* 查询首页新闻
|
||||
* */
|
||||
@GetMapping("listIndexNews")
|
||||
public ResultBean listIndexNews(){
|
||||
return ResultBean.ok(newsService.listIndexNews());
|
||||
public RestResult<List<News>> listIndexNews(){
|
||||
return RestResult.ok(newsService.listIndexNews());
|
||||
}
|
||||
|
||||
/**
|
||||
* 分页查询新闻列表
|
||||
* */
|
||||
@GetMapping("listByPage")
|
||||
public ResultBean listByPage(@RequestParam(value = "curr", defaultValue = "1") int page, @RequestParam(value = "limit", defaultValue = "5") int pageSize){
|
||||
return ResultBean.ok(newsService.listByPage(page,pageSize));
|
||||
public RestResult<PageBean<News>> listByPage(@RequestParam(value = "curr", defaultValue = "1") int page, @RequestParam(value = "limit", defaultValue = "5") int pageSize){
|
||||
return RestResult.ok(newsService.listByPage(page,pageSize));
|
||||
}
|
||||
|
||||
/**
|
||||
* 增加新闻阅读量
|
||||
* */
|
||||
@PostMapping("addReadCount")
|
||||
public RestResult<Void> addReadCount(@RequestParam(value = "newsId") Integer newsId){
|
||||
newsService.addReadCount(newsId);
|
||||
return RestResult.ok();
|
||||
}
|
||||
|
||||
|
||||
|
@ -17,8 +17,8 @@ import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.PrintWriter;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
@ -47,7 +47,6 @@ public class PayController extends BaseController {
|
||||
if (userDetails == null) {
|
||||
//未登录,跳转到登陆页面
|
||||
httpResponse.sendRedirect("/user/login.html?originUrl=/pay/aliPay?payAmount="+payAmount);
|
||||
return;
|
||||
}else {
|
||||
//创建充值订单
|
||||
Long outTradeNo = orderService.createPayOrder((byte)1,payAmount,userDetails.getId());
|
||||
@ -92,11 +91,10 @@ public class PayController extends BaseController {
|
||||
PrintWriter out = httpResponse.getWriter();
|
||||
|
||||
//获取支付宝POST过来反馈信息
|
||||
Map<String,String> params = new HashMap<String,String>();
|
||||
Map<String,String> params = new HashMap<>();
|
||||
Map<String,String[]> requestParams = request.getParameterMap();
|
||||
for (Iterator<String> iter = requestParams.keySet().iterator(); iter.hasNext();) {
|
||||
String name = (String) iter.next();
|
||||
String[] values = (String[]) requestParams.get(name);
|
||||
for (String name : requestParams.keySet()) {
|
||||
String[] values = requestParams.get(name);
|
||||
String valueStr = "";
|
||||
for (int i = 0; i < values.length; i++) {
|
||||
valueStr = (i == values.length - 1) ? valueStr + values[i]
|
||||
@ -119,13 +117,13 @@ public class PayController extends BaseController {
|
||||
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);
|
||||
|
@ -1,16 +1,17 @@
|
||||
package com.java2nb.novel.controller;
|
||||
|
||||
import com.java2nb.novel.core.bean.ResultBean;
|
||||
|
||||
import com.java2nb.novel.core.bean.UserDetails;
|
||||
import com.java2nb.novel.core.cache.CacheService;
|
||||
import com.java2nb.novel.core.enums.ResponseStatus;
|
||||
import com.java2nb.novel.core.utils.RandomValidateCodeUtil;
|
||||
import com.java2nb.novel.core.valid.AddGroup;
|
||||
import com.java2nb.novel.core.valid.UpdateGroup;
|
||||
import com.java2nb.novel.entity.User;
|
||||
import com.java2nb.novel.entity.UserBuyRecord;
|
||||
import com.java2nb.novel.service.BookService;
|
||||
import com.java2nb.novel.service.UserService;
|
||||
import io.github.xxyopen.model.resp.RestResult;
|
||||
import io.github.xxyopen.web.valid.AddGroup;
|
||||
import io.github.xxyopen.web.valid.UpdateGroup;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
@ -41,7 +42,7 @@ public class UserController extends BaseController {
|
||||
* 登陆
|
||||
*/
|
||||
@PostMapping("login")
|
||||
public ResultBean login(User user) {
|
||||
public RestResult<Map<String, Object>> login(User user) {
|
||||
|
||||
//登陆
|
||||
UserDetails userDetails = userService.login(user);
|
||||
@ -49,7 +50,7 @@ public class UserController extends BaseController {
|
||||
Map<String, Object> data = new HashMap<>(1);
|
||||
data.put("token", jwtTokenUtil.generateToken(userDetails));
|
||||
|
||||
return ResultBean.ok(data);
|
||||
return RestResult.ok(data);
|
||||
|
||||
|
||||
}
|
||||
@ -58,12 +59,12 @@ public class UserController extends BaseController {
|
||||
* 注册
|
||||
*/
|
||||
@PostMapping("register")
|
||||
public ResultBean register(@Validated({AddGroup.class}) User user, @RequestParam(value = "velCode", defaultValue = "") String velCode) {
|
||||
public RestResult<?> register(@Validated({AddGroup.class}) User user, @RequestParam(value = "velCode", defaultValue = "") String velCode) {
|
||||
|
||||
|
||||
//判断验证码是否正确
|
||||
if (!velCode.equals(cacheService.get(RandomValidateCodeUtil.RANDOM_CODE_KEY))) {
|
||||
return ResultBean.fail(ResponseStatus.VEL_CODE_ERROR);
|
||||
return RestResult.fail(ResponseStatus.VEL_CODE_ERROR);
|
||||
}
|
||||
|
||||
//注册
|
||||
@ -71,7 +72,7 @@ public class UserController extends BaseController {
|
||||
Map<String, Object> data = new HashMap<>(1);
|
||||
data.put("token", jwtTokenUtil.generateToken(userDetails));
|
||||
|
||||
return ResultBean.ok(data);
|
||||
return RestResult.ok(data);
|
||||
|
||||
|
||||
}
|
||||
@ -81,7 +82,7 @@ public class UserController extends BaseController {
|
||||
* 刷新token
|
||||
*/
|
||||
@PostMapping("refreshToken")
|
||||
public ResultBean refreshToken(HttpServletRequest request) {
|
||||
public RestResult<?> refreshToken(HttpServletRequest request) {
|
||||
String token = getToken(request);
|
||||
if (jwtTokenUtil.canRefresh(token)) {
|
||||
token = jwtTokenUtil.refreshToken(token);
|
||||
@ -90,10 +91,10 @@ public class UserController extends BaseController {
|
||||
UserDetails userDetail = jwtTokenUtil.getUserDetailsFromToken(token);
|
||||
data.put("username", userDetail.getUsername());
|
||||
data.put("nickName", userDetail.getNickName());
|
||||
return ResultBean.ok(data);
|
||||
return RestResult.ok(data);
|
||||
|
||||
} else {
|
||||
return ResultBean.fail(ResponseStatus.NO_LOGIN);
|
||||
return RestResult.fail(ResponseStatus.NO_LOGIN);
|
||||
}
|
||||
|
||||
}
|
||||
@ -102,131 +103,131 @@ public class UserController extends BaseController {
|
||||
* 查询小说是否已加入书架
|
||||
*/
|
||||
@GetMapping("queryIsInShelf")
|
||||
public ResultBean queryIsInShelf(Long bookId, HttpServletRequest request) {
|
||||
public RestResult<?> queryIsInShelf(Long bookId, HttpServletRequest request) {
|
||||
UserDetails userDetails = getUserDetails(request);
|
||||
if (userDetails == null) {
|
||||
return ResultBean.fail(ResponseStatus.NO_LOGIN);
|
||||
return RestResult.fail(ResponseStatus.NO_LOGIN);
|
||||
}
|
||||
return ResultBean.ok(userService.queryIsInShelf(userDetails.getId(), bookId));
|
||||
return RestResult.ok(userService.queryIsInShelf(userDetails.getId(), bookId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 加入书架
|
||||
* */
|
||||
@PostMapping("addToBookShelf")
|
||||
public ResultBean addToBookShelf(Long bookId,Long preContentId, HttpServletRequest request) {
|
||||
public RestResult<Void> addToBookShelf(Long bookId,Long preContentId, HttpServletRequest request) {
|
||||
UserDetails userDetails = getUserDetails(request);
|
||||
if (userDetails == null) {
|
||||
return ResultBean.fail(ResponseStatus.NO_LOGIN);
|
||||
return RestResult.fail(ResponseStatus.NO_LOGIN);
|
||||
}
|
||||
userService.addToBookShelf(userDetails.getId(),bookId,preContentId);
|
||||
return ResultBean.ok();
|
||||
return RestResult.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 移出书架
|
||||
* */
|
||||
@DeleteMapping("removeFromBookShelf/{bookId}")
|
||||
public ResultBean removeFromBookShelf(@PathVariable("bookId") Long bookId, HttpServletRequest request) {
|
||||
public RestResult<?> removeFromBookShelf(@PathVariable("bookId") Long bookId, HttpServletRequest request) {
|
||||
UserDetails userDetails = getUserDetails(request);
|
||||
if (userDetails == null) {
|
||||
return ResultBean.fail(ResponseStatus.NO_LOGIN);
|
||||
return RestResult.fail(ResponseStatus.NO_LOGIN);
|
||||
}
|
||||
userService.removeFromBookShelf(userDetails.getId(),bookId);
|
||||
return ResultBean.ok();
|
||||
return RestResult.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 分页查询书架
|
||||
* */
|
||||
@GetMapping("listBookShelfByPage")
|
||||
public ResultBean listBookShelfByPage(@RequestParam(value = "curr", defaultValue = "1") int page, @RequestParam(value = "limit", defaultValue = "10") int pageSize,HttpServletRequest request) {
|
||||
public RestResult<?> listBookShelfByPage(@RequestParam(value = "curr", defaultValue = "1") int page, @RequestParam(value = "limit", defaultValue = "10") int pageSize,HttpServletRequest request) {
|
||||
UserDetails userDetails = getUserDetails(request);
|
||||
if (userDetails == null) {
|
||||
return ResultBean.fail(ResponseStatus.NO_LOGIN);
|
||||
return RestResult.fail(ResponseStatus.NO_LOGIN);
|
||||
}
|
||||
return ResultBean.ok(userService.listBookShelfByPage(userDetails.getId(),page,pageSize));
|
||||
return RestResult.ok(userService.listBookShelfByPage(userDetails.getId(),page,pageSize));
|
||||
}
|
||||
|
||||
/**
|
||||
* 分页查询阅读记录
|
||||
* */
|
||||
@GetMapping("listReadHistoryByPage")
|
||||
public ResultBean listReadHistoryByPage(@RequestParam(value = "curr", defaultValue = "1") int page, @RequestParam(value = "limit", defaultValue = "10") int pageSize,HttpServletRequest request) {
|
||||
public RestResult<?> listReadHistoryByPage(@RequestParam(value = "curr", defaultValue = "1") int page, @RequestParam(value = "limit", defaultValue = "10") int pageSize,HttpServletRequest request) {
|
||||
UserDetails userDetails = getUserDetails(request);
|
||||
if (userDetails == null) {
|
||||
return ResultBean.fail(ResponseStatus.NO_LOGIN);
|
||||
return RestResult.fail(ResponseStatus.NO_LOGIN);
|
||||
}
|
||||
return ResultBean.ok(userService.listReadHistoryByPage(userDetails.getId(),page,pageSize));
|
||||
return RestResult.ok(userService.listReadHistoryByPage(userDetails.getId(),page,pageSize));
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加阅读记录
|
||||
* */
|
||||
@PostMapping("addReadHistory")
|
||||
public ResultBean addReadHistory(Long bookId,Long preContentId, HttpServletRequest request) {
|
||||
public RestResult<?> addReadHistory(Long bookId,Long preContentId, HttpServletRequest request) {
|
||||
UserDetails userDetails = getUserDetails(request);
|
||||
if (userDetails == null) {
|
||||
return ResultBean.fail(ResponseStatus.NO_LOGIN);
|
||||
return RestResult.fail(ResponseStatus.NO_LOGIN);
|
||||
}
|
||||
userService.addReadHistory(userDetails.getId(),bookId,preContentId);
|
||||
return ResultBean.ok();
|
||||
return RestResult.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加反馈
|
||||
* */
|
||||
@PostMapping("addFeedBack")
|
||||
public ResultBean addFeedBack(String content, HttpServletRequest request) {
|
||||
public RestResult<?> addFeedBack(String content, HttpServletRequest request) {
|
||||
UserDetails userDetails = getUserDetails(request);
|
||||
if (userDetails == null) {
|
||||
return ResultBean.fail(ResponseStatus.NO_LOGIN);
|
||||
return RestResult.fail(ResponseStatus.NO_LOGIN);
|
||||
}
|
||||
userService.addFeedBack(userDetails.getId(),content);
|
||||
return ResultBean.ok();
|
||||
return RestResult.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 分页查询我的反馈列表
|
||||
* */
|
||||
@GetMapping("listUserFeedBackByPage")
|
||||
public ResultBean listUserFeedBackByPage(@RequestParam(value = "curr", defaultValue = "1") int page, @RequestParam(value = "limit", defaultValue = "5") int pageSize, HttpServletRequest request){
|
||||
public RestResult<?> listUserFeedBackByPage(@RequestParam(value = "curr", defaultValue = "1") int page, @RequestParam(value = "limit", defaultValue = "5") int pageSize, HttpServletRequest request){
|
||||
UserDetails userDetails = getUserDetails(request);
|
||||
if (userDetails == null) {
|
||||
return ResultBean.fail(ResponseStatus.NO_LOGIN);
|
||||
return RestResult.fail(ResponseStatus.NO_LOGIN);
|
||||
}
|
||||
return ResultBean.ok(userService.listUserFeedBackByPage(userDetails.getId(),page,pageSize));
|
||||
return RestResult.ok(userService.listUserFeedBackByPage(userDetails.getId(),page,pageSize));
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询个人信息
|
||||
* */
|
||||
@GetMapping("userInfo")
|
||||
public ResultBean userInfo(HttpServletRequest request) {
|
||||
public RestResult<?> userInfo(HttpServletRequest request) {
|
||||
UserDetails userDetails = getUserDetails(request);
|
||||
if (userDetails == null) {
|
||||
return ResultBean.fail(ResponseStatus.NO_LOGIN);
|
||||
return RestResult.fail(ResponseStatus.NO_LOGIN);
|
||||
}
|
||||
return ResultBean.ok(userService.userInfo(userDetails.getId()));
|
||||
return RestResult.ok(userService.userInfo(userDetails.getId()));
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新个人信息
|
||||
* */
|
||||
@PostMapping("updateUserInfo")
|
||||
public ResultBean updateUserInfo(@Validated({UpdateGroup.class}) User user, HttpServletRequest request) {
|
||||
public RestResult<?> updateUserInfo(@Validated({UpdateGroup.class}) User user, HttpServletRequest request) {
|
||||
UserDetails userDetails = getUserDetails(request);
|
||||
if (userDetails == null) {
|
||||
return ResultBean.fail(ResponseStatus.NO_LOGIN);
|
||||
return RestResult.fail(ResponseStatus.NO_LOGIN);
|
||||
}
|
||||
userService.updateUserInfo(userDetails.getId(),user);
|
||||
if(user.getNickName() != null){
|
||||
userDetails.setNickName(user.getNickName());
|
||||
Map<String, Object> data = new HashMap<>(1);
|
||||
data.put("token", jwtTokenUtil.generateToken(userDetails));
|
||||
return ResultBean.ok(data);
|
||||
return RestResult.ok(data);
|
||||
}
|
||||
return ResultBean.ok();
|
||||
return RestResult.ok();
|
||||
}
|
||||
|
||||
|
||||
@ -234,28 +235,28 @@ public class UserController extends BaseController {
|
||||
* 更新密码
|
||||
* */
|
||||
@PostMapping("updatePassword")
|
||||
public ResultBean updatePassword(String oldPassword,String newPassword1,String newPassword2,HttpServletRequest request) {
|
||||
public RestResult<?> updatePassword(String oldPassword,String newPassword1,String newPassword2,HttpServletRequest request) {
|
||||
UserDetails userDetails = getUserDetails(request);
|
||||
if (userDetails == null) {
|
||||
return ResultBean.fail(ResponseStatus.NO_LOGIN);
|
||||
return RestResult.fail(ResponseStatus.NO_LOGIN);
|
||||
}
|
||||
if(!(StringUtils.isNotBlank(newPassword1) && newPassword1.equals(newPassword2))){
|
||||
ResultBean.fail(ResponseStatus.TWO_PASSWORD_DIFF);
|
||||
RestResult.fail(ResponseStatus.TWO_PASSWORD_DIFF);
|
||||
}
|
||||
userService.updatePassword(userDetails.getId(),oldPassword,newPassword1);
|
||||
return ResultBean.ok();
|
||||
return RestResult.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 分页查询用户书评
|
||||
* */
|
||||
@GetMapping("listCommentByPage")
|
||||
public ResultBean listCommentByPage(@RequestParam(value = "curr", defaultValue = "1") int page, @RequestParam(value = "limit", defaultValue = "5") int pageSize,HttpServletRequest request) {
|
||||
public RestResult<?> listCommentByPage(@RequestParam(value = "curr", defaultValue = "1") int page, @RequestParam(value = "limit", defaultValue = "5") int pageSize,HttpServletRequest request) {
|
||||
UserDetails userDetails = getUserDetails(request);
|
||||
if (userDetails == null) {
|
||||
return ResultBean.fail(ResponseStatus.NO_LOGIN);
|
||||
return RestResult.fail(ResponseStatus.NO_LOGIN);
|
||||
}
|
||||
return ResultBean.ok(bookService.listCommentByPage(userDetails.getId(),null,page,pageSize));
|
||||
return RestResult.ok(bookService.listCommentByPage(userDetails.getId(),null,page,pageSize));
|
||||
}
|
||||
|
||||
|
||||
@ -263,14 +264,14 @@ public class UserController extends BaseController {
|
||||
* 购买小说章节
|
||||
* */
|
||||
@PostMapping("buyBookIndex")
|
||||
public ResultBean buyBookIndex(UserBuyRecord buyRecord, HttpServletRequest request) {
|
||||
public RestResult<?> buyBookIndex(UserBuyRecord buyRecord, HttpServletRequest request) {
|
||||
UserDetails userDetails = getUserDetails(request);
|
||||
if (userDetails == null) {
|
||||
return ResultBean.fail(ResponseStatus.NO_LOGIN);
|
||||
return RestResult.fail(ResponseStatus.NO_LOGIN);
|
||||
}
|
||||
buyRecord.setBuyAmount(bookService.queryBookIndex(buyRecord.getBookIndexId()).getBookPrice());
|
||||
userService.buyBookIndex(userDetails.getId(),buyRecord);
|
||||
return ResultBean.ok();
|
||||
return RestResult.ok();
|
||||
}
|
||||
|
||||
|
||||
|
@ -30,7 +30,7 @@ public class EsConfig {
|
||||
String uri = uris[i];
|
||||
String scheme = uri.substring(0,uri.indexOf(":")).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);
|
||||
}
|
||||
|
||||
|
@ -32,7 +32,7 @@ public class FilterConfig{
|
||||
private String urlPatterns;
|
||||
|
||||
@Bean
|
||||
public FilterRegistrationBean<NovelFilter> filterRegist() {
|
||||
public FilterRegistrationBean<NovelFilter> filterRegister() {
|
||||
FilterRegistrationBean<NovelFilter> frBean = new FilterRegistrationBean<>();
|
||||
frBean.setFilter(new NovelFilter());
|
||||
frBean.addUrlPatterns("/*");
|
||||
@ -41,9 +41,9 @@ public class FilterConfig{
|
||||
}
|
||||
|
||||
@Bean
|
||||
public FilterRegistrationBean xssFilterRegistration()
|
||||
public FilterRegistrationBean<XssFilter> xssFilterRegistration()
|
||||
{
|
||||
FilterRegistrationBean registration = new FilterRegistrationBean();
|
||||
FilterRegistrationBean<XssFilter> registration = new FilterRegistrationBean<>();
|
||||
//
|
||||
registration.setDispatcherTypes(DispatcherType.REQUEST);
|
||||
//过滤器类(继承Filter)
|
||||
|
@ -3,6 +3,8 @@ package com.java2nb.novel.core.filter;
|
||||
import com.java2nb.novel.core.cache.CacheKey;
|
||||
import com.java2nb.novel.core.cache.CacheService;
|
||||
import com.java2nb.novel.core.utils.*;
|
||||
import io.github.xxyopen.util.UUIDUtil;
|
||||
import io.github.xxyopen.web.util.SpringUtil;
|
||||
|
||||
import javax.servlet.*;
|
||||
import javax.servlet.http.Cookie;
|
||||
@ -38,7 +40,7 @@ public class NovelFilter implements Filter {
|
||||
//缓存10天
|
||||
resp.setDateHeader("expires", System.currentTimeMillis()+60*60*24*10*1000);
|
||||
OutputStream out = resp.getOutputStream();
|
||||
InputStream input = new FileInputStream(new File(picSavePath + requestUri));
|
||||
InputStream input = new FileInputStream(picSavePath + requestUri);
|
||||
byte[] b = new byte[4096];
|
||||
for (int n; (n = input.read(b)) != -1; ) {
|
||||
out.write(b, 0, n);
|
||||
@ -55,7 +57,7 @@ public class NovelFilter implements Filter {
|
||||
userMark = UUIDUtil.getUUID32();
|
||||
CookieUtil.setCookie(resp,Constants.USER_CLIENT_MARK_KEY,userMark);
|
||||
}
|
||||
ThreadLocalUtil.setCientId(userMark);
|
||||
ThreadLocalUtil.setClientId(userMark);
|
||||
//根据浏览器类型选择前端模板
|
||||
String to = req.getParameter("to");
|
||||
CacheService cacheService = SpringUtil.getBean(CacheService.class);
|
||||
|
@ -6,8 +6,8 @@ import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import javax.servlet.*;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
@ -34,12 +34,10 @@ public class XssFilter implements Filter {
|
||||
String tempEnabled = filterConfig.getInitParameter("enabled");
|
||||
if (StringUtils.isNotBlank(tempExcludes)) {
|
||||
String[] url = tempExcludes.split(",");
|
||||
for (int i = 0; url != null && i < url.length; i++) {
|
||||
excludes.add(url[i]);
|
||||
}
|
||||
excludes.addAll(Arrays.asList(url));
|
||||
}
|
||||
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)
|
||||
{
|
||||
HttpServletRequest req = (HttpServletRequest) request;
|
||||
HttpServletResponse resp = (HttpServletResponse) response;
|
||||
if (handleExcludeURL(req, resp)) {
|
||||
if (handleExcludeURL(req)) {
|
||||
chain.doFilter(request, response);
|
||||
return;
|
||||
}
|
||||
@ -57,7 +54,7 @@ public class XssFilter implements Filter {
|
||||
chain.doFilter(xssRequest, response);
|
||||
}
|
||||
|
||||
private boolean handleExcludeURL(HttpServletRequest request, HttpServletResponse response) {
|
||||
private boolean handleExcludeURL(HttpServletRequest request) {
|
||||
if (!enabled) {
|
||||
return true;
|
||||
}
|
||||
|
@ -58,8 +58,8 @@ public class MonthIncomeStaSchedule {
|
||||
//2.查询作家作品
|
||||
List<Book> books = bookService.queryBookList(authorId);
|
||||
|
||||
Long totalPreTaxIncome = 0L;
|
||||
Long totalAfterTaxIncome = 0L;
|
||||
long totalPreTaxIncome = 0L;
|
||||
long totalAfterTaxIncome = 0L;
|
||||
for (Book book : books) {
|
||||
|
||||
Long bookId = book.getId();
|
||||
@ -70,14 +70,14 @@ public class MonthIncomeStaSchedule {
|
||||
|
||||
BigDecimal monthIncomeShare = new BigDecimal(monthIncome)
|
||||
.multiply(authorIncomeConfig.getShareProportion());
|
||||
Long preTaxIncome = monthIncomeShare
|
||||
long preTaxIncome = monthIncomeShare
|
||||
.multiply(authorIncomeConfig.getExchangeProportion())
|
||||
.multiply(new BigDecimal(100))
|
||||
.longValue();
|
||||
|
||||
totalPreTaxIncome += preTaxIncome;
|
||||
|
||||
Long afterTaxIncome = monthIncomeShare
|
||||
long afterTaxIncome = monthIncomeShare
|
||||
.multiply(authorIncomeConfig.getTaxRate())
|
||||
.multiply(authorIncomeConfig.getExchangeProportion())
|
||||
.multiply(new BigDecimal(100))
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -29,7 +29,7 @@ public class Constants {
|
||||
/**
|
||||
* 首页设置的小说数量
|
||||
* */
|
||||
public static final int INDEX_BOOK_SETTING_NUM = 32;
|
||||
public static final int INDEX_BOOK_SETTING_NUM = 31;
|
||||
|
||||
/**
|
||||
* 累积的最大点击量
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user