Compare commits

...

102 Commits

Author SHA1 Message Date
bb2d95ad75 Merge pull request #71 from a100488/task_updateCrawlSource
feat(新增编辑规则测试规则): 新增编辑规则测试规则
2021-12-24 15:46:00 +08:00
e6b60bb0a8 feat(新增编辑规则测试规则): 新增编辑规则测试规则2 2021-12-24 15:41:32 +08:00
3a44d14149 feat(新增编辑规则测试规则): 新增编辑规则测试规则 2021-12-24 13:41:25 +08:00
fecf03b3f5 fix: 升级mybatis版本,增加Optional支持 2021-12-24 11:35:59 +08:00
e7f702ece0 docs: 微信群说明 2021-12-23 10:27:05 +08:00
b2c67c4f15 build: 修改打包配置 2021-12-17 19:53:21 +08:00
6a385877ac Merge pull request #69 from a100488/feature/saw_fenbao
feat(打包改为分包): 打包改为分包
2021-12-17 16:45:13 +08:00
7cde6ebf61 feat(打包改为分包): 打包改为分包 2021-12-17 16:33:45 +08:00
78969f9fd1 fix: 修复单本小说采集即使没有采集到内容仍然标记状态为采集成功的问题 2021-12-17 10:20:59 +08:00
b2eb6686e9 build: 更新xxyopen依赖版本 2021-12-12 20:44:09 +08:00
c537f6fb20 docs: maven仓库配置说明 2021-12-11 20:56:11 +08:00
16e4c98a45 refactor: 引入xxy-common相关依赖 2021-12-11 18:30:22 +08:00
776083076c update 2021-11-11 14:28:05 +08:00
2bf945fe0e 样式调整 2021-11-08 19:55:03 +08:00
ede7aca66d 作家作品列表分页修复 2021-09-27 22:35:48 +08:00
396452b46e 3.6.1发布 2021-09-13 22:24:08 +08:00
fc2ea40c6a 实现小说内容多种存储方式(txt、db..)并存 2021-09-13 22:21:50 +08:00
bfe4d938fd 去除重复依赖 2021-09-11 22:07:14 +08:00
7f4728191a 修改配置项命名 2021-09-04 16:27:02 +08:00
80b393fdda v3.6.0发布 2021-08-17 21:14:15 +08:00
e7897c988a 更新文档 2021-08-17 20:00:53 +08:00
750c8dee02 增加小说内容TXT文本存储方案(一行配置切换) 2021-08-17 19:55:24 +08:00
cbfd0b049f 爬虫部分代码重构,准备适配TXT文本存储方案 2021-08-17 11:08:51 +08:00
7f0331e095 解决爬虫运行时的UnrecognizedPropertyException 2021-08-16 15:58:32 +08:00
3520200a87 部分代码重构 2021-08-16 15:42:56 +08:00
4939bcf418 模版更新 2021-08-09 19:46:32 +08:00
1cffbae495 增加新闻阅读数 2021-07-26 19:06:57 +08:00
b99b6ae4f2 新闻详情时间显示 2021-07-24 17:52:25 +08:00
2e2a58c84b Merge pull request #41 from 201206030/dependabot/maven/novel-admin/org.apache.shiro-shiro-spring-1.7.0
Bump shiro-spring from 1.3.2 to 1.7.0 in /novel-admin
2021-07-24 16:54:19 +08:00
4fe36a8f4f 部分爬虫代码优化 2021-07-24 15:51:54 +08:00
b5df86d5c7 perf(index.html): orange模版更新 2021-07-03 12:00:17 +08:00
9b3ba1d8c1 perf(index): 首页优化 2021-07-03 11:51:47 +08:00
c4db754d23 docs(readme): 更新官网地址 2021-06-10 09:42:07 +08:00
8d3ce53dba build(pom): v3.5.4发布 2021-06-01 23:14:35 +08:00
d32d9d8410 perf(html): 模版更新 2021-06-01 23:13:18 +08:00
05ae012e05 fix(yml): Public Key Retrieval is not allowed 2021-06-01 23:03:15 +08:00
b60a0c9b40 perf(监控): 设置druid监控信息登陆后查看 2021-06-01 22:49:23 +08:00
3efaf8ce5f perf(评论): 优化评论显示 2021-06-01 22:01:05 +08:00
ebc4210774 fix(章节更新): xss 2021-06-01 21:44:18 +08:00
655ec90906 fix(data submit): Xss攻击 2021-06-01 20:58:06 +08:00
f28dd867ef v3.5.3发布 2021-05-28 20:32:08 +08:00
8e6842a495 模版更新 2021-05-28 20:08:45 +08:00
928cb2417f 小说详情页优化 2021-05-28 20:04:52 +08:00
625694ba1e Merge branch 'release_3.5.3' into develop_xxy 2021-05-28 11:54:24 +08:00
d6c0337c09 首页SEO优化 2021-05-28 11:51:11 +08:00
689efc0807 style(novel-common/bean): ResultBean更新
代码格式化,去除多余分号
2021-05-16 10:54:25 +08:00
4540c3781e 模版更新 2021-05-16 09:49:35 +08:00
9d2c453bb0 图片上传流程优化 2021-05-16 09:47:23 +08:00
xxy
9de47ce697 update README.md. 2021-04-25 07:39:56 +08:00
c79974ff77 3.5.2发布 2021-04-24 10:46:59 +08:00
fb0098aef8 作家后台新增作品封片图片修改功能 2021-04-24 10:38:55 +08:00
e83494cb17 Bump shiro-spring from 1.3.2 to 1.7.0 in /novel-admin
Bumps shiro-spring from 1.3.2 to 1.7.0.

Signed-off-by: dependabot[bot] <support@github.com>
2021-04-22 17:07:42 +00:00
419d7a971b 优化首页显示(修改周推小说数量) 2021-02-11 18:03:27 +08:00
83eda2a44d 模版更新 2021-02-11 12:25:04 +08:00
3182029bdd 文件压缩 2021-02-11 10:26:48 +08:00
19d4a9960d 使用图片懒加载优化首页加载速度 2021-02-11 09:36:03 +08:00
2603150b33 作家专区的跳转方式改为新标签页跳转 2021-02-11 08:31:27 +08:00
f5e440390b 修改404页面自动跳转首页的时间 2021-02-11 08:27:11 +08:00
91e525ec8e v3.5.1发布 2021-02-05 00:39:25 +08:00
83afb9e6e2 新增内置爬虫源i笔趣阁 2021-02-05 00:17:19 +08:00
19d4c6b778 修复部分分页接口的查询bug 2021-02-04 23:59:26 +08:00
d22200b8c7 文档update 2021-01-28 09:00:36 +08:00
43fe1150fd 文档update 2021-01-28 08:58:20 +08:00
65b65f874f 文档update 2021-01-28 08:46:56 +08:00
3b6bc859a5 文档update 2021-01-28 08:35:08 +08:00
cfc55a6c92 update 2021-01-28 08:33:05 +08:00
0a80c5662d update 2021-01-28 08:28:03 +08:00
02fd0d7e25 模版更新 2021-01-25 18:10:47 +08:00
521142a792 v3.5.1发布 2021-01-25 16:56:41 +08:00
c567e37423 v3.5.1发布 2021-01-25 14:56:05 +08:00
b5e0814eb4 小说内容页性能优化 2021-01-25 14:14:54 +08:00
ca6c2aec96 update 2021-01-24 14:07:14 +08:00
34859c839b update 2021-01-22 10:18:25 +08:00
039f9d9cf8 update 2021-01-21 21:03:08 +08:00
224829dd1f v3.5.0发布 2021-01-19 19:39:33 +08:00
1a5122209a 个人中心新增头像设置 2021-01-19 19:34:14 +08:00
48aff7cf37 个人中心新增头像设置 2021-01-19 19:32:32 +08:00
e673f9be9d 新增启动banner 2021-01-19 19:00:54 +08:00
20469bd669 增加生产环境配置 2021-01-19 18:53:47 +08:00
755300db3c update 2021-01-14 23:26:38 +08:00
a790f8042d update 2021-01-14 23:22:03 +08:00
d0db2021a6 v3.4.1发布 2021-01-10 17:55:48 +08:00
c403fc7496 更新orange主题手机端首尾章节跳转逻辑 2021-01-07 20:59:19 +08:00
e4927d7ac6 爬虫管理系统设置session默认超时时间为1天,解决由于编写爬虫规则时间过长导致的提交失败问题 2021-01-05 21:46:01 +08:00
a00a2141f2 爬虫管理系统设置session默认超时时间为1天,解决由于编写爬虫规则时间过长导致的提交失败问题 2021-01-05 21:45:04 +08:00
7cc7d8b541 v3.4.0发布 2021-01-04 10:28:01 +08:00
e4822979e2 elasticsearch升级到7.x,集成RestHighLevelClient客户端 2021-01-03 13:42:40 +08:00
ab741ec6bf v3.3.0发布 2020-12-28 12:06:19 +08:00
057c0646cd v3.3.0发布 2020-12-28 12:02:34 +08:00
57a9cd09ef v3.3.0发布 2020-12-28 11:06:27 +08:00
1a49e2a340 增加外部配置文件来配置网站信息 2020-12-28 10:58:38 +08:00
f8411c2337 v3.3.0发布 2020-12-28 09:34:22 +08:00
343a741c21 更新展示图片 2020-12-27 15:54:50 +08:00
f1a5fb4813 更新展示图片 2020-12-27 15:34:23 +08:00
0428356bd4 新增蓝色主题模版 2020-12-27 09:43:45 +08:00
c01097cd5f 更新v3.3.0的安装文档 2020-12-26 23:53:05 +08:00
7e650a0a04 修改版本号 2020-12-26 22:27:51 +08:00
45c59ecc37 前端新增深色主题模版 2020-12-26 22:16:58 +08:00
5e3962fef4 update 2020-12-26 20:10:11 +08:00
7f5035e369 update 2020-12-26 20:08:07 +08:00
44aad39847 update 2020-12-26 20:00:21 +08:00
6ad51908d5 文件夹结构调整,新增模版自定义功能 2020-12-26 19:13:07 +08:00
1333 changed files with 113532 additions and 13089 deletions

1
.gitignore vendored
View File

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

137
README.md
View File

@ -2,9 +2,14 @@
# 小说精品屋-plus
[![Github stars](https://img.shields.io/github/stars/201206030/novel-plus?logo=github)](https://github.com/201206030/novel-plus)
[![Github forks](https://img.shields.io/github/forks/201206030/novel-plus?logo=github)](https://github.com/201206030/novel-plus)
[![Gitee star](https://gitee.com/novel_dev_team/novel-plus/badge/star.svg?theme=gitee)](https://gitee.com/novel_dev_team/novel-plus)
[![Gitee fork](https://gitee.com/novel_dev_team/novel-plus/badge/fork.svg?theme=gitee)](https://gitee.com/novel_dev_team/novel-plus)
#### 官网
https://xiongxyang.gitee.io/home/
https://201206030.github.io
#### 新项目小说精品屋-微服务版
@ -29,6 +34,7 @@ Gitee仓库地址 https://gitee.com/novel_dev_team/novel-cloud
- [x] 服务端代码重构MyBatis3升级为MyBatis3DynamicSql
- [x] 移动站与PC站站点分离浏览器自动识别跳转
- [x] PC站UI更新
- [x] 支持前端模版自定义内置多套模版
- [x] 新闻模块
- [x] 排行榜
- [x] 小说评论模块
@ -46,7 +52,8 @@ novel-plus -- 父工程
novel-common -- 通用模块
novel-front -- 前台门户&作家后台管理子系统可拆分
novel-crawl -- 爬虫管理子系统
novel-admin -- 平台后台管理子系统
novel-admin -- 平台后台管理子系统
templates -- 前端模版
```
#### 技术选型
@ -76,15 +83,22 @@ novel-plus -- 父工程
| Layui | 前端UI
#### 开发工具
感谢Jetbrains公司提供的免费License
[![index]( https://s3.ax1x.com/2021/01/14/sdHsJg.png )]( https://www.jetbrains.com/?from=小说精品屋)
#### 接口文档
[点击查看接口文档示例](./doc/api.md)
[点击查看接口文档示例](doc/api/api.md)
#### PC站截图
#### 橙色主题模版截图
##### PC站截图
1. 首页
![img](https://oscimg.oschina.net/oscnet/up-bbb1c7f72e183327bff754a9fa8bb75223e.png)
![img](https://s3.ax1x.com/2020/12/27/r5400A.png)
2. 分类索引页
@ -92,7 +106,7 @@ novel-plus -- 父工程
3. 搜索页
![img](https://gitee.com/xiongxyang/novel-plus/raw/release_v2.1.0/assets/QQ20200520-215756.png)
![img](https://s3.ax1x.com/2020/12/27/r5TO8x.png)
![img](https://oscimg.oschina.net/oscnet/up-ed5f689557718924acac76bc3ebca36afcb.png)
@ -134,31 +148,31 @@ novel-plus -- 父工程
![img](https://oscimg.oschina.net/oscnet/up-f849960f4c1303fea77d26e64fc505a7180.png)
#### 手机站截图
##### 手机站截图
1. 首页
<img src="https://s3.ax1x.com/2020/12/04/DbsSoj.jpg" alt="index" style="zoom:33%;" />
<img src="https://s3.ax1x.com/2020/12/27/r5447n.jpg" alt="index" width="300" />
2. 小说列表页
<img src="https://s3.ax1x.com/2020/12/04/DbrfsO.jpg" alt="微信图片_20190904181558" style="zoom: 33%;" />
<img src="https://s3.ax1x.com/2020/12/27/r55xKg.jpg" alt="微信图片_20190904181558" width="300" />
3. 小说详情页
<img src="https://s3.ax1x.com/2020/12/04/DbsklV.jpg" alt="QQ图片20191018161901" style="zoom:33%;" />
<img src="https://s3.ax1x.com/2020/12/28/roZWOf.jpg" alt="QQ图片20191018161901" width="300" />
4. 小说阅读页
<img src="https://s3.ax1x.com/2020/12/04/Dbsew4.jpg" alt="QQ图片20191018161901" style="zoom:33%;" />
<img src="https://s3.ax1x.com/2020/12/27/r55Stx.jpg" alt="QQ图片20191018161901" width="300" />
#### 爬虫管理系统截图
##### 爬虫管理系统截图
![img](https://s1.ax1x.com/2020/11/03/BsOgbD.png)
![img](https://s1.ax1x.com/2020/11/03/BsOHr8.png)
#### 后台管理系统截图
##### 后台管理系统截图
![img](https://oscimg.oschina.net/oscnet/up-0552343538674a22a64819834100558f39b.png)
@ -168,30 +182,97 @@ novel-plus -- 父工程
![img](https://oscimg.oschina.net/oscnet/up-faf5dda7320674c29a1772bc0c81d74762e.png)
#### 安装步骤
#### 深色主题模版截图
##### PC站截图
1. 首页
![index](https://static.oschina.net/uploads/img/202006/24151811_wIus.png)
##### 手机站截图
1. 首页
![index](https://static.oschina.net/uploads/img/202006/24151812_OOob.jpg)
4. 小说详情页
![微信图片_20190904181558](https://static.oschina.net/uploads/img/202006/24151812_ZosF.png)
5. 目录页
![QQ图片20191018161901](https://static.oschina.net/uploads/img/202006/24151812_Krva.png)
5. 小说阅读页
![QQ图片20191018161901](https://static.oschina.net/uploads/img/202006/24151813_fDgT.png)
#### 蓝色主题模版截图更新中
![QQ图片20191018161901](https://s3.ax1x.com/2020/12/27/r5Fe0A.png)
#### 安装步骤源码小白请看其他安装教程
##### 数据库安装
1. 安装MySQL软件
2. 修改MySQL`max_allowed_packet `配置建议100M
3. 新建数据库设置编码为utf8mb4
4. 执行sql/novel_plus.sql脚本文件
4. 执行doc/sql/novel_plus.sql脚本文件
##### 爬虫管理系统安装
1. 修改novel-common模块下application-dev.yml文件中的数据库配置
1. 修改novel-common模块下application-common-dev.ymldev环境默认环境或application-common-prod.ymlprod环境需要在application.yml配置文件中切换配置文件中的数据库配置
2. 修改novel-crawl模块下application.yml文件中的管理员账号密码
3. 启动程序打开浏览器默认8081端口访问
4. 选择已有或新增爬虫源支持自定义爬虫规则点击`开启`按钮开始爬取小说数据
##### 前台小说门户安装
##### 前台小说门户安装dev环境跳过34步骤
1. 修改novel-common模块下application-dev.yml文件中的数据库配置
2. 启动程序打开浏览器默认8080端口访问
1. 修改novel-common模块下application-common-dev.ymldev环境默认环境或application-common-prod.ymlprod环境需要在application.yml配置文件中切换配置文件中的数据库配置
2. 修改novel-front模块下application-website配置文件中的网站信息
```
#网站配置
website:
#网站名
name: 小说精品屋
#域名
domain: xiongxyang.gitee.io
#SEO关键词
keyword: ${website.name},小说,小说CMS,原创文学系统,开源小说系统,免费小说建站程序
#SEO描述
description: ${website.name}是一个多端PCWAP阅读功能完善的原创文学CMS系统由前台门户系统作家后台管理系统平台后台管理系统爬虫管理系统等多个子系统构成支持会员充值订阅模式新闻发布和实时统计报表等功能新书自动入库老书自动更新
#联系QQ
qq: 1179705413
```
3. prod环境下需要修改novel-front模块下application-prod.yml配置文件中的模版名为你需要使用的模版名templates文件夹下的模版文件夹名内置orange和dark两套模版prod环境下才支持多模版
```
#模版配置
templates:
#模版名
name: orange
```
4. prod环境下的jar包形式部署时需要复制templates文件夹到jar文件的相同目录下
5. 启动程序打开浏览器默认8080端口访问
**喜欢此项目的可以给我的GitHub和Gitee加个Star支持一下 **
#### 其他安装教程
#### 其他安装教程如果链接打不开可关注公众号获取
##### 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)
@ -207,9 +288,17 @@ docker安装教程[点击前往](https://my.oschina.net/java2nb/blog/4271989)
#### QQ交流群
[点击前往官网查看](https://xiongxyang.gitee.io/home/service.htm)
[点击前往官网查看](https://xiongxyang.gitee.io/service.htm)
#### 微信公众号发布最新更新资讯
问问题的三要素
1. 说明背景使用了哪个模块要做什么
2. 怎么输入或操作的得到了什么结果 截图日志
3. 哪里不明白或有什么疑问
#### 微信公众号发布最新更新资讯最新前端模版最新爬虫规则技术文档等
![mini-code](https://s3.ax1x.com/2020/12/03/DoImOx.png)
@ -223,12 +312,12 @@ docker安装教程[点击前往](https://my.oschina.net/java2nb/blog/4271989)
![mini-code](https://s1.ax1x.com/2020/10/31/BUQJwq.png)
### 免责声明
#### 免责声明
本项目提供的爬虫工具仅用于采集项目初期的测试数据请勿用于商业盈利
用户使用本系统从事任何违法违规的事情一切后果由用户自行承担作者不承担任何责任
### 备注
#### 备注
精品小说屋所有相关项目均已在开源中国公开感兴趣的可进入[开源中国](https://www.oschina.net/p/fiction_house)按关键字`精品小说屋`搜索。

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

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

View File

@ -1837,3 +1837,7 @@ INSERT INTO `sys_role_menu`(`id`, `role_id`, `menu_id`) VALUES (4888, 1, 234);
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;

View File

@ -5,7 +5,7 @@
<groupId>com.java2nb</groupId>
<artifactId>novel-admin</artifactId>
<version>3.2.0</version>
<version>3.5.4</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,17 +224,17 @@
<!--<scope>provided</scope>-->
<!--</dependency>-->
</dependencies>
<build>
<!-- <build>
<plugins>
<!--<plugin>
&lt;!&ndash;<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>
</plugin>&ndash;&gt;
&lt;!&ndash;SpringBoot项目默认使用spring-boot-maven-plugin要打成被其他项目引用的jar包需要更换此插件&ndash;&gt;
&lt;!&ndash; <plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
@ -242,12 +242,91 @@
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>-->
</plugin>&ndash;&gt;
<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>
<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>
</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>
</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>
<!--<distributionManagement>
<repository>

View File

@ -0,0 +1,8 @@
1linux启动环境
sh start.sh
3windows启动环境
windows-start.bat
3linux停止应用
sh stop.sh

View File

@ -0,0 +1,47 @@
#!/bin/bash
ENGINE=novel-admin.jar
cd ../
#部署目路
DEPLOY_DIR=`pwd`
#获取到当前目录的名称
SERVER_NAME=`basename $DEPLOY_DIR`
#应用进程
PIDS=`ps -ef | grep java | grep "$ENGINE" |awk '{print $2}'`
#设置日志文件的输出目录
LOGS_DIR=$DEPLOY_DIR/logs
if [ ! -d $LOGS_DIR ]; then
mkdir $LOGS_DIR
fi
#日志
STDOUT_FILE=$LOGS_DIR/stdout.log
#JAVA 环境配置
JAVA_OPTS=" -Djava.net.preferIPv4Stack=true -Dlog.home=$LOGS_DIR"
JAVA_MEM_OPTS=" -server -Xms1024m -Xmx1024m -XX:MetaspaceSize=64m -XX:MaxMetaspaceSize=256m -XX:+UseG1GC -XX:MaxGCPauseMillis=100 -XX:InitiatingHeapOccupancyPercent=50 -XX:+PrintGCApplicationStoppedTime -XX:+PrintGCApplicationConcurrentTime -XX:+PrintGCDateStamps -verbose:gc -XX:+PrintGCDetails -XX:+PrintHeapAtGC -Xloggc:$LOGS_DIR/gc.log -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=10 -XX:GCLogFileSize=100M -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=dump.hprof "
#退出标志
RETVAL="0"
if [ -n "$PIDS" ]; then
echo "ERROR: The $SERVER_NAME already started!"
echo "PID: $PIDS"
exit $RETVAL
fi
nohup java -jar $JAVA_OPTS $JAVA_MEM_OPTS -Dloader.path=conf,lib $ENGINE > $STDOUT_FILE 2>&1 &
COUNT=0
while [ $COUNT -lt 1 ]; do
echo -e ".\c"
sleep 1
COUNT=`ps -f | grep java | grep "$DEPLOY_DIR" | awk '{print $2}' | wc -l`
if [ $COUNT -gt 0 ]; then
break
fi
done
echo "OK!"
PIDS=`ps -f | grep java | grep "$DEPLOY_DIR" | awk '{print $2}'`
echo "PID: $PIDS"
echo "STDOUT: $STDOUT_FILE"

View File

@ -0,0 +1,33 @@
#!/bin/bash
SERVER_NAME=novel-admin.jar
#应用进程
PIDS=`ps -ef | grep java | grep "$SERVER_NAME" |awk '{print $2}'`
if [ -z "$PIDS" ]; then
echo "ERROR: The $SERVER_NAME does not started!"
exit 1
fi
echo -e "Stopping the $SERVER_NAME ...\c"
for PID in $PIDS ; do
kill $PID > /dev/null 2>&1
done
COUNT=0
while [ $COUNT -lt 1 ]; do
echo -e ".\c"
sleep 1
COUNT=1
for PID in $PIDS ; do
PID_EXIST=`ps -f -p $PID | grep java`
if [ -n "$PID_EXIST" ]; then
COUNT=0
break
fi
done
done
echo "OK!"
echo "PID: $PIDS"
PIDS=""

View File

@ -0,0 +1,10 @@
@echo off
setlocal enabledelayedexpansion
set JAVA=java
set OPTS=-XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=128m -Xms1024m -Xmx1024m -Xmn256m -Xss256k -XX:SurvivorRatio=8 -XX:+UseConcMarkSweepGC
set ENGINE=novel-admin.jar
cd ../
java -jar %OPTS% -Dloader.path=conf,lib %ENGINE%
pause

View File

@ -2,20 +2,18 @@ package com.java2nb;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.transaction.annotation.EnableTransactionManagement;
//关闭SpringSecurity的功能
@EnableAutoConfiguration(exclude = {
org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration.class
})
@EnableTransactionManagement
@ServletComponentScan
@MapperScan("com.java2nb.*.dao")
@SpringBootApplication
@SpringBootApplication(exclude = {
org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration.class
})
@EnableCaching
public class AdminApplication {
public static void main(String[] args) {

View File

@ -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");

View File

@ -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;

View File

@ -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();
}
}

View File

@ -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);
}

View File

@ -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;
}
}

View File

@ -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);
}

View File

@ -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);
}
}

View File

@ -9,8 +9,8 @@ logging:
spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driverClassName: com.mysql.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai
driverClassName: com.mysql.cj.jdbc.Driver
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:

View File

@ -1,16 +1,19 @@
java2nb:
uploadPath: /var/java2nb/uploaded_files/
uploadPath: /var/pic/
username: admin
password: 111111
logging:
level:
root: error
com.java2nb: info
com.java2nb: error
spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driverClassName: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/java2nb?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai
username: java2nb
password: java2nb1019
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:
initialSize: 1
minIdle: 3
maxActive: 20
@ -34,18 +37,18 @@ spring:
# 合并多个DruidDataSource的监控数据
#useGlobalDataSourceStat: true
redis:
host: 127.0.0.1
port: 6379
password:
# 连接超时时间毫秒
timeout: 10000
jedis:
pool:
# 连接池中的最大空闲连接
max-idle: 8
# 连接池中的最小空闲连接
min-idle: 10
# 连接池最大连接数使用负值表示没有限制
max-active: 100
# 连接池最大阻塞等待时间使用负值表示没有限制
max-wait: -1
host: 127.0.0.1
port: 6379
password: test
# 连接超时时间毫秒
timeout: 10000
jedis:
pool:
# 连接池中的最大空闲连接
max-idle: 8
# 连接池中的最小空闲连接
min-idle: 10
# 连接池最大连接数使用负值表示没有限制
max-active: 100
# 连接池最大阻塞等待时间使用负值表示没有限制
max-wait: -1

View File

@ -1,6 +1,15 @@
__ ________ ___.
|__|____ ___ _______ \_____ \ ____\_ |__
| \__ \\ \/ /\__ \ / ____/ / \| __ \
| |/ __ \\ / / __ \_/ \| | \ \_\ \
/\__| (____ /\_/ (____ /\_______ \___| /___ /
\______| \/ \/ \/ \/ \/
${AnsiColor.CYAN}
--------------------------------------------------------------------------------
${AnsiColor.RED}
|| / | / /
|| / | / / ___ // ___ ___ _ __
|| / /||/ / //___) ) // // ) ) // ) ) // ) ) ) )
||/ / | / // // // // / / // / / / /
| / | / ((____ // ((____ ((___/ / // / / / / 小说精品屋欢迎您!!!
-------Powered By XXY
${AnsiColor.CYAN}
--------------------------------------------------------------------------------
${AnsiColor.BRIGHT_YELLOW}
::: Spring-Boot ${spring-boot.formatted-version} :::

View File

@ -56,7 +56,7 @@
<!-- 指定项目中某个包,当有日志操作行为时的日志记录级别 -->
<!-- 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="debug" />
</logger>
</configuration>

View File

@ -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>

View File

@ -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';

View File

@ -1,327 +0,0 @@
<!DOCTYPE html>
<html>
<meta charset="utf-8">
<head th:include="include :: header"></head>
<body class="gray-bg">
<div class="wrapper wrapper-content ">
<div class="row">
<div class="col-sm-12">
<div class="ibox float-e-margins">
<div class="ibox-content">
<form class="form-horizontal m-t" id="signupForm">
<div class="form-group">
<label class="col-sm-3 control-label">付呗商户号:</label>
<div class="col-sm-8">
<input id="fbMerchantCode" name="fbMerchantCode"
class="form-control"
type="text">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">第三方商户的订单号:</label>
<div class="col-sm-8">
<input id="merchantOrderSn" name="merchantOrderSn"
class="form-control"
type="text">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">付呗订单号:</label>
<div class="col-sm-8">
<select data-placeholder="--选择--" id="orderSn"
name="orderSn"
class="form-control chosen-select" tabindex="2"
dict-type="color">
</select>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">平台方订单号:</label>
<div class="col-sm-8">
<select data-placeholder="--选择--" id="platformOrderNo"
name="platformOrderNo"
class="form-control chosen-select" tabindex="2"
dict-type="oa_leave_type">
</select>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">商户单号:</label>
<div class="col-sm-8">
<input type="hidden" id="tradeNo" name="tradeNo"/>
<div id="contentEditortradeNo">
</div>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">订单状态1未支付2支付成功3支付失败4支付取消</label>
<div class="col-sm-8">
<select data-placeholder="--选择--" id="orderState"
name="orderState"
class="form-control chosen-select" tabindex="2"
dict-type="yes_no">
</select>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">蜂鸟优惠卷抵扣:</label>
<div class="col-sm-8">
<input id="fnCoupon" name="fnCoupon"
class="form-control"
type="number">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">红包抵扣:</label>
<div class="col-sm-8">
<input id="redPacket" name="redPacket"
class="form-control"
type="number">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">实收金额(元)</label>
<div class="col-sm-8">
<input id="totalFee" name="totalFee"
class="form-control"
type="number">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">订单金额:</label>
<div class="col-sm-8">
<input id="orderPrice" name="orderPrice"
class="form-control"
type="number">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">手续费(元)</label>
<div class="col-sm-8">
<input id="fee" name="fee"
class="form-control"
type="number">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">对商品或交易的描述:</label>
<div class="col-sm-8">
<img title="点击选择图片" id="picImagebody"
style="cursor:pointer;width: 100px;height: 100px"
src="/img/webuploader.png"/>
<input id="body" name="body"
class="form-control"
type="hidden">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">附加数据:</label>
<div class="col-sm-8">
<input type="hidden" id="attach" name="attach"/>
<div id="contentEditorattach">
</div>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">付呗系统的门店id</label>
<div class="col-sm-8">
<input id="storeId" name="storeId"
class="form-control"
type="number">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">付呗系统的收银员id</label>
<div class="col-sm-8">
<input id="cashierId" name="cashierId"
class="form-control"
type="number">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">设备终端号:</label>
<div class="col-sm-8">
<input id="deviceNo" name="deviceNo"
class="form-control"
type="text">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">微信顾客支付授权的“open_id”或者支付宝顾客的“buyer_user_id”</label>
<div class="col-sm-8">
<input id="userId" name="userId"
class="form-control"
type="text">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">支付宝顾客的账号:</label>
<div class="col-sm-8">
<textarea id="userLogonId" name="userLogonId"
class="form-control"></textarea>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">交易成功的时间:</label>
<div class="col-sm-8">
<input type="text" class="laydate-icon layer-date form-control"
id="payTime"
name="payTime"
onclick="laydate({istime: true, format: 'YYYY-MM-DD hh:mm:ss'})"
style="background-color: #fff;" readonly="readonly"/>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">支付通道:1微信、2支付宝、3银联</label>
<div class="col-sm-8">
<select data-placeholder="--选择--" id="payChannel"
name="payChannel"
class="form-control chosen-select" tabindex="2"
dict-type="del_flag">
</select>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">免充值代金券金额(元)</label>
<div class="col-sm-8">
<input id="noCashCouponFee" name="noCashCouponFee"
class="form-control"
type="number">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">预充值代金券金额(元)</label>
<div class="col-sm-8">
<input id="cashCouponFee" name="cashCouponFee"
class="form-control"
type="number">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">顾客实际支付金额(元)</label>
<div class="col-sm-8">
<input id="cashFee" name="cashFee"
class="form-control"
type="number">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">签名:</label>
<div class="col-sm-8">
<select data-placeholder="--选择--" id="sign"
name="sign"
class="form-control chosen-select" tabindex="2"
dict-type="theme">
</select>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">其它选项:</label>
<div class="col-sm-8">
<img title="点击选择图片" id="picImageoptions"
style="cursor:pointer;width: 100px;height: 100px"
src="/img/webuploader.png"/>
<input id="options" name="options"
class="form-control"
type="hidden">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">创建时间:</label>
<div class="col-sm-8">
<input type="text" class="laydate-icon layer-date form-control"
id="createTime"
name="createTime"
onclick="laydate({istime: true, format: 'YYYY-MM-DD hh:mm:ss'})"
style="background-color: #fff;" readonly="readonly"/>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">推送时间:</label>
<div class="col-sm-8">
<input type="text" class="laydate-icon layer-date form-control"
id="pushTime"
name="pushTime"
onclick="laydate({istime: true, format: 'YYYY-MM-DD hh:mm:ss'})"
style="background-color: #fff;" readonly="readonly"/>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">推送IP</label>
<div class="col-sm-8">
<input type="hidden" id="pushIp" name="pushIp"/>
<div id="contentEditorpushIp">
</div>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">商户id</label>
<div class="col-sm-8">
<input id="mchtId" name="mchtId"
class="form-control"
type="number">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">QR编号</label>
<div class="col-sm-8">
<input id="sn" name="sn"
class="form-control"
type="text">
</div>
</div>
<div class="form-group">
<div class="col-sm-8 col-sm-offset-3">
<button type="submit" class="btn btn-primary">提交</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
<div th:include="include::footer"></div>
<script type="text/javascript" src="/wangEditor/release/wangEditor.js"></script>
<script type="text/javascript" src="/js/appjs/test/order/add.js">
</script>
</body>
</html>

View File

@ -1,315 +0,0 @@
<!DOCTYPE html>
<html>
<meta charset="utf-8">
<head th:include="include :: header"></head>
<body class="gray-bg">
<div class="wrapper wrapper-content ">
<div class="row">
<div class="col-sm-12">
<div class="ibox float-e-margins">
<div class="ibox-content">
<form class="form-horizontal m-t" id="signupForm">
<input id="id" name="id" th:value="${order.id}"
type="hidden">
<div class="form-group">
<label class="col-sm-3 control-label">付呗商户号:</label>
<div style="padding-top:8px" class="col-sm-8"
th:text="${order.fbMerchantCode}">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">第三方商户的订单号:</label>
<div style="padding-top:8px" class="col-sm-8"
th:text="${order.merchantOrderSn}">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">付呗订单号:</label>
<div style="padding-top:8px" class="col-sm-8 dict-type" dict-type="color"
th:attr="dict-value=${order.orderSn}">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">平台方订单号:</label>
<div style="padding-top:8px" class="col-sm-8 dict-type" dict-type="oa_leave_type"
th:attr="dict-value=${order.platformOrderNo}">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">商户单号:</label>
<div style="padding-top:8px" class="col-sm-8"
th:utext="${order.tradeNo}"></div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">订单状态1未支付2支付成功3支付失败4支付取消</label>
<div style="padding-top:8px" class="col-sm-8 dict-type" dict-type="yes_no"
th:attr="dict-value=${order.orderState}">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">蜂鸟优惠卷抵扣:</label>
<div style="padding-top:8px" class="col-sm-8"
th:text="${order.fnCoupon}">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">红包抵扣:</label>
<div style="padding-top:8px" class="col-sm-8"
th:text="${order.redPacket}">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">实收金额(元)</label>
<div style="padding-top:8px" class="col-sm-8"
th:text="${order.totalFee}">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">订单金额:</label>
<div style="padding-top:8px" class="col-sm-8"
th:text="${order.orderPrice}">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">手续费(元)</label>
<div style="padding-top:8px" class="col-sm-8"
th:text="${order.fee}">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">对商品或交易的描述:</label>
<div style="padding-top:8px" class="col-sm-8">
<img id="picImagebody"
style="cursor:pointer;width: 100px;height: 100px"
th:src="${order.body}==null?'/img/webuploader.png':${order.body}"/>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">附加数据:</label>
<div style="padding-top:8px" class="col-sm-8"
th:utext="${order.attach}"></div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">付呗系统的门店id</label>
<div style="padding-top:8px" class="col-sm-8"
th:text="${order.storeId}">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">付呗系统的收银员id</label>
<div style="padding-top:8px" class="col-sm-8"
th:text="${order.cashierId}">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">设备终端号:</label>
<div style="padding-top:8px" class="col-sm-8"
th:text="${order.deviceNo}">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">微信顾客支付授权的“open_id”或者支付宝顾客的“buyer_user_id”</label>
<div style="padding-top:8px" class="col-sm-8"
th:text="${order.userId}">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">支付宝顾客的账号:</label>
<div style="padding-top:8px" class="col-sm-8"
th:text="${order.userLogonId}">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">交易成功的时间:</label>
<div style="padding-top:8px" class="col-sm-8"
th:text="${order.payTime}==null?null:${#dates.format(order.payTime,'yyyy-MM-dd HH:mm:ss')}">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">支付通道:1微信、2支付宝、3银联</label>
<div style="padding-top:8px" class="col-sm-8 dict-type" dict-type="del_flag"
th:attr="dict-value=${order.payChannel}">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">免充值代金券金额(元)</label>
<div style="padding-top:8px" class="col-sm-8"
th:text="${order.noCashCouponFee}">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">预充值代金券金额(元)</label>
<div style="padding-top:8px" class="col-sm-8"
th:text="${order.cashCouponFee}">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">顾客实际支付金额(元)</label>
<div style="padding-top:8px" class="col-sm-8"
th:text="${order.cashFee}">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">签名:</label>
<div style="padding-top:8px" class="col-sm-8 dict-type" dict-type="theme"
th:attr="dict-value=${order.sign}">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">其它选项:</label>
<div style="padding-top:8px" class="col-sm-8">
<img id="picImageoptions"
style="cursor:pointer;width: 100px;height: 100px"
th:src="${order.options}==null?'/img/webuploader.png':${order.options}"/>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">创建时间:</label>
<div style="padding-top:8px" class="col-sm-8"
th:text="${order.createTime}==null?null:${#dates.format(order.createTime,'yyyy-MM-dd HH:mm:ss')}">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">推送时间:</label>
<div style="padding-top:8px" class="col-sm-8"
th:text="${order.pushTime}==null?null:${#dates.format(order.pushTime,'yyyy-MM-dd HH:mm:ss')}">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">推送IP</label>
<div style="padding-top:8px" class="col-sm-8"
th:utext="${order.pushIp}"></div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">商户id</label>
<div style="padding-top:8px" class="col-sm-8"
th:text="${order.mchtId}">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">QR编号</label>
<div style="padding-top:8px" class="col-sm-8"
th:text="${order.sn}">
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
<div th:include="include::footer"></div>
</body>
</html>

View File

@ -1,323 +0,0 @@
<!DOCTYPE html>
<html>
<meta charset="utf-8">
<head th:include="include :: header"></head>
<body class="gray-bg">
<div class="wrapper wrapper-content ">
<div class="row">
<div class="col-sm-12">
<div class="ibox float-e-margins">
<div class="ibox-content">
<form class="form-horizontal m-t" id="signupForm">
<input id="id" name="id" th:value="${order.id}"
type="hidden">
<div class="form-group">
<label class="col-sm-3 control-label">付呗商户号:</label>
<div class="col-sm-8">
<input id="fbMerchantCode" name="fbMerchantCode"
th:value="${order.fbMerchantCode}"
class="form-control"
type="text">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">第三方商户的订单号:</label>
<div class="col-sm-8">
<input id="merchantOrderSn" name="merchantOrderSn"
th:value="${order.merchantOrderSn}"
class="form-control"
type="text">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">付呗订单号:</label>
<div class="col-sm-8">
<select data-placeholder="--选择--" id="orderSn"
name="orderSn"
class="form-control chosen-select" tabindex="2"
dict-type="color"
th:attr="dict-value=${order.orderSn}" >
</select>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">平台方订单号:</label>
<div class="col-sm-8">
<select data-placeholder="--选择--" id="platformOrderNo"
name="platformOrderNo"
class="form-control chosen-select" tabindex="2"
dict-type="oa_leave_type"
th:attr="dict-value=${order.platformOrderNo}" >
</select>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">商户单号:</label>
<div class="col-sm-8">
<input type="hidden" id="tradeNo" name="tradeNo" th:value="${order.tradeNo}"/>
<div id="contentEditortradeNo">
</div>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">订单状态1未支付2支付成功3支付失败4支付取消</label>
<div class="col-sm-8">
<select data-placeholder="--选择--" id="orderState"
name="orderState"
class="form-control chosen-select" tabindex="2"
dict-type="yes_no"
th:attr="dict-value=${order.orderState}" >
</select>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">蜂鸟优惠卷抵扣:</label>
<div class="col-sm-8">
<input id="fnCoupon" name="fnCoupon"
th:value="${order.fnCoupon}"
class="form-control"
type="number">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">红包抵扣:</label>
<div class="col-sm-8">
<input id="redPacket" name="redPacket"
th:value="${order.redPacket}"
class="form-control"
type="number">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">实收金额(元)</label>
<div class="col-sm-8">
<input id="totalFee" name="totalFee"
th:value="${order.totalFee}"
class="form-control"
type="number">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">订单金额:</label>
<div class="col-sm-8">
<input id="orderPrice" name="orderPrice"
th:value="${order.orderPrice}"
class="form-control"
type="number">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">手续费(元)</label>
<div class="col-sm-8">
<input id="fee" name="fee"
th:value="${order.fee}"
class="form-control"
type="number">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">对商品或交易的描述:</label>
<div class="col-sm-8">
<img title="点击选择图片" id="picImagebody"
style="cursor:pointer;width: 100px;height: 100px"
th:src="${order.body}==null?'/img/webuploader.png':${order.body}"/>
<input id="body" name="body" th:value="${order.body}"
class="form-control"
type="hidden">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">附加数据:</label>
<div class="col-sm-8">
<input type="hidden" id="attach" name="attach" th:value="${order.attach}"/>
<div id="contentEditorattach">
</div>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">付呗系统的门店id</label>
<div class="col-sm-8">
<input id="storeId" name="storeId"
th:value="${order.storeId}"
class="form-control"
type="number">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">付呗系统的收银员id</label>
<div class="col-sm-8">
<input id="cashierId" name="cashierId"
th:value="${order.cashierId}"
class="form-control"
type="number">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">设备终端号:</label>
<div class="col-sm-8">
<input id="deviceNo" name="deviceNo"
th:value="${order.deviceNo}"
class="form-control"
type="text">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">微信顾客支付授权的“open_id”或者支付宝顾客的“buyer_user_id”</label>
<div class="col-sm-8">
<input id="userId" name="userId"
th:value="${order.userId}"
class="form-control"
type="text">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">支付宝顾客的账号:</label>
<div class="col-sm-8">
<textarea id="userLogonId" name="userLogonId"
class="form-control" th:text="${order.userLogonId}"></textarea>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">交易成功的时间:</label>
<div class="col-sm-8">
<input type="text" class="laydate-icon layer-date form-control"
id="payTime"
name="payTime"
th:value="${order.payTime}==null?null:${#dates.format(order.payTime,'yyyy-MM-dd HH:mm:ss')}"
onclick="laydate({istime: true, format: 'YYYY-MM-DD hh:mm:ss'})"
style="background-color: #fff;" readonly="readonly"/>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">支付通道:1微信、2支付宝、3银联</label>
<div class="col-sm-8">
<select data-placeholder="--选择--" id="payChannel"
name="payChannel"
class="form-control chosen-select" tabindex="2"
dict-type="del_flag"
th:attr="dict-value=${order.payChannel}" >
</select>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">免充值代金券金额(元)</label>
<div class="col-sm-8">
<input id="noCashCouponFee" name="noCashCouponFee"
th:value="${order.noCashCouponFee}"
class="form-control"
type="number">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">预充值代金券金额(元)</label>
<div class="col-sm-8">
<input id="cashCouponFee" name="cashCouponFee"
th:value="${order.cashCouponFee}"
class="form-control"
type="number">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">顾客实际支付金额(元)</label>
<div class="col-sm-8">
<input id="cashFee" name="cashFee"
th:value="${order.cashFee}"
class="form-control"
type="number">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">签名:</label>
<div class="col-sm-8">
<select data-placeholder="--选择--" id="sign"
name="sign"
class="form-control chosen-select" tabindex="2"
dict-type="theme"
th:attr="dict-value=${order.sign}" >
</select>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">其它选项:</label>
<div class="col-sm-8">
<img title="点击选择图片" id="picImageoptions"
style="cursor:pointer;width: 100px;height: 100px"
th:src="${order.options}==null?'/img/webuploader.png':${order.options}"/>
<input id="options" name="options" th:value="${order.options}"
class="form-control"
type="hidden">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">创建时间:</label>
<div class="col-sm-8">
<input type="text" class="laydate-icon layer-date form-control"
id="createTime"
name="createTime"
th:value="${order.createTime}==null?null:${#dates.format(order.createTime,'yyyy-MM-dd HH:mm:ss')}"
onclick="laydate({istime: true, format: 'YYYY-MM-DD hh:mm:ss'})"
style="background-color: #fff;" readonly="readonly"/>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">推送时间:</label>
<div class="col-sm-8">
<input type="text" class="laydate-icon layer-date form-control"
id="pushTime"
name="pushTime"
th:value="${order.pushTime}==null?null:${#dates.format(order.pushTime,'yyyy-MM-dd HH:mm:ss')}"
onclick="laydate({istime: true, format: 'YYYY-MM-DD hh:mm:ss'})"
style="background-color: #fff;" readonly="readonly"/>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">推送IP</label>
<div class="col-sm-8">
<input type="hidden" id="pushIp" name="pushIp" th:value="${order.pushIp}"/>
<div id="contentEditorpushIp">
</div>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">商户id</label>
<div class="col-sm-8">
<input id="mchtId" name="mchtId"
th:value="${order.mchtId}"
class="form-control"
type="number">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">QR编号</label>
<div class="col-sm-8">
<input id="sn" name="sn"
th:value="${order.sn}"
class="form-control"
type="text">
</div>
</div>
<div class="form-group">
<div class="col-sm-8 col-sm-offset-3">
<button type="submit" class="btn btn-primary">提交</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
<div th:include="include::footer"></div>
<script type="text/javascript" src="/wangEditor/release/wangEditor.js"></script>
<script type="text/javascript" src="/js/appjs/test/order/edit.js">
</script>
</body>
</html>

View File

@ -1,66 +0,0 @@
<!DOCTYPE html>
<html>
<meta charset="utf-8">
<head th:include="include :: header"></head>
<body class="gray-bg">
<div class="wrapper wrapper-content ">
<div class="col-sm-12">
<div class="ibox">
<div class="ibox-body">
<div class="fixed-table-toolbar">
<div class="columns pull-left">
<button shiro:hasPermission="test:order:add" type="button"
class="btn btn-primary" onclick="add()">
<i class="fa fa-plus" aria-hidden="true"></i>添加
</button>
<button shiro:hasPermission="test:order:batchRemove" type="button"
class="btn btn-danger"
onclick="batchRemove()">
<i class="fa fa-trash" aria-hidden="true"></i>删除
</button>
</div>
<div class="columns pull-right">
<button class="btn btn-success" onclick="reLoad()">查询</button>
</div>
<form id="searchForm">
<div class="columns pull-right col-md-2">
<input id="id" name="id" type="text" class="form-control"
placeholder="主键">
</div>
</form>
</div>
<table id="exampleTable" data-mobile-responsive="true">
</table>
</div>
</div>
</div>
</div>
<!--shiro控制bootstraptable行内按钮看见性 -->
<div>
<script type="text/javascript">
var s_detail_h = 'hidden';
var s_edit_h = 'hidden';
var s_remove_h = 'hidden';
</script>
</div>
<div shiro:hasPermission="test:order:detail">
<script type="text/javascript">
s_detail_h = '';
</script>
</div>
<div shiro:hasPermission="test:order:edit">
<script type="text/javascript">
s_edit_h = '';
</script>
</div>
<div shiro:hasPermission="test:order:remove">
<script type="text/javascript">
var s_remove_h = '';
</script>
</div>
<div th:include="include :: footer"></div>
<script type="text/javascript" src="/js/appjs/test/order/order.js"></script>
</body>
</html>

View File

@ -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"));
}
;
}

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>novel</artifactId>
<groupId>com.java2nb</groupId>
<version>3.2.0</version>
<version>3.5.4</version>
</parent>
<modelVersion>4.0.0</modelVersion>
@ -123,6 +123,12 @@
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
</dependencies>

View File

@ -0,0 +1,53 @@
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 使用其他的分页工具或框架进行分页查询的场景
}

View File

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

View File

@ -65,4 +65,8 @@ public interface CacheKey {
* 累积的小说点击量
* */
String BOOK_ADD_VISIT_COUNT = "bookAddVisitCount";
/**
* 测试爬虫规则缓存
*/
String BOOK_TEST_PARSE = "testParse";
}

View File

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

View File

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

View File

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

View File

@ -1,6 +1,7 @@
package com.java2nb.novel.core.utils;
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,6 +12,7 @@ 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;
@ -19,13 +21,14 @@ 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 {
@ -82,5 +85,21 @@ public class FileUtil {
}
/**
* 判断文件是否为图片
* @param file 需要判断的文件
* @return true:是图片false:不是图片
* */
@SneakyThrows
public boolean isImage(File file){
BufferedImage bi = ImageIO.read(file);
return bi != null;
}
}

View File

@ -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;

View File

@ -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);

View File

@ -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)

View File

@ -71,8 +71,3 @@ sharding:
pic:
save:
type: 2 #图片保存方式, 1不保存使用爬取的网络图片 2保存在自己的存储介质
storage: local #存储介质local本地OSS阿里云对象存储fastDfs分布式文件系统
path: /var/pic #图片保存路径

View File

@ -0,0 +1,82 @@
spring:
profiles:
include: [common]
main:
allow-bean-definition-overriding: true
#Redis服务器IP
redis:
host: 127.0.0.1
#Redis服务器连接端口
port: 6379
#Redis服务器连接密码
password: test
jedis:
pool:
#连接池最大连接数使用负值表示没有限制
max-active: 8
#连接池最大阻塞等待时间使用负值表示没有限制
max-wait: 1
#连接池最大阻塞等待时间使用负值表示没有限制
max-idle: 8
#连接池中的最小空闲连接
min-idle: 0
#连接超时时间毫秒
timeout: 30000
datasource:
url: jdbc:mysql://127.0.0.1:3306/novel_biz?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai
username: root
password: test123456
driver-class-name: com.mysql.cj.jdbc.Driver
####使用shardingJdbc时
####所有的jdbcType都不能是LONGVARCHAR,否则会导致java.io.NotSerializableException: java.io.StringReader错误
##### 应该替换所有的 LONGVARCHAR 类型为VARCHAR
sharding:
jdbc:
datasource:
names: ds0 #,ds1
ds0:
type: com.zaxxer.hikari.HikariDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
jdbc-url: jdbc:mysql://localhost:3306/novel_plus?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai
username: root
password: test123456
# ds1:
# type: com.alibaba.druid.pool.DruidDataSource
# driver-class-name: com.mysql.jdbc.Driver
# url: jdbc:mysql://localhost:3306/novel_plus2
# username: root
# password: test123456
config:
sharding:
props:
sql.show: true
tables:
book_content: #book_content表
key-generator-column-name: id #主键
actual-data-nodes: ds${0}.book_content${0..9} #数据节点
# database-strategy: #分库策略
# inline:
# sharding-column: book_id
# algorithm-expression: ds${book_id % 10}
table-strategy: #分表策略
inline:
shardingColumn: index_id
algorithm-expression: book_content${index_id % 10}
logging:
level:
root: error
com.java2nb: error

View File

@ -1,17 +0,0 @@
spring:
profiles:
include: [common]
datasource:
url: jdbc:mysql://127.0.0.1:3306/novel_biz?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai
username: root
password: root
driver-class-name: com.mysql.cj.jdbc.Driver
pic:
save:
type: 2 #图片保存方式, 1不保存使用网络图片 2本地保存
path: /var/pic #图片保存路径

View File

@ -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

View File

@ -0,0 +1,15 @@
${AnsiColor.CYAN}
--------------------------------------------------------------------------------
${AnsiColor.RED}
|| / | / /
|| / | / / ___ // ___ ___ _ __
|| / /||/ / //___) ) // // ) ) // ) ) // ) ) ) )
||/ / | / // // // // / / // / / / /
| / | / ((____ // ((____ ((___/ / // / / / / 小说精品屋欢迎您!!!
-------Powered By XXY
${AnsiColor.CYAN}
--------------------------------------------------------------------------------
${AnsiColor.BRIGHT_YELLOW}
::: Spring-Boot ${spring-boot.formatted-version} :::

View File

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

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>novel</artifactId>
<groupId>com.java2nb</groupId>
<version>3.2.0</version>
<version>3.5.4</version>
</parent>
<modelVersion>4.0.0</modelVersion>
@ -32,8 +32,79 @@
<build>
<plugins>
<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>
</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>
</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>

View File

@ -0,0 +1,8 @@
1linux启动环境
sh start.sh
3windows启动环境
windows-start.bat
3linux停止应用
sh stop.sh

View File

@ -0,0 +1,47 @@
#!/bin/bash
ENGINE=novel-crawl.jar
cd ../
#部署目路
DEPLOY_DIR=`pwd`
#获取到当前目录的名称
SERVER_NAME=`basename $DEPLOY_DIR`
#应用进程
PIDS=`ps -ef | grep java | grep "$ENGINE" |awk '{print $2}'`
#设置日志文件的输出目录
LOGS_DIR=$DEPLOY_DIR/logs
if [ ! -d $LOGS_DIR ]; then
mkdir $LOGS_DIR
fi
#日志
STDOUT_FILE=$LOGS_DIR/stdout.log
#JAVA 环境配置
JAVA_OPTS=" -Djava.net.preferIPv4Stack=true -Dlog.home=$LOGS_DIR"
JAVA_MEM_OPTS=" -server -Xms1024m -Xmx1024m -XX:MetaspaceSize=64m -XX:MaxMetaspaceSize=256m -XX:+UseG1GC -XX:MaxGCPauseMillis=100 -XX:InitiatingHeapOccupancyPercent=50 -XX:+PrintGCApplicationStoppedTime -XX:+PrintGCApplicationConcurrentTime -XX:+PrintGCDateStamps -verbose:gc -XX:+PrintGCDetails -XX:+PrintHeapAtGC -Xloggc:$LOGS_DIR/gc.log -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=10 -XX:GCLogFileSize=100M -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=dump.hprof "
#退出标志
RETVAL="0"
if [ -n "$PIDS" ]; then
echo "ERROR: The $SERVER_NAME already started!"
echo "PID: $PIDS"
exit $RETVAL
fi
nohup java -jar $JAVA_OPTS $JAVA_MEM_OPTS -Dloader.path=conf,lib $ENGINE > $STDOUT_FILE 2>&1 &
COUNT=0
while [ $COUNT -lt 1 ]; do
echo -e ".\c"
sleep 1
COUNT=`ps -f | grep java | grep "$DEPLOY_DIR" | awk '{print $2}' | wc -l`
if [ $COUNT -gt 0 ]; then
break
fi
done
echo "OK!"
PIDS=`ps -f | grep java | grep "$DEPLOY_DIR" | awk '{print $2}'`
echo "PID: $PIDS"
echo "STDOUT: $STDOUT_FILE"

View File

@ -0,0 +1,33 @@
#!/bin/bash
SERVER_NAME=novel-crawl.jar
#应用进程
PIDS=`ps -ef | grep java | grep "$SERVER_NAME" |awk '{print $2}'`
if [ -z "$PIDS" ]; then
echo "ERROR: The $SERVER_NAME does not started!"
exit 1
fi
echo -e "Stopping the $SERVER_NAME ...\c"
for PID in $PIDS ; do
kill $PID > /dev/null 2>&1
done
COUNT=0
while [ $COUNT -lt 1 ]; do
echo -e ".\c"
sleep 1
COUNT=1
for PID in $PIDS ; do
PID_EXIST=`ps -f -p $PID | grep java`
if [ -n "$PID_EXIST" ]; then
COUNT=0
break
fi
done
done
echo "OK!"
echo "PID: $PIDS"
PIDS=""

View File

@ -0,0 +1,10 @@
@echo off
setlocal enabledelayedexpansion
set JAVA=java
set OPTS=-XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=128m -Xms1024m -Xmx1024m -Xmn256m -Xss256k -XX:SurvivorRatio=8 -XX:+UseConcMarkSweepGC
set ENGINE=novel-crawl.jar
cd ../
java -jar %OPTS% -Dloader.path=conf,lib %ENGINE%
pause

View File

@ -1,16 +1,26 @@
package com.java2nb.novel.controller;
import com.github.pagehelper.PageInfo;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.java2nb.novel.core.bean.PageBean;
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.crawl.CrawlParser;
import com.java2nb.novel.core.crawl.RuleBean;
import com.java2nb.novel.core.utils.HttpUtil;
import com.java2nb.novel.entity.BookIndex;
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 com.java2nb.novel.utils.Constants;
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,12 +31,12 @@ public class CrawlController {
private final CrawlService crawlService;
private final CacheService cacheService;
/**
* 新增爬虫源
* */
@PostMapping("addCrawlSource")
public ResultBean addCrawlSource(CrawlSource source){
public ResultBean<Void> addCrawlSource(CrawlSource source){
crawlService.addCrawlSource(source);
return ResultBean.ok();
@ -37,17 +47,79 @@ public class CrawlController {
* 爬虫源分页列表查询
* */
@GetMapping("listCrawlByPage")
public ResultBean listCrawlByPage(@RequestParam(value = "curr", defaultValue = "1") int page, @RequestParam(value = "limit", defaultValue = "10") int pageSize){
public ResultBean<PageBean<CrawlSource>> listCrawlByPage(@RequestParam(value = "curr", defaultValue = "1") int page, @RequestParam(value = "limit", defaultValue = "10") int pageSize){
return ResultBean.ok(crawlService.listCrawlByPage(page,pageSize));
}
/**
* 获取爬虫源
* */
@GetMapping("getCrawlSource/{id}")
public ResultBean<CrawlSource> getCrawlSource(@PathVariable("id") Integer id){
CrawlSource crawlSource= crawlService.getCrawlSource(id);
return ResultBean.ok(crawlSource);
return ResultBean.ok(new PageInfo<>(BeanUtil.copyList(crawlService.listCrawlByPage(page,pageSize), CrawlSourceVO.class)
));
}
/**
* 测试规则
* @param rule
* @param url
* @param isRefresh
* @return
*/
@PostMapping("testParse")
public ResultBean<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 ResultBean.ok(resultMap);
}
}
}else{
resultMap.put("html","url is null");
return ResultBean.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 ResultBean.ok(resultMap);
}
/**
* 修改爬虫源
* */
@PostMapping("updateCrawlSource")
public ResultBean<Void> updateCrawlSource(CrawlSource source){
crawlService.updateCrawlSource(source);
return ResultBean.ok();
}
/**
* 开启或停止爬虫
* */
@PostMapping("openOrCloseCrawl")
public ResultBean openOrCloseCrawl(Integer sourceId,Byte sourceStatus){
public ResultBean<Void> openOrCloseCrawl(Integer sourceId,Byte sourceStatus){
crawlService.openOrCloseCrawl(sourceId,sourceStatus);
@ -58,7 +130,7 @@ public class CrawlController {
* 新增单本采集任务
* */
@PostMapping("addCrawlSingleTask")
public ResultBean addCrawlSingleTask(CrawlSingleTask singleTask){
public ResultBean<Void> addCrawlSingleTask(CrawlSingleTask singleTask){
crawlService.addCrawlSingleTask(singleTask);
return ResultBean.ok();
@ -69,17 +141,16 @@ public class CrawlController {
* 单本采集任务分页列表查询
* */
@GetMapping("listCrawlSingleTaskByPage")
public ResultBean listCrawlSingleTaskByPage(@RequestParam(value = "curr", defaultValue = "1") int page, @RequestParam(value = "limit", defaultValue = "10") int pageSize){
public ResultBean<PageBean<CrawlSingleTask>> listCrawlSingleTaskByPage(@RequestParam(value = "curr", defaultValue = "1") int page, @RequestParam(value = "limit", defaultValue = "10") int pageSize){
return ResultBean.ok(new PageInfo<>(BeanUtil.copyList(crawlService.listCrawlSingleTaskByPage(page,pageSize), CrawlSingleTaskVO.class)
));
return ResultBean.ok(crawlService.listCrawlSingleTaskByPage(page,pageSize));
}
/**
* 删除采集任务
* */
@DeleteMapping("delCrawlSingleTask/{id}")
public ResultBean delCrawlSingleTask(@PathVariable("id") Long id){
public ResultBean<Void> delCrawlSingleTask(@PathVariable("id") Long id){
crawlService.delCrawlSingleTask(id);

View File

@ -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
*/

View File

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

View File

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

View File

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

View File

@ -26,18 +26,14 @@ import static java.util.regex.Pattern.compile;
@Slf4j
public class CrawlParser {
private static IdWorker idWorker = new IdWorker();
private static final IdWorker idWorker = new IdWorker();
public static final Integer BOOK_INDEX_LIST_KEY = 1;
private static final RestTemplate restTemplate = RestTemplateUtil.getInstance("utf-8");
public static final Integer BOOK_CONTENT_LIST_KEY = 2;
private static 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);
@ -139,13 +135,10 @@ public class CrawlParser {
}
}
}
return book;
handler.handle(book);
}
public static Map<Integer, List> parseBookIndexAndContent(String sourceBookId, Book book, RuleBean ruleBean, Map<Integer, BookIndex> hasIndexs) {
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 void parseBookIndexAndContent(String sourceBookId, Book book, RuleBean ruleBean, Map<Integer, BookIndex> existBookIndexMap, CrawlBookChapterHandler handler) {
Date currentDate = new Date();
@ -171,11 +164,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 +214,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 +228,7 @@ public class CrawlParser {
bookContent.setIndexId(hasIndex.getId());
//计算总字数
totalWordCount = (totalWordCount+wordCount-hasIndex.getWordCount());
totalWordCount = (totalWordCount + wordCount - hasIndex.getWordCount());
} else {
//章节插入
//设置目录和章节内容
@ -253,7 +246,6 @@ public class CrawlParser {
bookIndex.setUpdateTime(currentDate);
}
@ -266,7 +258,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 +269,22 @@ 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;
}
}
handler.handle(new ChapterBean() {{
setBookIndexList(new ArrayList<>(0));
setBookContentList(new ArrayList<>(0));
}});
return result;
}
@ -294,6 +293,7 @@ public class CrawlParser {
ResponseEntity<String> forEntity = restTemplate.getForEntity(url, String.class);
if (forEntity.getStatusCode() == HttpStatus.OK) {
String body = forEntity.getBody();
assert body != null;
if (body.length() < Constants.INVALID_HTML_LENGTH) {
return processErrorHttpResult(url);
}

View File

@ -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;

View File

@ -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);

View File

@ -8,12 +8,10 @@ import com.java2nb.novel.entity.CrawlSource;
import com.java2nb.novel.service.CrawlService;
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;
/**

View File

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

View File

@ -1,5 +1,7 @@
package com.java2nb.novel.service;
import com.java2nb.novel.core.bean.PageBean;
import com.java2nb.novel.core.bean.ResultBean;
import com.java2nb.novel.core.crawl.RuleBean;
import com.java2nb.novel.entity.CrawlSingleTask;
import com.java2nb.novel.entity.CrawlSource;
@ -17,14 +19,18 @@ public interface CrawlService {
* */
void addCrawlSource(CrawlSource source);
/**
* 修改爬虫源
* @param source
*/
void updateCrawlSource(CrawlSource source);
/**
* 爬虫源分页列表
* @param page 当前页码
* @param pageSize 分页大小
*@return 爬虫源集合
*@return 爬虫源分页数据
* */
List<CrawlSource> listCrawlByPage(int page, int pageSize);
PageBean<CrawlSource> listCrawlByPage(int page, int pageSize);
/**
* 开启或停止爬虫
@ -61,7 +67,7 @@ public interface CrawlService {
* 根据分类ID和规则解析分类列表
* @param catId 分类ID
* @param ruleBean 规则对象
* @param sourceId
* @param sourceId 爬虫源ID
*/
void parseBookList(int catId, RuleBean ruleBean, Integer sourceId);
@ -83,9 +89,9 @@ public interface CrawlService {
* 单本采集任务分页列表查询
* @param page 当前页码
* @param pageSize 分页大小
* @return 单本采集任务集合
* @return 单本采集任务分页数据
* */
List<CrawlSingleTask> listCrawlSingleTaskByPage(int page, int pageSize);
PageBean<CrawlSingleTask> listCrawlSingleTaskByPage(int page, int pageSize);
/**
* 删除采集任务
@ -105,4 +111,11 @@ public interface CrawlService {
* @param status 采集状态
* */
void updateCrawlSingleTask(CrawlSingleTask task, Byte status);
/**
* 获取采集规则详细
* @param id
* @return
*/
CrawlSource getCrawlSource(Integer id);
}

View File

@ -176,19 +176,4 @@ public class BookServiceImpl implements BookService {
}
/**
* 查询最后的章节
* */
private BookIndex queryLastIndex(Long bookId) {
return bookIndexMapper.queryLastIndex(bookId);
}
/**
* 查询小说总字数
* */
private Integer queryTotalWordCount(Long bookId) {
return bookMapper.queryTotalWordCount(bookId);
}
}

View File

@ -2,20 +2,28 @@ package com.java2nb.novel.service.impl;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.pagehelper.PageHelper;
import com.java2nb.novel.core.bean.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 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 lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
@ -23,18 +31,16 @@ 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 com.java2nb.novel.mapper.CrawlSourceDynamicSqlSupport.id;
import static org.mybatis.dynamic.sql.SqlBuilder.isEqualTo;
import static org.mybatis.dynamic.sql.select.SelectDSL.select;
/**
@ -64,16 +70,36 @@ public class CrawlServiceImpl implements CrawlService {
crawlSourceMapper.insertSelective(source);
}
@Override
public List<CrawlSource> listCrawlByPage(int page, int pageSize) {
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);
SelectStatementProvider render = select(id, sourceName, sourceStatus, createTime, updateTime)
.from(crawlSource)
.orderBy(updateTime)
.build()
.render(RenderingStrategies.MYBATIS3);
return crawlSourceMapper.selectMany(render);
List<CrawlSource> crawlSources = crawlSourceMapper.selectMany(render);
PageBean<CrawlSource> pageBean = new PageBean<>(crawlSources);
pageBean.setList(BeanUtil.copyList(crawlSources, CrawlSourceVO.class));
return pageBean;
}
@SneakyThrows
@ -112,11 +138,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());
@ -134,12 +156,17 @@ public class CrawlServiceImpl implements CrawlService {
@Override
public CrawlSource queryCrawlSource(Integer sourceId) {
SelectStatementProvider render = select(CrawlSourceDynamicSqlSupport.sourceStatus, CrawlSourceDynamicSqlSupport.crawlRule)
SelectStatementProvider render = select(id, sourceName, sourceStatus, createTime, updateTime,crawlRule)
.from(crawlSource)
.where(id, isEqualTo(sourceId))
.build()
.render(RenderingStrategies.MYBATIS3);
return crawlSourceMapper.selectMany(render).get(0);
List<CrawlSource> list= crawlSourceMapper.selectMany(render);
if(list!=null&&list.size()>0){
return list.get(0);
}
return null;
}
@Override
@ -156,14 +183,17 @@ public class CrawlServiceImpl implements CrawlService {
}
@Override
public List<CrawlSingleTask> listCrawlSingleTaskByPage(int page, int pageSize) {
public PageBean<CrawlSingleTask> listCrawlSingleTaskByPage(int page, int pageSize) {
PageHelper.startPage(page, pageSize);
SelectStatementProvider render = select(CrawlSingleTaskDynamicSqlSupport.crawlSingleTask.allColumns())
.from(CrawlSingleTaskDynamicSqlSupport.crawlSingleTask)
.orderBy(CrawlSingleTaskDynamicSqlSupport.createTime.descending())
.build()
.render(RenderingStrategies.MYBATIS3);
return crawlSingleTaskMapper.selectMany(render);
List<CrawlSingleTask> crawlSingleTasks = crawlSingleTaskMapper.selectMany(render);
PageBean<CrawlSingleTask> pageBean = new PageBean<>(crawlSingleTasks);
pageBean.setList(BeanUtil.copyList(crawlSingleTasks, CrawlSingleTaskVO.class));
return pageBean;
}
@Override
@ -198,6 +228,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;
}
/**
* 解析分类列表
*/
@ -267,39 +307,46 @@ 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(new IdWorker().nextId());
//解析章节目录
CrawlParser.parseBookIndexAndContent(bookId, book, ruleBean, new HashMap<>(0),chapter -> {
bookService.saveBookAndIndexAndContent(book, chapter.getBookIndexList(), chapter.getBookContentList());
});
bookService.saveBookAndIndexAndContent(book, (List<BookIndex>) indexAndContentList.get(CrawlParser.BOOK_INDEX_LIST_KEY), (List<BookContent>) indexAndContentList.get(CrawlParser.BOOK_CONTENT_LIST_KEY));
} else {
//只更新书籍的爬虫相关字段
bookService.updateCrawlProperties(existBook.getId(), sourceId, bookId);
}
parseResult.set(true);
});
return parseResult.get();
} else {
//只更新书籍的爬虫相关字段
bookService.updateCrawlProperties(existBook.getId(), sourceId, bookId);
}
return true;
}
@Override

View File

@ -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 {

View File

@ -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{

View File

@ -0,0 +1,3 @@
spring:
profiles:
include: [common-prod]

View File

@ -1,6 +1,9 @@
#端口号
server:
port: 8081
servlet:
session:
timeout: 1D
spring:
profiles:
@ -19,3 +22,6 @@ crawl:
thread: 1

View File

@ -57,7 +57,7 @@
<!-- 指定项目中某个包,当有日志操作行为时的日志记录级别 -->
<!-- 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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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,8 +120,8 @@
<script language="javascript" type="text/javascript">
search(1, 10);
var pageCrawlSourceList=null;
function search(curr, limit) {
$.ajax({
type: "get",
url: "/crawl/listCrawlByPage",
@ -129,6 +130,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 +149,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 +200,12 @@
})
}
function updateCrawlSource(crawlSourceId){
localStorage.setItem("crawlSourceId",crawlSourceId);
window.location.href="/crawl/crawlSource_update.html";
}
function openOrStopCrawl(sourceId,status) {

View File

@ -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>

View File

@ -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>&lt;p class="title"&gt;([^/]+)&lt;/p&gt;</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>&lt;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>状态:([^/]+)&lt;/li&gt;</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>&lt;div\s+class="score"&gt;(\d+\.\d+)分&lt;/div&gt;</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>&lt;p class="review"&gt;</b>
<li><input type="text" id="descStart" class="s_input icon_key"
placeholder="小说简介开始截取字符串"></li>
示例:<b>&lt;/p&gt;</b>
<li><input type="text" id="descEnd" class="s_input icon_key" placeholder="小说简介结束截取字符串">
</li>
示例:<b>更新:(\d+-\d+-\d+\s\d+:\d+:\d+)&lt;/a&gt;</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>&lt;a\s+style=""\s+href="/ddk\d+/(\d+)\.html"&gt;[^/]+&lt;/a&gt;</b>
<li><input type="text" id="indexIdPatten" class="s_input icon_key"
placeholder="目录页目录ID正则表达式"></li>
示例:<b>&lt;a\s+style=""\s+href="/ddk\d+/\d+\.html"&gt;([^/]+)&lt;/a&gt;</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>&lt;script&gt;</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>

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>novel</artifactId>
<groupId>com.java2nb</groupId>
<version>3.2.0</version>
<version>3.5.4</version>
</parent>
<modelVersion>4.0.0</modelVersion>
@ -39,6 +39,12 @@
<version>${jest.version}</version>
</dependency>
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>${elasticsearch.version}</version>
</dependency>
<!--aliyunOSS-->
<dependency>
<groupId>com.aliyun.oss</groupId>
@ -81,14 +87,92 @@
</dependency>
</dependencies>
<!-- <build>-->
<!-- <plugins>-->
<!-- <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>
<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>
</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>
</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>

View File

@ -0,0 +1,8 @@
1linux启动环境
sh start.sh
3windows启动环境
windows-start.bat
3linux停止应用
sh stop.sh

View File

@ -0,0 +1,47 @@
#!/bin/bash
ENGINE=novel-front.jar
cd ../
#部署目路
DEPLOY_DIR=`pwd`
#获取到当前目录的名称
SERVER_NAME=`basename $DEPLOY_DIR`
#应用进程
PIDS=`ps -ef | grep java | grep "$ENGINE" |awk '{print $2}'`
#设置日志文件的输出目录
LOGS_DIR=$DEPLOY_DIR/logs
if [ ! -d $LOGS_DIR ]; then
mkdir $LOGS_DIR
fi
#日志
STDOUT_FILE=$LOGS_DIR/stdout.log
#JAVA 环境配置
JAVA_OPTS=" -Djava.net.preferIPv4Stack=true -Dlog.home=$LOGS_DIR"
JAVA_MEM_OPTS=" -server -Xms1024m -Xmx1024m -XX:MetaspaceSize=64m -XX:MaxMetaspaceSize=256m -XX:+UseG1GC -XX:MaxGCPauseMillis=100 -XX:InitiatingHeapOccupancyPercent=50 -XX:+PrintGCApplicationStoppedTime -XX:+PrintGCApplicationConcurrentTime -XX:+PrintGCDateStamps -verbose:gc -XX:+PrintGCDetails -XX:+PrintHeapAtGC -Xloggc:$LOGS_DIR/gc.log -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=10 -XX:GCLogFileSize=100M -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=dump.hprof "
#退出标志
RETVAL="0"
if [ -n "$PIDS" ]; then
echo "ERROR: The $SERVER_NAME already started!"
echo "PID: $PIDS"
exit $RETVAL
fi
nohup java -jar $JAVA_OPTS $JAVA_MEM_OPTS -Dloader.path=conf,lib $ENGINE > $STDOUT_FILE 2>&1 &
COUNT=0
while [ $COUNT -lt 1 ]; do
echo -e ".\c"
sleep 1
COUNT=`ps -f | grep java | grep "$DEPLOY_DIR" | awk '{print $2}' | wc -l`
if [ $COUNT -gt 0 ]; then
break
fi
done
echo "OK!"
PIDS=`ps -f | grep java | grep "$DEPLOY_DIR" | awk '{print $2}'`
echo "PID: $PIDS"
echo "STDOUT: $STDOUT_FILE"

View File

@ -0,0 +1,33 @@
#!/bin/bash
SERVER_NAME=novel-front.jar
#应用进程
PIDS=`ps -ef | grep java | grep "$SERVER_NAME" |awk '{print $2}'`
if [ -z "$PIDS" ]; then
echo "ERROR: The $SERVER_NAME does not started!"
exit 1
fi
echo -e "Stopping the $SERVER_NAME ...\c"
for PID in $PIDS ; do
kill $PID > /dev/null 2>&1
done
COUNT=0
while [ $COUNT -lt 1 ]; do
echo -e ".\c"
sleep 1
COUNT=1
for PID in $PIDS ; do
PID_EXIST=`ps -f -p $PID | grep java`
if [ -n "$PID_EXIST" ]; then
COUNT=0
break
fi
done
done
echo "OK!"
echo "PID: $PIDS"
PIDS=""

View File

@ -0,0 +1,10 @@
@echo off
setlocal enabledelayedexpansion
set JAVA=java
set OPTS=-XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=128m -Xms1024m -Xmx1024m -Xmn256m -Xss256k -XX:SurvivorRatio=8 -XX:+UseConcMarkSweepGC
set ENGINE=novel-front.jar
cd ../
java -jar %OPTS% -Dloader.path=conf,lib %ENGINE%
pause

View File

@ -5,6 +5,7 @@ import io.shardingsphere.shardingjdbc.spring.boot.SpringBootConfiguration;
import org.mybatis.spring.annotation.MapperScan;
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.annotation.Bean;
import org.springframework.context.annotation.Import;
@ -20,6 +21,7 @@ import org.springframework.transaction.annotation.EnableTransactionManagement;
@EnableTransactionManagement
@EnableScheduling
@EnableCaching
@ServletComponentScan
@MapperScan(basePackages = {"com.java2nb.novel.mapper"})
@Import(FdfsClientConfig.class)
public class FrontNovelApplication {

View File

@ -1,22 +1,21 @@
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.core.exception.BusinessException;
import com.java2nb.novel.core.utils.BeanUtil;
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,7 +35,7 @@ public class AuthorController extends BaseController{
* 校验笔名是否存在
* */
@GetMapping("checkPenName")
public ResultBean checkPenName(String penName){
public ResultBean<Boolean> checkPenName(String penName){
return ResultBean.ok(authorService.checkPenName(penName));
}
@ -45,17 +44,16 @@ public class AuthorController extends BaseController{
* 作家发布小说分页列表查询
* */
@GetMapping("listBookByPage")
public ResultBean listBookByPage(@RequestParam(value = "curr", defaultValue = "1") int page, @RequestParam(value = "limit", defaultValue = "10") int pageSize ,HttpServletRequest request){
public ResultBean<PageBean<Book>> listBookByPage(@RequestParam(value = "curr", defaultValue = "1") int page, @RequestParam(value = "limit", defaultValue = "10") int pageSize , HttpServletRequest request){
return ResultBean.ok(new PageInfo<>(bookService.listBookPageByUserId(getUserDetails(request).getId(),page,pageSize)
));
return ResultBean.ok(bookService.listBookPageByUserId(getUserDetails(request).getId(),page,pageSize));
}
/**
* 发布小说
* */
@PostMapping("addBook")
public ResultBean addBook(@RequestParam("bookDesc") String bookDesc,Book book,HttpServletRequest request){
public ResultBean<Void> addBook(@RequestParam("bookDesc") String bookDesc,Book book,HttpServletRequest request){
Author author = checkAuthor(request);
@ -73,7 +71,7 @@ public class AuthorController extends BaseController{
* 更新小说状态,上架或下架
* */
@PostMapping("updateBookStatus")
public ResultBean updateBookStatus(Long bookId,Byte status,HttpServletRequest request){
public ResultBean<Void> updateBookStatus(Long bookId,Byte status,HttpServletRequest request){
Author author = checkAuthor(request);
//更新小说状态,上架或下架
@ -88,7 +86,7 @@ public class AuthorController extends BaseController{
* 删除章节
*/
@DeleteMapping("deleteIndex/{indexId}")
public ResultBean deleteIndex(@PathVariable("indexId") Long indexId, HttpServletRequest request) {
public ResultBean<Void> deleteIndex(@PathVariable("indexId") Long indexId, HttpServletRequest request) {
Author author = checkAuthor(request);
@ -102,7 +100,7 @@ public class AuthorController extends BaseController{
* 更新章节名
*/
@PostMapping("updateIndexName")
public ResultBean updateIndexName(Long indexId, String indexName, HttpServletRequest request) {
public ResultBean<Void> updateIndexName(Long indexId, String indexName, HttpServletRequest request) {
Author author = checkAuthor(request);
@ -119,7 +117,7 @@ public class AuthorController extends BaseController{
* 发布章节内容
*/
@PostMapping("addBookContent")
public ResultBean addBookContent(Long bookId, String indexName, String content,Byte isVip, HttpServletRequest request) {
public ResultBean<Void> addBookContent(Long bookId, String indexName, String content,Byte isVip, HttpServletRequest request) {
Author author = checkAuthor(request);
content = content.replaceAll("\\n", "<br>")
@ -134,7 +132,7 @@ public class AuthorController extends BaseController{
* 查询章节内容
*/
@GetMapping("queryIndexContent/{indexId}")
public ResultBean queryIndexContent(@PathVariable("indexId") Long indexId, HttpServletRequest request) {
public ResultBean<String> queryIndexContent(@PathVariable("indexId") Long indexId, HttpServletRequest request) {
Author author = checkAuthor(request);
@ -150,7 +148,7 @@ public class AuthorController extends BaseController{
* 更新章节内容
*/
@PostMapping("updateBookContent")
public ResultBean updateBookContent(Long indexId, String indexName, String content, HttpServletRequest request) {
public ResultBean<Void> updateBookContent(Long indexId, String indexName, String content, HttpServletRequest request) {
Author author = checkAuthor(request);
content = content.replaceAll("\\n", "<br>")
@ -161,19 +159,29 @@ public class AuthorController extends BaseController{
return ResultBean.ok();
}
/**
* 修改小说封面
*/
@PostMapping("updateBookPic")
public ResultBean<Void> updateBookPic(@RequestParam("bookId") Long bookId,@RequestParam("bookPic") String bookPic,HttpServletRequest request) {
Author author = checkAuthor(request);
bookService.updateBookPic(bookId,bookPic, author.getId());
return ResultBean.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 ResultBean<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(new PageInfo<>(authorService.listIncomeDailyByPage(page,pageSize,getUserDetails(request).getId(),bookId,startTime,endTime)
));
return ResultBean.ok(authorService.listIncomeDailyByPage(page,pageSize,getUserDetails(request).getId(),bookId,startTime,endTime));
}
@ -181,13 +189,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 ResultBean<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(new PageInfo<>(authorService.listIncomeMonthByPage(page,pageSize,getUserDetails(request).getId(),bookId)
));
return ResultBean.ok(authorService.listIncomeMonthByPage(page,pageSize,getUserDetails(request).getId(),bookId));
}
private Author checkAuthor(HttpServletRequest request) {

View File

@ -1,11 +1,17 @@
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.search.BookSP;
import com.java2nb.novel.entity.BookIndex;
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 lombok.RequiredArgsConstructor;
@ -16,6 +22,7 @@ import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
@ -39,7 +46,7 @@ public class BookController extends BaseController{
* 查询首页小说设置列表数据
* */
@GetMapping("listBookSetting")
public ResultBean listBookSetting(){
public ResultBean<Map<Byte, List<BookSettingVO>>> listBookSetting(){
return ResultBean.ok(bookService.listBookSettingVO());
}
@ -47,7 +54,7 @@ public class BookController extends BaseController{
* 查询首页点击榜单数据
* */
@GetMapping("listClickRank")
public ResultBean listClickRank(){
public ResultBean<List<Book>> listClickRank(){
return ResultBean.ok(bookService.listClickRank());
}
@ -55,7 +62,7 @@ public class BookController extends BaseController{
* 查询首页新书榜单数据
* */
@GetMapping("listNewRank")
public ResultBean listNewRank(){
public ResultBean<List<Book>> listNewRank(){
return ResultBean.ok(bookService.listNewRank());
}
@ -63,7 +70,7 @@ public class BookController extends BaseController{
* 查询首页更新榜单数据
* */
@GetMapping("listUpdateRank")
public ResultBean listUpdateRank(){
public ResultBean<List<BookVO>> listUpdateRank(){
return ResultBean.ok(bookService.listUpdateRank());
}
@ -71,7 +78,7 @@ public class BookController extends BaseController{
* 查询小说分类列表
* */
@GetMapping("listBookCategory")
public ResultBean listBookCategory(){
public ResultBean<List<BookCategory>> listBookCategory(){
return ResultBean.ok(bookService.listBookCategory());
}
@ -79,16 +86,15 @@ public class BookController extends BaseController{
* 分页搜索
* */
@GetMapping("searchByPage")
public ResultBean searchByPage(BookSP bookSP, @RequestParam(value = "curr", defaultValue = "1") int page, @RequestParam(value = "limit", defaultValue = "20") int pageSize){
PageInfo<BookVO> pageInfo = bookService.searchByPage(bookSP,page,pageSize);
return ResultBean.ok(pageInfo);
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));
}
/**
* 查询小说详情信息
* */
@GetMapping("queryBookDetail/{id}")
public ResultBean queryBookDetail(@PathVariable("id") Long id){
public ResultBean<Book> queryBookDetail(@PathVariable("id") Long id){
return ResultBean.ok(bookService.queryBookDetail(id));
}
@ -97,7 +103,7 @@ public class BookController extends BaseController{
* 查询小说排行信息
* */
@GetMapping("listRank")
public ResultBean listRank(@RequestParam(value = "type",defaultValue = "0") Byte type,@RequestParam(value = "limit",defaultValue = "30") Integer limit){
public ResultBean<List<Book>> listRank(@RequestParam(value = "type",defaultValue = "0") Byte type,@RequestParam(value = "limit",defaultValue = "30") Integer limit){
return ResultBean.ok(bookService.listRank(type,limit));
}
@ -105,7 +111,7 @@ public class BookController extends BaseController{
* 增加点击次数
* */
@PostMapping("addVisitCount")
public ResultBean addVisitCount(Long bookId){
public ResultBean<Void> addVisitCount(Long bookId){
if(enableMq == 1) {
rabbitTemplate.convertAndSend("ADD-BOOK-VISIT-EXCHANGE", null, bookId);
}else {
@ -118,7 +124,7 @@ public class BookController extends BaseController{
* 查询章节相关信息
* */
@GetMapping("queryBookIndexAbout")
public ResultBean queryBookIndexAbout(Long bookId,Long lastBookIndexId) {
public ResultBean<Map<String,Object>> queryBookIndexAbout(Long bookId,Long lastBookIndexId) {
Map<String,Object> data = new HashMap<>(2);
data.put("bookIndexCount",bookService.queryIndexCount(bookId));
String lastBookContent = bookService.queryBookContent(lastBookIndexId).getContent();
@ -133,7 +139,7 @@ public class BookController extends BaseController{
* 根据分类id查询同类推荐书籍
* */
@GetMapping("listRecBookByCatId")
public ResultBean listRecBookByCatId(Integer catId) {
public ResultBean<List<Book>> listRecBookByCatId(Integer catId) {
return ResultBean.ok(bookService.listRecBookByCatId(catId));
}
@ -142,15 +148,15 @@ public class BookController extends BaseController{
*分页查询书籍评论列表
* */
@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(new PageInfo<>(bookService.listCommentByPage(null,bookId,page,pageSize)));
public ResultBean<PageBean<BookCommentVO>> listCommentByPage(@RequestParam("bookId") Long bookId, @RequestParam(value = "curr", defaultValue = "1") int page, @RequestParam(value = "limit", defaultValue = "5") int pageSize) {
return ResultBean.ok(bookService.listCommentByPage(null,bookId,page,pageSize));
}
/**
* 新增评价
* */
@PostMapping("addBookComment")
public ResultBean addBookComment(BookComment comment, HttpServletRequest request) {
public ResultBean<?> addBookComment(BookComment comment, HttpServletRequest request) {
UserDetails userDetails = getUserDetails(request);
if (userDetails == null) {
return ResultBean.fail(ResponseStatus.NO_LOGIN);
@ -163,7 +169,7 @@ public class BookController extends BaseController{
* 根据小说ID查询小说前十条最新更新目录集合
* */
@GetMapping("queryNewIndexList")
public ResultBean queryNewIndexList(Long bookId){
public ResultBean<List<BookIndex>> queryNewIndexList(Long bookId){
return ResultBean.ok(bookService.queryIndexList(bookId,"index_num desc",1,10));
}
@ -171,8 +177,8 @@ public class BookController extends BaseController{
* 目录页
* */
@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 PageInfo<>(bookService.queryIndexList(bookId,orderBy,page,pageSize)));
public ResultBean<PageBean<BookIndex>> indexList(Long bookId,@RequestParam(value = "curr", defaultValue = "1") int page, @RequestParam(value = "limit", defaultValue = "5") int pageSize,@RequestParam(value = "orderBy",defaultValue = "index_num desc") String orderBy) {
return ResultBean.ok(new PageBean<>(bookService.queryIndexList(bookId,orderBy,page,pageSize)));
}

View File

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

View File

@ -2,28 +2,23 @@ package com.java2nb.novel.controller;
import com.java2nb.novel.core.bean.ResultBean;
import com.java2nb.novel.core.cache.CacheService;
import com.java2nb.novel.core.enums.ResponseStatus;
import com.java2nb.novel.core.exception.BusinessException;
import com.java2nb.novel.core.utils.Constants;
import com.java2nb.novel.core.utils.FileUtil;
import com.java2nb.novel.core.utils.RandomValidateCodeUtil;
import com.java2nb.novel.core.utils.RestTemplateUtil;
import com.java2nb.novel.core.utils.UUIDUtil;
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.util.Date;
import java.util.Objects;
@ -63,29 +58,35 @@ public class FileController {
}
/**
* 文件上传
* 图片上传
* @return
*/
@SneakyThrows
@ResponseBody
@PostMapping("/upload")
ResultBean upload(@RequestParam("file") MultipartFile file) {
@PostMapping("/picUpload")
ResultBean<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 ResultBean.ok(savePath + "/" + saveFileName);
}

View File

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

View File

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

View File

@ -5,7 +5,7 @@ import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.java2nb.novel.core.bean.UserDetails;
import com.java2nb.novel.core.config.AlipayConfig;
import com.java2nb.novel.core.config.AlipayProperties;
import com.java2nb.novel.service.OrderService;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
@ -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;
/**
@ -31,7 +31,7 @@ import java.util.Map;
public class PayController extends BaseController {
private final AlipayConfig alipayConfig;
private final AlipayProperties alipayConfig;
private final OrderService orderService;
@ -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);

View File

@ -1,6 +1,5 @@
package com.java2nb.novel.controller;
import com.github.pagehelper.PageInfo;
import com.java2nb.novel.core.bean.ResultBean;
import com.java2nb.novel.core.bean.UserDetails;
import com.java2nb.novel.core.cache.CacheService;
@ -19,7 +18,6 @@ import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.util.HashMap;
import java.util.Map;
@ -43,7 +41,7 @@ public class UserController extends BaseController {
* 登陆
*/
@PostMapping("login")
public ResultBean login(User user) {
public ResultBean<Map<String, Object>> login(User user) {
//登陆
UserDetails userDetails = userService.login(user);
@ -60,7 +58,7 @@ public class UserController extends BaseController {
* 注册
*/
@PostMapping("register")
public ResultBean register(@Validated({AddGroup.class}) User user, @RequestParam(value = "velCode", defaultValue = "") String velCode) {
public ResultBean<?> register(@Validated({AddGroup.class}) User user, @RequestParam(value = "velCode", defaultValue = "") String velCode) {
//判断验证码是否正确
@ -83,7 +81,7 @@ public class UserController extends BaseController {
* 刷新token
*/
@PostMapping("refreshToken")
public ResultBean refreshToken(HttpServletRequest request) {
public ResultBean<?> refreshToken(HttpServletRequest request) {
String token = getToken(request);
if (jwtTokenUtil.canRefresh(token)) {
token = jwtTokenUtil.refreshToken(token);
@ -104,7 +102,7 @@ public class UserController extends BaseController {
* 查询小说是否已加入书架
*/
@GetMapping("queryIsInShelf")
public ResultBean queryIsInShelf(Long bookId, HttpServletRequest request) {
public ResultBean<?> queryIsInShelf(Long bookId, HttpServletRequest request) {
UserDetails userDetails = getUserDetails(request);
if (userDetails == null) {
return ResultBean.fail(ResponseStatus.NO_LOGIN);
@ -116,7 +114,7 @@ public class UserController extends BaseController {
* 加入书架
* */
@PostMapping("addToBookShelf")
public ResultBean addToBookShelf(Long bookId,Long preContentId, HttpServletRequest request) {
public ResultBean<Void> addToBookShelf(Long bookId,Long preContentId, HttpServletRequest request) {
UserDetails userDetails = getUserDetails(request);
if (userDetails == null) {
return ResultBean.fail(ResponseStatus.NO_LOGIN);
@ -129,7 +127,7 @@ public class UserController extends BaseController {
* 移出书架
* */
@DeleteMapping("removeFromBookShelf/{bookId}")
public ResultBean removeFromBookShelf(@PathVariable("bookId") Long bookId, HttpServletRequest request) {
public ResultBean<?> removeFromBookShelf(@PathVariable("bookId") Long bookId, HttpServletRequest request) {
UserDetails userDetails = getUserDetails(request);
if (userDetails == null) {
return ResultBean.fail(ResponseStatus.NO_LOGIN);
@ -142,31 +140,31 @@ public class UserController extends BaseController {
* 分页查询书架
* */
@GetMapping("listBookShelfByPage")
public ResultBean listBookShelfByPage(@RequestParam(value = "curr", defaultValue = "1") int page, @RequestParam(value = "limit", defaultValue = "10") int pageSize,HttpServletRequest request) {
public ResultBean<?> listBookShelfByPage(@RequestParam(value = "curr", defaultValue = "1") int page, @RequestParam(value = "limit", defaultValue = "10") int pageSize,HttpServletRequest request) {
UserDetails userDetails = getUserDetails(request);
if (userDetails == null) {
return ResultBean.fail(ResponseStatus.NO_LOGIN);
}
return ResultBean.ok(new PageInfo<>(userService.listBookShelfByPage(userDetails.getId(),page,pageSize)));
return ResultBean.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 ResultBean<?> 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 ResultBean.ok(new PageInfo<>(userService.listReadHistoryByPage(userDetails.getId(),page,pageSize)));
return ResultBean.ok(userService.listReadHistoryByPage(userDetails.getId(),page,pageSize));
}
/**
* 添加阅读记录
* */
@PostMapping("addReadHistory")
public ResultBean addReadHistory(Long bookId,Long preContentId, HttpServletRequest request) {
public ResultBean<?> addReadHistory(Long bookId,Long preContentId, HttpServletRequest request) {
UserDetails userDetails = getUserDetails(request);
if (userDetails == null) {
return ResultBean.fail(ResponseStatus.NO_LOGIN);
@ -179,7 +177,7 @@ public class UserController extends BaseController {
* 添加反馈
* */
@PostMapping("addFeedBack")
public ResultBean addFeedBack(String content, HttpServletRequest request) {
public ResultBean<?> addFeedBack(String content, HttpServletRequest request) {
UserDetails userDetails = getUserDetails(request);
if (userDetails == null) {
return ResultBean.fail(ResponseStatus.NO_LOGIN);
@ -192,19 +190,19 @@ public class UserController extends BaseController {
* 分页查询我的反馈列表
* */
@GetMapping("listUserFeedBackByPage")
public ResultBean listUserFeedBackByPage(@RequestParam(value = "curr", defaultValue = "1") int page, @RequestParam(value = "limit", defaultValue = "5") int pageSize, HttpServletRequest request){
public ResultBean<?> listUserFeedBackByPage(@RequestParam(value = "curr", defaultValue = "1") int page, @RequestParam(value = "limit", defaultValue = "5") int pageSize, HttpServletRequest request){
UserDetails userDetails = getUserDetails(request);
if (userDetails == null) {
return ResultBean.fail(ResponseStatus.NO_LOGIN);
}
return ResultBean.ok(new PageInfo<>(userService.listUserFeedBackByPage(userDetails.getId(),page,pageSize)));
return ResultBean.ok(userService.listUserFeedBackByPage(userDetails.getId(),page,pageSize));
}
/**
* 查询个人信息
* */
@GetMapping("userInfo")
public ResultBean userInfo(HttpServletRequest request) {
public ResultBean<?> userInfo(HttpServletRequest request) {
UserDetails userDetails = getUserDetails(request);
if (userDetails == null) {
return ResultBean.fail(ResponseStatus.NO_LOGIN);
@ -216,7 +214,7 @@ public class UserController extends BaseController {
* 更新个人信息
* */
@PostMapping("updateUserInfo")
public ResultBean updateUserInfo(@Validated({UpdateGroup.class}) User user, HttpServletRequest request) {
public ResultBean<?> updateUserInfo(@Validated({UpdateGroup.class}) User user, HttpServletRequest request) {
UserDetails userDetails = getUserDetails(request);
if (userDetails == null) {
return ResultBean.fail(ResponseStatus.NO_LOGIN);
@ -236,7 +234,7 @@ public class UserController extends BaseController {
* 更新密码
* */
@PostMapping("updatePassword")
public ResultBean updatePassword(String oldPassword,String newPassword1,String newPassword2,HttpServletRequest request) {
public ResultBean<?> updatePassword(String oldPassword,String newPassword1,String newPassword2,HttpServletRequest request) {
UserDetails userDetails = getUserDetails(request);
if (userDetails == null) {
return ResultBean.fail(ResponseStatus.NO_LOGIN);
@ -252,12 +250,12 @@ public class UserController extends BaseController {
* 分页查询用户书评
* */
@GetMapping("listCommentByPage")
public ResultBean listCommentByPage(@RequestParam(value = "curr", defaultValue = "1") int page, @RequestParam(value = "limit", defaultValue = "5") int pageSize,HttpServletRequest request) {
public ResultBean<?> listCommentByPage(@RequestParam(value = "curr", defaultValue = "1") int page, @RequestParam(value = "limit", defaultValue = "5") int pageSize,HttpServletRequest request) {
UserDetails userDetails = getUserDetails(request);
if (userDetails == null) {
return ResultBean.fail(ResponseStatus.NO_LOGIN);
}
return ResultBean.ok(new PageInfo<>(bookService.listCommentByPage(userDetails.getId(),null,page,pageSize)));
return ResultBean.ok(bookService.listCommentByPage(userDetails.getId(),null,page,pageSize));
}
@ -265,7 +263,7 @@ public class UserController extends BaseController {
* 购买小说章节
* */
@PostMapping("buyBookIndex")
public ResultBean buyBookIndex(UserBuyRecord buyRecord, HttpServletRequest request) {
public ResultBean<?> buyBookIndex(UserBuyRecord buyRecord, HttpServletRequest request) {
UserDetails userDetails = getUserDetails(request);
if (userDetails == null) {
return ResultBean.fail(ResponseStatus.NO_LOGIN);

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