mirror of
https://github.com/201206030/novel-plus.git
synced 2025-07-01 07:16:39 +00:00
Compare commits
260 Commits
Author | SHA1 | Date | |
---|---|---|---|
80b393fdda | |||
e7897c988a | |||
750c8dee02 | |||
cbfd0b049f | |||
7f0331e095 | |||
3520200a87 | |||
4939bcf418 | |||
1cffbae495 | |||
b99b6ae4f2 | |||
2e2a58c84b | |||
4fe36a8f4f | |||
b5df86d5c7 | |||
9b3ba1d8c1 | |||
c4db754d23 | |||
8d3ce53dba | |||
d32d9d8410 | |||
05ae012e05 | |||
b60a0c9b40 | |||
3efaf8ce5f | |||
ebc4210774 | |||
655ec90906 | |||
f28dd867ef | |||
8e6842a495 | |||
928cb2417f | |||
625694ba1e | |||
d6c0337c09 | |||
689efc0807 | |||
4540c3781e | |||
9d2c453bb0 | |||
9de47ce697 | |||
c79974ff77 | |||
fb0098aef8 | |||
e83494cb17 | |||
419d7a971b | |||
83eda2a44d | |||
3182029bdd | |||
19d4a9960d | |||
2603150b33 | |||
f5e440390b | |||
91e525ec8e | |||
83afb9e6e2 | |||
19d4c6b778 | |||
d22200b8c7 | |||
43fe1150fd | |||
65b65f874f | |||
3b6bc859a5 | |||
cfc55a6c92 | |||
0a80c5662d | |||
02fd0d7e25 | |||
521142a792 | |||
c567e37423 | |||
b5e0814eb4 | |||
ca6c2aec96 | |||
34859c839b | |||
039f9d9cf8 | |||
224829dd1f | |||
1a5122209a | |||
48aff7cf37 | |||
e673f9be9d | |||
20469bd669 | |||
755300db3c | |||
a790f8042d | |||
d0db2021a6 | |||
c403fc7496 | |||
e4927d7ac6 | |||
a00a2141f2 | |||
7cc7d8b541 | |||
e4822979e2 | |||
ab741ec6bf | |||
057c0646cd | |||
57a9cd09ef | |||
1a49e2a340 | |||
f8411c2337 | |||
343a741c21 | |||
f1a5fb4813 | |||
0428356bd4 | |||
c01097cd5f | |||
7e650a0a04 | |||
45c59ecc37 | |||
5e3962fef4 | |||
7f5035e369 | |||
44aad39847 | |||
6ad51908d5 | |||
f03ab953d0 | |||
5cc9dfa1bc | |||
2fbda60617 | |||
39c19ac004 | |||
7494fe431a | |||
c9f1500976 | |||
f61c252e71 | |||
6fd183c2ae | |||
c3daaecaaa | |||
1b6cc8ccd5 | |||
0a10504461 | |||
1046a7ffc1 | |||
612555dbe6 | |||
d5768e4011 | |||
5982eb623f | |||
85ad5fa3b2 | |||
bdc81f7676 | |||
f31c86f362 | |||
45d8902429 | |||
ff9696bb7e | |||
cacebcaa33 | |||
355cb80458 | |||
a8c74d061c | |||
a713b66c1b | |||
e9d915c1fe | |||
cd3520971d | |||
dc4c9138ee | |||
f830600c3e | |||
154210719f | |||
11e744e6a8 | |||
944ef912e2 | |||
2ce51d5fc0 | |||
2f4b671d84 | |||
6ffd8d90d7 | |||
1e2b6f4103 | |||
24c7175872 | |||
a6b009cc84 | |||
04afa759a7 | |||
1be39a0f13 | |||
2fd0349a80 | |||
79fd85ab9b | |||
0b22bbb111 | |||
7f4d315f25 | |||
f7375c5779 | |||
194461f729 | |||
6bf6b44493 | |||
cffa00a54a | |||
b279763383 | |||
cfe19854a5 | |||
28cebad48d | |||
68a1ece57c | |||
77645da2bd | |||
36376aa623 | |||
9e98665cca | |||
9a19a33406 | |||
a4f7042b87 | |||
31aa3192fd | |||
cd11854eff | |||
85f5048fd9 | |||
f625ee38e1 | |||
2c3e346ea7 | |||
66093cb065 | |||
beba6e5154 | |||
04d3aef82b | |||
018daf8d37 | |||
8e0f1f12a4 | |||
165c96cd48 | |||
e343134ce2 | |||
a1adb2c7df | |||
81a82d8e72 | |||
1d33094bd7 | |||
4cccea5d75 | |||
fbfb68583f | |||
655957904b | |||
99e973091d | |||
5fdf618223 | |||
03c4e6c54b | |||
29527301cf | |||
29d03a7a22 | |||
ad4199dc4e | |||
4f7f9af6a9 | |||
ee2a0f514f | |||
70f04bd37c | |||
9d621edaec | |||
56c0a81c1b | |||
6b3b88c147 | |||
894ee67f56 | |||
a88891b72f | |||
5c7724c813 | |||
79c9f3e0f1 | |||
575142f9f3 | |||
83c2460c83 | |||
c7642ac2ef | |||
5af570a514 | |||
0d96ff81b6 | |||
7733cf1e3f | |||
c9c714e71e | |||
3cbb6bf3fb | |||
750e234f60 | |||
c1d485c42b | |||
0e2e6229cd | |||
f8a669eb01 | |||
6d56399d0f | |||
1a0c1f864b | |||
b193aca288 | |||
7a6d7a4442 | |||
5505840b6e | |||
8eb3048b91 | |||
1b138c2aad | |||
f5e2dbaa6b | |||
b6cb9aaedc | |||
f9f1e474ec | |||
06bf848e99 | |||
6e171d20ed | |||
c62acc288e | |||
9975faed01 | |||
8fde3a3725 | |||
430504ee28 | |||
16447c60ec | |||
be7cbe2d6f | |||
8f1ed88b07 | |||
9b9851e7ab | |||
a55edf0408 | |||
856c4c0667 | |||
e4dd5bcb71 | |||
5dbddbdd96 | |||
73be43e1c5 | |||
ce2a3b4647 | |||
68abdeca93 | |||
0b505a3922 | |||
353cb8c536 | |||
e1e1310b9e | |||
4c42ac0d29 | |||
d025d3d514 | |||
a0fb8e481a | |||
80b933db8d | |||
87a060280a | |||
9c78f400dc | |||
c2cdf73893 | |||
a13ea78c3f | |||
0144b77983 | |||
07b9ffde96 | |||
002a0723f7 | |||
8a628f081f | |||
4aa6b82143 | |||
c80b02caf0 | |||
5e16119880 | |||
231b94f1da | |||
92ce982899 | |||
8c2e43c04f | |||
f553d23fb9 | |||
9773b73475 | |||
5543b905cd | |||
e273906441 | |||
83dc04c50b | |||
b4f5b18e93 | |||
fe80c21812 | |||
4c2a7f12c1 | |||
e24e87b546 | |||
b8b074d40a | |||
a662f42bcf | |||
0fa929f9de | |||
401d23871d | |||
4878f17de8 | |||
e9ab6d8bb0 | |||
c8d7a10d9f | |||
d30c6bfd6e | |||
334f3e17a6 | |||
a202100818 | |||
84814e0792 | |||
dde10c983e | |||
c9428bf0e7 | |||
0e2e610d18 | |||
9df69edc2c | |||
16aa925521 | |||
320d693238 | |||
ca9fd1c2f7 |
19
.gitignore
vendored
19
.gitignore
vendored
@ -1,12 +1,7 @@
|
||||
/.idea
|
||||
/cachedata
|
||||
/logs
|
||||
/novel-common/target
|
||||
/novel-front/target
|
||||
/novel-front/*.iml
|
||||
/novel-common/*.iml
|
||||
/novel-mobile/target
|
||||
/novel-mobile/*.iml
|
||||
/novel-front/novel-front.iml
|
||||
/novel-crawl/novel-crawl.iml
|
||||
/novel-crawl/target
|
||||
**/logs
|
||||
**/.idea
|
||||
**/cachedata
|
||||
**/target
|
||||
**/*.iml
|
||||
**/.DS_Store
|
||||
|
||||
|
293
README.md
293
README.md
@ -1,28 +1,49 @@
|
||||
[](https://cloud.tencent.com/act/cps/redirect?redirect=1052&cps_key=736e609d66e0ac4e57813316cec6fd0b&from=console)
|
||||
[]( https://cloud.tencent.com/act/cps/redirect?redirect=1052&cps_key=736e609d66e0ac4e57813316cec6fd0b&from=console )
|
||||
|
||||
# 小说精品屋-plus
|
||||
|
||||
#### 前言
|
||||
[](https://github.com/201206030/novel-plus)
|
||||
[](https://github.com/201206030/novel-plus)
|
||||
[](https://gitee.com/novel_dev_team/novel-plus)
|
||||
[](https://gitee.com/novel_dev_team/novel-plus)
|
||||
|
||||
#### 官网
|
||||
|
||||
https://201206030.github.io
|
||||
|
||||
#### 新项目:小说精品屋-微服务版
|
||||
|
||||
基于小说精品屋-plus构建的Spring Cloud 微服务小说门户平台。
|
||||
|
||||
GitHub仓库地址: https://github.com/201206030/novel-cloud
|
||||
|
||||
Gitee仓库地址: https://gitee.com/novel_dev_team/novel-cloud
|
||||
|
||||
#### 演示地址
|
||||
|
||||
[点击前往](http://47.106.243.172:8888/)
|
||||
|
||||
小说精品屋-plus致力于打造一个完整的商用小说门户平台。
|
||||
|
||||
#### 项目介绍
|
||||
|
||||
[小说精品屋](https://github.com/201206030/fiction_house)是一个多平台(web、安卓app、微信小程序)、功能完善的小说弹幕网站,包含精品小说专区、轻小说专区和漫画专区。包括小说/漫画分类、小说/漫画搜索、小说/漫画排行、完本小说/漫画、小说/漫画评分、小说/漫画在线阅读、小说/漫画书架、小说/漫画阅读记录、小说下载、小说弹幕、小说/漫画自动爬取、小说内容自动分享到微博、邮件自动推广、链接自动推送到百度搜索引擎等功能。包含电脑端、移动端、微信小程序等多个平台,现已开源web端、安卓端、小程序端源码。
|
||||
小说精品屋-plus是在[小说精品屋](https://github.com/201206030/fiction_house)的基础上,去除了漫画和弹幕模块,专注于小说,是一个多端(PC、WAP)阅读、功能完善的原创文学CMS系统,由前台门户系统、作家后台管理系统、平台后台管理系统、爬虫管理系统等多个子系统构成,支持会员充值、订阅模式、新闻发布和实时统计报表等功能。
|
||||
|
||||
小说精品屋-plus是在小说精品屋的基础上,重新进行了数据库设计、代码重构和功能增强,提升了程序整体的可读性和性能,增加了很多商用特性。主要升级如下:
|
||||
小说精品屋-plus重新进行了数据库设计、代码重构和功能增强,提升了程序整体的可读性和性能,增加了很多商用特性。主要升级如下:
|
||||
|
||||
- [x] 数据库重新设计,结构调整。
|
||||
- [x] 服务端代码重构,MyBatis3升级为MyBatis3DynamicSql。
|
||||
- [x] 移动站与PC站站点分离,浏览器自动识别跳转。
|
||||
- [x] PC站UI更新。
|
||||
- [x] 支持前端模版自定义,内置多套模版。
|
||||
- [x] 可拓展的多种方式存储小说内容,内置数据库(分表)存储和TXT文本存储。
|
||||
- [x] 新闻模块。
|
||||
- [x] 排行榜。
|
||||
- [x] 小说评论模块。
|
||||
- [x] 阅读主题模块。
|
||||
- [ ] 作家专区。
|
||||
- [ ] 充值。
|
||||
- [ ] 后台管理系统。
|
||||
- [x] 作家专区。
|
||||
- [x] 充值。
|
||||
- [x] 订阅。
|
||||
- [x] 后台管理系统。
|
||||
- [x] 爬虫管理系统。
|
||||
|
||||
#### 项目结构
|
||||
@ -30,105 +51,275 @@
|
||||
```
|
||||
novel-plus -- 父工程
|
||||
├── novel-common -- 通用模块
|
||||
├── novel-front -- 前台门户系统
|
||||
├── novel-crawl -- 爬虫管理系统
|
||||
└── novel-admin -- 后台管理系统
|
||||
├── novel-front -- 前台门户&作家后台管理子系统(可拆分)
|
||||
├── novel-crawl -- 爬虫管理子系统
|
||||
├── novel-admin -- 平台后台管理子系统
|
||||
└── templates -- 前端模版
|
||||
```
|
||||
|
||||
#### 技术选型
|
||||
Springboot+Mybatis+Mysql+Ehcache+Thymeleaf+Layui
|
||||
|
||||
#### PC站截图
|
||||
| 技术 | 说明
|
||||
| -------------------- | ---------------------------
|
||||
| SpringBoot | Spring应用快速开发脚手架
|
||||
| MyBatis | 持久层ORM框架
|
||||
| MyBatis Dynamic SQL | Mybatis动态sql
|
||||
| PageHelper | MyBatis分页插件
|
||||
| MyBatisGenerator | 持久层代码生成插件
|
||||
| Sharding-Jdbc | 代码层分库分表中间件
|
||||
| JJWT | JWT登录支持
|
||||
| SpringSecurity | 安全框架
|
||||
| Shiro | 安全框架
|
||||
| Ehcache | Java进程内缓存框架(默认缓存)
|
||||
| Redis | 分布式缓存(缓存替换方案,默认关闭,一行配置开启)
|
||||
| ElasticSearch | 搜索引擎(搜索增强方案,默认关闭,一行配置开启)
|
||||
| RabbitMq | 消息队列(流量削峰,默认关闭,一行配置开启)
|
||||
| OSS | 阿里云对象存储服务(图片存储方式之一,一行配置即可切换)
|
||||
| FastDfs |开源轻量级分布式文件系统(图片存储方式之一,一行配置即可切换)
|
||||
| Redisson | 实现分布式锁
|
||||
| Lombok | 简化对象封装工具
|
||||
| Docker | 应用容器引擎
|
||||
| Mysql | 数据库服务
|
||||
| Thymeleaf | 模板引擎
|
||||
| Layui | 前端UI
|
||||
|
||||
|
||||
#### 开发工具
|
||||
感谢Jetbrains公司提供的免费License。
|
||||
|
||||
[]( https://www.jetbrains.com/?from=小说精品屋)
|
||||
|
||||
|
||||
#### 接口文档
|
||||
|
||||

|
||||
[点击查看接口文档示例](doc/api/api.md)
|
||||
|
||||
|
||||
|
||||

|
||||
|
||||
|
||||
|
||||

|
||||
|
||||
|
||||
|
||||
#### 手机站截图
|
||||
#### 橙色主题模版截图
|
||||
##### PC站截图
|
||||
|
||||
1. 首页
|
||||
|
||||

|
||||

|
||||
|
||||
|
||||
2. 分类索引页
|
||||
|
||||
2. 小说详情页
|
||||

|
||||
|
||||

|
||||
3. 搜索页
|
||||
|
||||
|
||||

|
||||
|
||||
3. 目录页
|
||||

|
||||
|
||||

|
||||
4. 排行榜
|
||||
|
||||

|
||||
|
||||
5. 详情页
|
||||
|
||||

|
||||
|
||||
6. 阅读页
|
||||
|
||||

|
||||
|
||||
7. 用户中心
|
||||
|
||||

|
||||
|
||||
8. 充值
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
9. 作家专区
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
10. 购买
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
##### 手机站截图
|
||||
|
||||
1. 首页
|
||||
|
||||
<img src="https://s3.ax1x.com/2020/12/27/r5447n.jpg" alt="index" width="300" />
|
||||
|
||||
2. 小说列表页
|
||||
|
||||
<img src="https://s3.ax1x.com/2020/12/27/r55xKg.jpg" alt="微信图片_20190904181558" width="300" />
|
||||
|
||||
3. 小说详情页
|
||||
|
||||
<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/27/r55Stx.jpg" alt="QQ图片20191018161901" width="300" />
|
||||
|
||||
|
||||
##### 爬虫管理系统截图
|
||||
|
||||
#### 爬虫管理系统截图
|
||||

|
||||
|
||||

|
||||

|
||||
|
||||
##### 后台管理系统截图
|
||||
|
||||

|
||||
|
||||
#### 安装步骤
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
#### 深色主题模版截图
|
||||
##### PC站截图
|
||||
|
||||
1. 首页
|
||||
|
||||

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

|
||||
|
||||
4. 小说详情页
|
||||
|
||||

|
||||
|
||||
5. 目录页
|
||||
|
||||

|
||||
|
||||
5. 小说阅读页
|
||||
|
||||

|
||||
|
||||
#### 蓝色主题模版截图(更新中)
|
||||
|
||||

|
||||
|
||||
#### 安装步骤(源码,小白请看其他安装教程)
|
||||
|
||||
##### 数据库安装:
|
||||
|
||||
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.yml(dev环境,默认环境)或application-common-prod.yml(prod环境,需要在application.yml配置文件中切换)配置文件中的数据库配置。
|
||||
2. 修改novel-crawl模块下application.yml文件中的管理员账号密码。
|
||||
3. 启动程序,打开浏览器,默认8081端口访问。
|
||||
4. 选择已有或新增爬虫源(支持自定义爬虫规则),点击`开启`按钮,开始爬取小说数据。
|
||||
|
||||
##### 前台小说门户安装:
|
||||
##### 前台小说门户安装(dev环境跳过3、4步骤):
|
||||
|
||||
1. 修改novel-common模块下application-dev.yml文件中的数据库的配置。
|
||||
2. 启动程序,打开浏览器,默认8080端口访问。
|
||||
1. 修改novel-common模块下application-common-dev.yml(dev环境,默认环境)或application-common-prod.yml(prod环境,需要在application.yml配置文件中切换)配置文件中的数据库配置。
|
||||
|
||||
2. 修改novel-front模块下application-website配置文件中的网站信息。
|
||||
|
||||
```
|
||||
#网站配置
|
||||
website:
|
||||
#网站名
|
||||
name: 小说精品屋
|
||||
#域名
|
||||
domain: xiongxyang.gitee.io
|
||||
#SEO关键词
|
||||
keyword: ${website.name},小说,小说CMS,原创文学系统,开源小说系统,免费小说建站程序
|
||||
#SEO描述
|
||||
description: ${website.name}是一个多端(PC、WAP)阅读、功能完善的原创文学CMS系统,由前台门户系统、作家后台管理系统、平台后台管理系统、爬虫管理系统等多个子系统构成,支持会员充值、订阅模式、新闻发布和实时统计报表等功能,新书自动入库,老书自动更新。
|
||||
#联系QQ
|
||||
qq: 1179705413
|
||||
```
|
||||
|
||||
3. prod环境下需要修改novel-front模块下application-prod.yml配置文件中的模版名为你需要使用的模版名(templates文件夹下的模版文件夹名,内置orange和dark两套模版,prod环境下才支持多模版)。
|
||||
|
||||
```
|
||||
#模版配置
|
||||
templates:
|
||||
#模版名
|
||||
name: orange
|
||||
```
|
||||
|
||||
4. prod环境下的jar包形式部署时,需要复制templates文件夹到jar文件的相同目录下。
|
||||
|
||||
5. 启动程序,打开浏览器,默认8080端口访问。
|
||||
|
||||
**喜欢此项目的可以给我的GitHub和Gitee加个Star支持一下 。**
|
||||
|
||||
#### 演示地址
|
||||
#### 其他安装教程(如果链接打不开,可关注公众号获取)
|
||||
|
||||
[点击前往](http://www.java2nb.com)(前台门户)
|
||||
##### version>=3.5.0版本
|
||||
|
||||
包安装及低版本升级教程:[点击前往](https://my.oschina.net/java2nb/blog/4914688)
|
||||
|
||||
##### 3.3.0<=version<3.5.0版本
|
||||
|
||||
包安装教程:[点击前往](https://my.oschina.net/java2nb/blog/4842472)
|
||||
|
||||
##### version<3.3.0版本
|
||||
|
||||
包安装教程:[点击前往](https://my.oschina.net/java2nb/blog/4272630)
|
||||
|
||||
宝塔安装教程(非官方):[点击前往](https://www.daniao.org/9166.html)
|
||||
|
||||
docker安装教程:[点击前往](https://my.oschina.net/java2nb/blog/4271989)
|
||||
|
||||
#### 代码仓库
|
||||
|
||||
Gitee仓库地址: https://gitee.com/xiongxyang/novel-plus
|
||||
|
||||
GitHub仓库地址: https://github.com/201206030/novel-plus
|
||||
|
||||
Gitee仓库地址: https://gitee.com/novel_dev_team/novel-plus
|
||||
|
||||
#### QQ交流群
|
||||
|
||||

|
||||
[点击前往官网查看](https://xiongxyang.gitee.io/service.htm)
|
||||
|
||||
#### 捐赠支持
|
||||
问问题的三要素
|
||||
|
||||
开源项目不易,若此项目能得到你的青睐,可以捐赠支持作者持续开发与维护。
|
||||
1. 说明背景,使用了哪个模块,要做什么?
|
||||
|
||||

|
||||
2. 怎么输入或操作的得到了什么结果? 截图,日志
|
||||
|
||||
3. 哪里不明白或有什么疑问 ?
|
||||
|
||||
#### 微信公众号(发布最新更新资讯、最新前端模版、最新爬虫规则、技术文档等)
|
||||
|
||||

|
||||
|
||||
#### 赞赏支持
|
||||
|
||||
开源项目不易,若此项目能得到你的青睐,那么你可以赞赏支持作者持续开发与维护。
|
||||
|
||||
- 服务器的费用也是一笔开销
|
||||
- 为用户提供更好的开发环境
|
||||
- 一杯咖啡
|
||||
|
||||

|
||||
|
||||
#### 免责声明
|
||||
|
||||
本项目提供的爬虫工具仅用于采集项目初期的测试数据,请勿用于商业盈利。
|
||||
用户使用本系统从事任何违法违规的事情,一切后果由用户自行承担,作者不承担任何责任。
|
||||
|
||||
#### 备注
|
||||
|
||||
精品小说屋所有相关项目均已在开源中国公开,感兴趣的可进入[开源中国](https://www.oschina.net/p/fiction_house)按关键字`精品小说屋`搜索。
|
||||
|
||||
[](https://www.aliyun.com/minisite/goods?userCode=uf4nasee )
|
||||
[](https://www.aliyun.com/minisite/goods?userCode=uf4nasee )
|
||||
|
BIN
assets/QQ20200520-215756.png
Normal file
BIN
assets/QQ20200520-215756.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 105 KiB |
Binary file not shown.
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 62 KiB |
Binary file not shown.
Before Width: | Height: | Size: 8.1 KiB After Width: | Height: | Size: 185 KiB |
116
doc/api/api.md
Normal file
116
doc/api/api.md
Normal file
@ -0,0 +1,116 @@
|
||||
|
||||
<h1 class="curproject-name"> 小说精品屋-plus </h1>
|
||||
小说精品屋-plus接口
|
||||
|
||||
|
||||
# 作家模块
|
||||
|
||||
## 小说章节分页列表查询接口
|
||||
<a id=小说章节分页列表查询接口> </a>
|
||||
### 基本信息
|
||||
|
||||
**Path:** /book/queryIndexList
|
||||
|
||||
**Method:** GET
|
||||
|
||||
**接口描述:**
|
||||
<p>作家后台章节管理页面需要请求该接口获取小说章节分页列表信息</p>
|
||||
|
||||
|
||||
### 请求参数
|
||||
**Query**
|
||||
|
||||
| 参数名称 | 是否必须 | 示例 | 备注 |
|
||||
| ------------ | ------------ | ------------ | ------------ |
|
||||
| bookId | 是 | 1334337530296893441 | 小说ID |
|
||||
| curr | 否 | 1 | 查询页码,默认1 |
|
||||
| limit | 否 | 5 | 分页大小,默认5 |
|
||||
|
||||
### 返回数据
|
||||
|
||||
<table>
|
||||
<thead class="ant-table-thead">
|
||||
<tr>
|
||||
<th key=name>名称</th><th key=type>类型</th><th key=required>是否必须</th><th key=default>默认值</th><th key=desc>备注</th><th key=sub>其他信息</th>
|
||||
</tr>
|
||||
</thead><tbody className="ant-table-tbody"><tr key=0-0><td key=0><span style="padding-left: 0px"><span style="color: #8c8a8a"></span> code</span></td><td key=1><span>number</span></td><td key=2>必须</td><td key=3></td><td key=4><span style="white-space: pre-wrap">响应状态吗,200表示成功</span></td><td key=5></td></tr><tr key=0-1><td key=0><span style="padding-left: 0px"><span style="color: #8c8a8a"></span> msg</span></td><td key=1><span>string</span></td><td key=2>必须</td><td key=3></td><td key=4><span style="white-space: pre-wrap">响应信息</span></td><td key=5></td></tr><tr key=0-2><td key=0><span style="padding-left: 0px"><span style="color: #8c8a8a"></span> data</span></td><td key=1><span>object</span></td><td key=2>必须</td><td key=3></td><td key=4><span style="white-space: pre-wrap">响应数据</span></td><td key=5></td></tr><tr key=0-2-0><td key=0><span style="padding-left: 20px"><span style="color: #8c8a8a">├─</span> total</span></td><td key=1><span>number</span></td><td key=2>必须</td><td key=3></td><td key=4><span style="white-space: pre-wrap">总数量</span></td><td key=5></td></tr><tr key=0-2-1><td key=0><span style="padding-left: 20px"><span style="color: #8c8a8a">├─</span> list</span></td><td key=1><span>object []</span></td><td key=2>必须</td><td key=3></td><td key=4><span style="white-space: pre-wrap">章节数据集合</span></td><td key=5><p key=3><span style="font-weight: '700'">item 类型: </span><span>object</span></p></td></tr><tr key=0-2-1-0><td key=0><span style="padding-left: 40px"><span style="color: #8c8a8a">├─</span> id</span></td><td key=1><span>string</span></td><td key=2>必须</td><td key=3></td><td key=4><span style="white-space: pre-wrap">章节ID</span></td><td key=5></td></tr><tr key=0-2-1-1><td key=0><span style="padding-left: 40px"><span style="color: #8c8a8a">├─</span> bookId</span></td><td key=1><span>string</span></td><td key=2>必须</td><td key=3></td><td key=4><span style="white-space: pre-wrap">小说ID</span></td><td key=5></td></tr><tr key=0-2-1-2><td key=0><span style="padding-left: 40px"><span style="color: #8c8a8a">├─</span> indexName</span></td><td key=1><span>string</span></td><td key=2>必须</td><td key=3></td><td key=4><span style="white-space: pre-wrap">章节名</span></td><td key=5></td></tr><tr key=0-2-1-3><td key=0><span style="padding-left: 40px"><span style="color: #8c8a8a">├─</span> isVip</span></td><td key=1><span>number</span></td><td key=2>必须</td><td key=3></td><td key=4><span style="white-space: pre-wrap">是否收费,1:收费,0:免费</span></td><td key=5></td></tr><tr key=0-2-1-4><td key=0><span style="padding-left: 40px"><span style="color: #8c8a8a">├─</span> updateTime</span></td><td key=1><span>string</span></td><td key=2>必须</td><td key=3></td><td key=4><span style="white-space: pre-wrap">更新时间</span></td><td key=5></td></tr><tr key=0-2-2><td key=0><span style="padding-left: 20px"><span style="color: #8c8a8a">├─</span> pageNum</span></td><td key=1><span>number</span></td><td key=2>必须</td><td key=3></td><td key=4><span style="white-space: pre-wrap">页码</span></td><td key=5></td></tr><tr key=0-2-3><td key=0><span style="padding-left: 20px"><span style="color: #8c8a8a">├─</span> pageSize</span></td><td key=1><span>number</span></td><td key=2>必须</td><td key=3></td><td key=4><span style="white-space: pre-wrap">分页大小</span></td><td key=5></td></tr><tr key=0-2-4><td key=0><span style="padding-left: 20px"><span style="color: #8c8a8a">├─</span> size</span></td><td key=1><span>number</span></td><td key=2>必须</td><td key=3></td><td key=4><span style="white-space: pre-wrap">当前页数量</span></td><td key=5></td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
## 小说章节删除接口
|
||||
<a id=小说章节删除接口> </a>
|
||||
### 基本信息
|
||||
|
||||
**Path:** /author/deleteIndex/{indexId}
|
||||
|
||||
**Method:** DELETE
|
||||
|
||||
**接口描述:**
|
||||
<p>作家后台章节管理页面点击删除按钮请求该接口删除小说章节内容</p>
|
||||
|
||||
|
||||
### 请求参数
|
||||
**Headers**
|
||||
|
||||
| 参数名称 | 参数值 | 是否必须 | 示例 | 备注 |
|
||||
| ------------ | ------------ | ------------ | ------------ | ------------ |
|
||||
| Content-Type | application/x-www-form-urlencoded | 是 | | |
|
||||
| Authorization | | 是 | eyJhbGciOiJIUzUxMiJ9.eyJleHAiOjE2MDgzNDg0NzksInN1YiI6IntcImlkXCI6MTI1NTA2MDMyODMyMjAyNzUyMCxcInVzZXJuYW1lXCI6XCIxMzU2MDQyMTMyNFwiLFwibmlja05hbWVcIjpcIjEzNTYwNDIxMzI0XCJ9IiwiY3JlYXRlZCI6MTYwNzc0MzY3OTkxM30.0qhwis_zPb6t8wGNejMhDZ2iHCL9Tgh2UHd1gcQBCp8t6RW3ggSwtfo4l_RgMT_v8jOkLW91GzTVWlNnTE6LCA | 认证JWT,请求登录接口成功后返回 |
|
||||
**路径参数**
|
||||
|
||||
| 参数名称 | 示例 | 备注 |
|
||||
| ------------ | ------------ | ------------ |
|
||||
| indexId | 1337603246936645632 | 章节ID |
|
||||
|
||||
### 返回数据
|
||||
|
||||
<table>
|
||||
<thead class="ant-table-thead">
|
||||
<tr>
|
||||
<th key=name>名称</th><th key=type>类型</th><th key=required>是否必须</th><th key=default>默认值</th><th key=desc>备注</th><th key=sub>其他信息</th>
|
||||
</tr>
|
||||
</thead><tbody className="ant-table-tbody"><tr key=0-0><td key=0><span style="padding-left: 0px"><span style="color: #8c8a8a"></span> code</span></td><td key=1><span>number</span></td><td key=2>必须</td><td key=3></td><td key=4><span style="white-space: pre-wrap">响应状态吗,200表示成功</span></td><td key=5></td></tr><tr key=0-1><td key=0><span style="padding-left: 0px"><span style="color: #8c8a8a"></span> msg</span></td><td key=1><span>string</span></td><td key=2>必须</td><td key=3></td><td key=4><span style="white-space: pre-wrap">响应信息</span></td><td key=5></td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
## 小说章节发布接口
|
||||
<a id=小说章节发布接口> </a>
|
||||
### 基本信息
|
||||
|
||||
**Path:** /author/addBookContent
|
||||
|
||||
**Method:** POST
|
||||
|
||||
**接口描述:**
|
||||
<p>作家后台章节发布页面点击提交按钮请求该接口新增小说章节内容</p>
|
||||
|
||||
|
||||
### 请求参数
|
||||
**Headers**
|
||||
|
||||
| 参数名称 | 参数值 | 是否必须 | 示例 | 备注 |
|
||||
| ------------ | ------------ | ------------ | ------------ | ------------ |
|
||||
| Content-Type | application/x-www-form-urlencoded | 是 | | |
|
||||
| Authorization | | 是 | eyJhbGciOiJIUzUxMiJ9.eyJleHAiOjE2MDgzNDg0NzksInN1YiI6IntcImlkXCI6MTI1NTA2MDMyODMyMjAyNzUyMCxcInVzZXJuYW1lXCI6XCIxMzU2MDQyMTMyNFwiLFwibmlja05hbWVcIjpcIjEzNTYwNDIxMzI0XCJ9IiwiY3JlYXRlZCI6MTYwNzc0MzY3OTkxM30.0qhwis_zPb6t8wGNejMhDZ2iHCL9Tgh2UHd1gcQBCp8t6RW3ggSwtfo4l_RgMT_v8jOkLW91GzTVWlNnTE6LCA | 认证JWT,请求登录接口成功后返回 |
|
||||
**Body**
|
||||
|
||||
| 参数名称 | 参数类型 | 是否必须 | 示例 | 备注 |
|
||||
| ------------ | ------------ | ------------ | ------------ | ------------ |
|
||||
| bookId | text | 是 | 1334337530296893441 | 小说ID |
|
||||
| indexName | text | 是 | 第六章未婚妻(下) | 章节名 |
|
||||
| content | text | 是 | 开始之时,李七夜还是生疏无比,那怕他对于刀术的所有奥义了然于胸,但是,他出刀之时依然会颤抖,无法达到妙及巅毫的要求。 | 章节内容 |
|
||||
| isVip | text | 是 | 1 | 是否收费,1:收费,0:免费 |
|
||||
|
||||
|
||||
|
||||
### 返回数据
|
||||
|
||||
<table>
|
||||
<thead class="ant-table-thead">
|
||||
<tr>
|
||||
<th key=name>名称</th><th key=type>类型</th><th key=required>是否必须</th><th key=default>默认值</th><th key=desc>备注</th><th key=sub>其他信息</th>
|
||||
</tr>
|
||||
</thead><tbody className="ant-table-tbody"><tr key=0-0><td key=0><span style="padding-left: 0px"><span style="color: #8c8a8a"></span> code</span></td><td key=1><span>number</span></td><td key=2>必须</td><td key=3></td><td key=4><span style="white-space: pre-wrap">响应状态吗,200表示成功</span></td><td key=5></td></tr><tr key=0-1><td key=0><span style="padding-left: 0px"><span style="color: #8c8a8a"></span> msg</span></td><td key=1><span>string</span></td><td key=2>必须</td><td key=3></td><td key=4><span style="white-space: pre-wrap">响应信息</span></td><td key=5></td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
82
doc/es/index_create.txt
Normal file
82
doc/es/index_create.txt
Normal file
@ -0,0 +1,82 @@
|
||||
PUT /novel
|
||||
{
|
||||
"mappings" : {
|
||||
"book" : {
|
||||
"properties" : {
|
||||
"id" : {
|
||||
"type" : "long"
|
||||
},
|
||||
"authorId" : {
|
||||
"type" : "long"
|
||||
},
|
||||
"authorName" : {
|
||||
"type" : "text",
|
||||
"analyzer": "ik_smart",
|
||||
"boost": 1.9
|
||||
},
|
||||
|
||||
"bookName" : {
|
||||
"type" : "text",
|
||||
"analyzer": "ik_smart",
|
||||
"boost": 2
|
||||
},
|
||||
|
||||
"bookDesc" : {
|
||||
"type" : "text",
|
||||
"analyzer": "ik_smart",
|
||||
"boost": 0.1
|
||||
},
|
||||
|
||||
"bookStatus" : {
|
||||
"type" : "short"
|
||||
},
|
||||
|
||||
"catId" : {
|
||||
"type" : "integer"
|
||||
},
|
||||
|
||||
"catName" : {
|
||||
"type" : "text",
|
||||
"analyzer": "ik_smart",
|
||||
"boost": 1.0
|
||||
},
|
||||
|
||||
"lastIndexId" : {
|
||||
"type" : "long"
|
||||
},
|
||||
|
||||
"lastIndexName" : {
|
||||
"type" : "text",
|
||||
"analyzer": "ik_smart",
|
||||
"boost": 0.1
|
||||
},
|
||||
|
||||
"lastIndexUpdateTime" : {
|
||||
"type": "keyword"
|
||||
},
|
||||
|
||||
"picUrl" : {
|
||||
"type" : "keyword"
|
||||
},
|
||||
|
||||
"score" : {
|
||||
"type" : "float"
|
||||
},
|
||||
|
||||
"wordCount" : {
|
||||
"type" : "integer"
|
||||
},
|
||||
|
||||
"workDirection" : {
|
||||
"type" : "short"
|
||||
},
|
||||
|
||||
"visitCount" : {
|
||||
"type": "long"
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
33
doc/sql/20200511.sql
Normal file
33
doc/sql/20200511.sql
Normal file
@ -0,0 +1,33 @@
|
||||
/*
|
||||
Navicat MySQL Data Transfer
|
||||
|
||||
Source Server : localhost
|
||||
Source Server Version : 50725
|
||||
Source Host : localhost:3306
|
||||
Source Database : novel_plus
|
||||
|
||||
Target Server Type : MYSQL
|
||||
Target Server Version : 50725
|
||||
File Encoding : 65001
|
||||
|
||||
Date: 2020-05-11 17:56:23
|
||||
*/
|
||||
|
||||
SET FOREIGN_KEY_CHECKS=0;
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for order_pay
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `order_pay`;
|
||||
CREATE TABLE `order_pay` (
|
||||
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
|
||||
`out_trade_no` bigint(20) NOT NULL COMMENT '商户订单号',
|
||||
`trade_no` varchar(64) DEFAULT NULL COMMENT '支付宝/微信交易号',
|
||||
`pay_channel` tinyint(1) NOT NULL DEFAULT '1' COMMENT '支付渠道,1:支付宝,2:微信',
|
||||
`total_amount` int(11) NOT NULL COMMENT '交易金额(单位元)',
|
||||
`user_id` bigint(20) NOT NULL COMMENT '支付用户ID',
|
||||
`pay_status` tinyint(1) DEFAULT '2' COMMENT '支付状态:0:支付失败,1:支付成功,2:待支付',
|
||||
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
|
||||
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=15 DEFAULT CHARSET=utf8mb4 COMMENT='充值订单';
|
87
doc/sql/20200513.sql
Normal file
87
doc/sql/20200513.sql
Normal file
@ -0,0 +1,87 @@
|
||||
/*
|
||||
Navicat MySQL Data Transfer
|
||||
|
||||
Source Server : localhost
|
||||
Source Server Version : 50624
|
||||
Source Host : localhost:3306
|
||||
Source Database : novel_plus
|
||||
|
||||
Target Server Type : MYSQL
|
||||
Target Server Version : 50624
|
||||
File Encoding : 65001
|
||||
|
||||
Date: 2020-05-13 21:42:20
|
||||
*/
|
||||
|
||||
SET FOREIGN_KEY_CHECKS=0;
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for author
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `author`;
|
||||
CREATE TABLE `author` (
|
||||
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
|
||||
`user_id` bigint(20) DEFAULT NULL COMMENT '用户ID',
|
||||
`invite_code` varchar(20) DEFAULT NULL COMMENT '邀请码',
|
||||
`pen_name` varchar(20) DEFAULT NULL COMMENT '笔名',
|
||||
`tel_phone` varchar(20) DEFAULT NULL COMMENT '手机号码',
|
||||
`chat_account` varchar(50) DEFAULT NULL COMMENT 'QQ或微信账号',
|
||||
`email` varchar(50) DEFAULT NULL COMMENT '电子邮箱',
|
||||
`work_direction` tinyint(4) DEFAULT NULL COMMENT '作品方向,0:男频,1:女频',
|
||||
`status` tinyint(4) DEFAULT '0' COMMENT '0:正常,1:封禁',
|
||||
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COMMENT='作者表';
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of author
|
||||
-- ----------------------------
|
||||
INSERT INTO `author` VALUES ('1', null, 'reerer', 'abc', '13560487656', '23484388', '23484388@qq.com', '0', '0', null);
|
||||
INSERT INTO `author` VALUES ('2', '1255060328322027520', 'rwrr445554', '梦入神机', '13560421324', '1179705413', 'reerer@qq.com', '0', '0', '2020-05-13 14:01:31');
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for author_code
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `author_code`;
|
||||
CREATE TABLE `author_code` (
|
||||
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
|
||||
`invite_code` varchar(100) DEFAULT NULL COMMENT '邀请码',
|
||||
`validity_time` datetime DEFAULT NULL COMMENT '有效时间',
|
||||
`is_use` tinyint(1) DEFAULT '0' COMMENT '是否使用过,0:未使用,1:使用过',
|
||||
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
|
||||
`create_user_id` bigint(20) DEFAULT NULL COMMENT '创建人ID',
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `key_code` (`invite_code`) USING BTREE
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8mb4 COMMENT='作家邀请码表';
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of author_code
|
||||
-- ----------------------------
|
||||
INSERT INTO `author_code` VALUES ('3', 'reerer', '2020-05-27 22:43:45', '1', '2020-05-13 11:40:56', '1');
|
||||
INSERT INTO `author_code` VALUES ('4', '123456', '2020-05-28 00:00:00', '0', '2020-05-13 14:09:55', '1');
|
||||
INSERT INTO `author_code` VALUES ('5', 'ww34343', '2020-05-21 00:00:00', '0', '2020-05-13 14:18:58', '1');
|
||||
|
||||
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for user_buy_record
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `user_buy_record`;
|
||||
CREATE TABLE `user_buy_record` (
|
||||
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
|
||||
`user_id` bigint(20) NOT NULL COMMENT '用户ID',
|
||||
`book_id` bigint(20) DEFAULT NULL COMMENT '购买的小说ID',
|
||||
`book_name` varchar(50) DEFAULT NULL COMMENT '购买的小说名',
|
||||
`book_index_id` bigint(20) DEFAULT NULL COMMENT '购买的章节ID',
|
||||
`book_index_name` varchar(100) DEFAULT NULL COMMENT '购买的章节名',
|
||||
`buy_amount` int(11) DEFAULT NULL COMMENT '购买使用的屋币数量',
|
||||
`create_time` datetime DEFAULT NULL COMMENT '购买时间',
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `key_userId_indexId` (`user_id`,`book_index_id`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COMMENT='用户消费记录表';
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of user_buy_record
|
||||
-- ----------------------------
|
||||
INSERT INTO `user_buy_record` VALUES ('1', '1255060328322027520', '1260400284744613890', '我是一只消消乐2', '1260522024606953472', '第三章', '10', '2020-05-13 21:29:09');
|
||||
INSERT INTO `user_buy_record` VALUES ('2', '1255060328322027520', '1260400284744613890', '我是一只消消乐2', '1260564410687107072', '第四章', '10', '2020-05-13 21:40:38');
|
3
doc/sql/20200518.sql
Normal file
3
doc/sql/20200518.sql
Normal file
@ -0,0 +1,3 @@
|
||||
INSERT INTO `crawl_source` (`id`, `source_name`, `crawl_rule`, `source_status`, `create_time`, `update_time`) VALUES ('4', '书趣阁', '{\r\n \"bookListUrl\": \"http://m.shuquge.com/sort/{catId}/0_{page}.html\",\r\n \"catIdRule\": {\r\n \"catId1\": \"1\",\r\n \"catId2\": \"2\",\r\n \"catId3\": \"3\",\r\n \"catId4\": \"4\",\r\n \"catId5\": \"7\",\r\n \"catId6\": \"6\",\r\n \"catId7\": \"8\"\r\n },\r\n \"bookIdPatten\": \"href=\\\"/s/(\\\\d+)\\\\.html\\\"\",\r\n \"pagePatten\": \"第(\\\\d+)/\\\\d+页\",\r\n \"totalPagePatten\": \"第\\\\d+/(\\\\d+)页\",\r\n \"bookDetailUrl\": \"http://m.shuquge.com/s/{bookId}.html\",\r\n \"bookNamePatten\": \"<a\\\\s+href=\\\"/s/\\\\d+\\\\.html\\\"><h2>([^/]+)</h2></a>\",\r\n \"authorNamePatten\": \"<p>作者:([^/]+)</p>\",\r\n \"picUrlPatten\": \"src=\\\"(http://www.shuquge.com/files/article/image/\\\\d+/\\\\d+/\\\\d+s\\\\.jpg)\\\"\",\r\n \"statusPatten\": \"<p>状态:([^/]+)</p>\",\r\n \"bookStatusRule\": {\r\n \"连载中\": 0,\r\n \"完本\": 1\r\n },\r\n \"descStart\": \"<div class=\\\"intro_info\\\">\",\r\n \"descEnd\": \"最新章节推荐地址\",\r\n \"bookIndexUrl\": \"http://www.shuquge.com/txt/{bookId}/index.html\",\r\n \"bookIndexStart\": \"》正文\",\r\n \"indexIdPatten\": \"<dd><a\\\\s+href=\\\"(\\\\d+)\\\\.html\\\">[^/]+</a></dd>\",\r\n \"indexNamePatten\": \"<dd><a\\\\s+href=\\\"\\\\d+\\\\.html\\\">([^/]+)</a></dd>\",\r\n \"bookContentUrl\": \"http://www.shuquge.com/txt/{bookId}/{indexId}.html\",\r\n \"contentStart\": \"<div id=\\\"content\\\" class=\\\"showtxt\\\">\",\r\n \"contentEnd\": \"http://www.shuquge.com\"\r\n}', '1', '2020-05-18 12:02:34', '2020-05-18 12:02:34');
|
||||
INSERT INTO `crawl_source` (`id`, `source_name`, `crawl_rule`, `source_status`, `create_time`, `update_time`) VALUES ('5', '笔趣阁', '{\"bookListUrl\":\"http://m.mcmssc.com/xclass/{catId}/{page}.html\",\"catIdRule\":{\"catId1\":\"1\",\"catId2\":\"2\",\"catId3\":\"3\",\"catId4\":\"4\",\"catId5\":\"5\",\"catId6\":\"6\",\"catId7\":\"7\"},\"bookIdPatten\":\"href=\\\"/(\\\\d+_\\\\d+)/\\\"\",\"pagePatten\":\"class=\\\"page_txt\\\"\\\\s+value=\\\"(\\\\d+)/\\\\d+\\\"\\\\s+size=\",\"totalPagePatten\":\"class=\\\"page_txt\\\"\\\\s+value=\\\"\\\\d+/(\\\\d+)\\\"\\\\s+size=\",\"bookDetailUrl\":\"http://m.mcmssc.com/{bookId}/\",\"bookNamePatten\":\"<span\\\\s+class=\\\"title\\\">([^/]+)</span>\",\"authorNamePatten\":\"<a\\\\s+href=\\\"/author/\\\\d+/\\\">([^/]+)</a>\",\"picUrlPatten\":\"<img\\\\s+src=\\\"([^>]+)\\\"\\\\s+onerror=\",\"picUrlPrefix\":\"http://m.mcmssc.com/\",\"statusPatten\":\">状态:([^/]+)<\",\"bookStatusRule\":{\"连载\":0,\"全本\":1},\"visitCountPatten\":\">点击:(\\\\d+)<\",\"descStart\":\"<p class=\\\"review\\\">\",\"descEnd\":\"</p>\",\"bookIndexUrl\":\"http://m.mcmssc.com/{bookId}/all.html\",\"indexIdPatten\":\"<a\\\\s+href=\\\"/\\\\d+_\\\\d+/(\\\\d+)\\\\.html\\\">[^/]+</a>\",\"indexNamePatten\":\"<a\\\\s+href=\\\"/\\\\d+_\\\\d+/\\\\d+\\\\.html\\\">([^/]+)</a>\",\"bookContentUrl\":\"http://www.mcmssc.com/{bookId}/{indexId}.html\",\"contentStart\":\"</p>\",\"contentEnd\":\"<div align=\\\"center\\\">\"}', '1', '2020-05-18 15:57:41', '2020-05-18 15:57:41');
|
||||
UPDATE `crawl_source` SET `source_name` = '书趣阁', `crawl_rule` = '{\n \"bookListUrl\": \"http://m.shuquge.com/sort/{catId}/0_{page}.html\",\n \"catIdRule\": {\n \"catId1\": \"1\",\n \"catId2\": \"2\",\n \"catId3\": \"3\",\n \"catId4\": \"4\",\n \"catId5\": \"7\",\n \"catId6\": \"6\",\n \"catId7\": \"8\"\n },\n \"bookIdPatten\": \"href=\\\"/s/(\\\\d+)\\\\.html\\\"\",\n \"pagePatten\": \"第(\\\\d+)/\\\\d+页\",\n \"totalPagePatten\": \"第\\\\d+/(\\\\d+)页\",\n \"bookDetailUrl\": \"http://m.shuquge.com/s/{bookId}.html\",\n \"bookNamePatten\": \"<a\\\\s+href=\\\"/s/\\\\d+\\\\.html\\\"><h2>([^/]+)</h2></a>\",\n \"authorNamePatten\": \"<p>作者:([^/]+)</p>\",\n \"picUrlPatten\": \"src=\\\"(http://www.shuquge.com/files/article/image/\\\\d+/\\\\d+/\\\\d+s\\\\.jpg)\\\"\",\n \"statusPatten\": \"<p>状态:([^/]+)</p>\",\n \"bookStatusRule\": {\n \"连载中\": 0,\n \"完本\": 1\n },\n \"descStart\": \"<div class=\\\"intro_info\\\">\",\n \"descEnd\": \"最新章节推荐地址\",\n \"bookIndexUrl\": \"http://www.shuquge.com/txt/{bookId}/index.html\",\n \"bookIndexStart\": \"<dt>《\",\n \"indexIdPatten\": \"<dd><a\\\\s+href=\\\"(\\\\d+)\\\\.html\\\">[^/]+</a></dd>\",\n \"indexNamePatten\": \"<dd><a\\\\s+href=\\\"\\\\d+\\\\.html\\\">([^/]+)</a></dd>\",\n \"bookContentUrl\": \"http://www.shuquge.com/txt/{bookId}/{indexId}.html\",\n \"contentStart\": \"<div id=\\\"content\\\" class=\\\"showtxt\\\">\",\n \"contentEnd\": \"http://www.shuquge.com\"\n}', `source_status` = 1, `create_time` = '2020-05-18 12:02:34', `update_time` = '2020-05-18 12:02:34' WHERE `id` = 4;
|
2
doc/sql/20200608.sql
Normal file
2
doc/sql/20200608.sql
Normal file
@ -0,0 +1,2 @@
|
||||
INSERT INTO `crawl_source` (`id`, `source_name`, `crawl_rule`, `source_status`, `create_time`, `update_time`) VALUES
|
||||
(6, '新笔趣阁', '{\n \"bookListUrl\": \"http://www.xbiquge.la/fenlei/{catId}_{page}.html\",\n \"catIdRule\": {\n \"catId1\": \"1\",\n \"catId2\": \"2\",\n \"catId3\": \"3\",\n \"catId4\": \"4\",\n \"catId5\": \"6\",\n \"catId6\": \"5\"\n },\n \"bookIdPatten\": \"<a\\\\s+href=\\\"http://www.xbiquge.la/(\\\\d+/\\\\d+)/\\\"\\\\s+target=\\\"_blank\\\">\",\n \"pagePatten\": \"<em\\\\s+id=\\\"pagestats\\\">(\\\\d+)/\\\\d+</em>\",\n \"totalPagePatten\": \"<em\\\\s+id=\\\"pagestats\\\">\\\\d+/(\\\\d+)</em>\",\n \"bookDetailUrl\": \"http://www.xbiquge.la/{bookId}/\",\n \"bookNamePatten\": \"<h1>([^/]+)</h1>\",\n \"authorNamePatten\": \"者:([^/]+)</p>\",\n \"picUrlPatten\": \"src=\\\"(http://www.xbiquge.la/files/article/image/\\\\d+/\\\\d+/\\\\d+s\\\\.jpg)\\\"\",\n \"bookStatusRule\": {},\n \"descStart\": \"<div id=\\\"intro\\\">\",\n \"descEnd\": \"</div>\",\n \"upadateTimePatten\": \"<p>最后更新:(\\\\d+-\\\\d+-\\\\d+\\\\s\\\\d+:\\\\d+:\\\\d+)</p>\",\n \"upadateTimeFormatPatten\": \"yyyy-MM-dd HH:mm:ss\",\n \"bookIndexUrl\": \"http://www.xbiquge.la/{bookId}/\",\n \"indexIdPatten\": \"<a\\\\s+href=\'/\\\\d+/\\\\d+/(\\\\d+)\\\\.html\'\\\\s+>[^/]+</a>\",\n \"indexNamePatten\": \"<a\\\\s+href=\'/\\\\d+/\\\\d+/\\\\d+\\\\.html\'\\\\s+>([^/]+)</a>\",\n \"bookContentUrl\": \"http://www.xbiquge.la/{bookId}/{indexId}.html\",\n \"contentStart\": \"<div id=\\\"content\\\">\",\n \"contentEnd\": \"<p>\"\n}', 0, '2020-05-23 22:46:58', '2020-05-23 22:46:58');
|
40
doc/sql/20200615.sql
Normal file
40
doc/sql/20200615.sql
Normal file
@ -0,0 +1,40 @@
|
||||
/*
|
||||
Navicat MySQL Data Transfer
|
||||
|
||||
Source Server : localhost
|
||||
Source Server Version : 50725
|
||||
Source Host : localhost:3306
|
||||
Source Database : novel_plus
|
||||
|
||||
Target Server Type : MYSQL
|
||||
Target Server Version : 50725
|
||||
File Encoding : 65001
|
||||
|
||||
Date: 2020-06-15 15:06:55
|
||||
*/
|
||||
|
||||
SET FOREIGN_KEY_CHECKS=0;
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for crawl_single_task
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `crawl_single_task`;
|
||||
CREATE TABLE `crawl_single_task` (
|
||||
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
|
||||
`source_id` int(11) DEFAULT NULL COMMENT '爬虫源ID',
|
||||
`source_name` varchar(50) DEFAULT NULL COMMENT '爬虫源名',
|
||||
`source_book_id` varchar(255) DEFAULT NULL COMMENT '源站小说ID',
|
||||
`cat_id` int(11) DEFAULT NULL COMMENT '分类ID',
|
||||
`book_name` varchar(50) DEFAULT NULL COMMENT '爬取的小说名',
|
||||
`author_name` varchar(50) DEFAULT NULL COMMENT '爬取的小说作者名',
|
||||
`task_status` tinyint(1) DEFAULT '2' COMMENT '任务状态,0:失败,1:成功,2;未执行',
|
||||
`exc_count` tinyint(2) DEFAULT '0' COMMENT '已经执行次数,最多执行5次',
|
||||
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8mb4 COMMENT='抓取单本小说任务表';
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of crawl_single_task
|
||||
-- ----------------------------
|
||||
INSERT INTO `crawl_single_task` VALUES ('6', '2', '百书斋', '1', '1', '1', '1', '0', '5', '2020-06-15 14:36:07');
|
||||
INSERT INTO `crawl_single_task` VALUES ('7', '5', '笔趣阁', '108_108291', '1', '衍天志之不朽仙', '白衣少年丶', '1', '1', '2020-06-15 14:46:08');
|
27
doc/sql/20201103.sql
Normal file
27
doc/sql/20201103.sql
Normal file
@ -0,0 +1,27 @@
|
||||
CREATE TABLE `author_income_detail` (
|
||||
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
|
||||
`user_id` bigint(20) NOT NULL COMMENT '用户ID',
|
||||
`author_id` bigint(20) NOT NULL COMMENT '作家ID',
|
||||
`book_id` bigint(20) NOT NULL DEFAULT '0' COMMENT '作品ID,0表示全部作品',
|
||||
`income_date` date NOT NULL COMMENT '收入日期',
|
||||
`income_account` int(11) NOT NULL DEFAULT '0' COMMENT '订阅总额',
|
||||
`income_count` int(11) NOT NULL DEFAULT '0' COMMENT '订阅次数',
|
||||
`income_number` int(11) NOT NULL DEFAULT '0' COMMENT '订阅人数',
|
||||
`create_time` datetime DEFAULT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='稿费收入明细统计表';
|
||||
|
||||
CREATE TABLE `author_income` (
|
||||
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
|
||||
`user_id` bigint(20) NOT NULL COMMENT '用户ID',
|
||||
`author_id` bigint(20) NOT NULL COMMENT '作家ID',
|
||||
`book_id` bigint(20) NOT NULL COMMENT '作品ID',
|
||||
`income_month` date NOT NULL COMMENT '收入月份',
|
||||
`pre_tax_income` bigint(20) NOT NULL DEFAULT '0' COMMENT '税前收入(分)',
|
||||
`after_tax_income` bigint(20) NOT NULL DEFAULT '0' COMMENT '税后收入(分)',
|
||||
`pay_status` tinyint(1) NOT NULL DEFAULT '0' COMMENT '支付状态,0:待支付,1:已支付',
|
||||
`confirm_status` tinyint(1) NOT NULL DEFAULT '0' COMMENT '稿费确认状态,0:待确认,1:已确认',
|
||||
`detail` varchar(255) DEFAULT NULL COMMENT '详情',
|
||||
`create_time` datetime DEFAULT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='稿费收入统计表';
|
1
doc/sql/20201109.sql
Normal file
1
doc/sql/20201109.sql
Normal file
@ -0,0 +1 @@
|
||||
alter table book add column `yesterday_buy` int(11) DEFAULT '0' COMMENT '昨日订阅数' after comment_count;
|
1
doc/sql/20201122.sql
Normal file
1
doc/sql/20201122.sql
Normal file
@ -0,0 +1 @@
|
||||
alter table book_index add column `book_price` int(3) DEFAULT 0 COMMENT '章节费用(屋币)' after `is_vip`;
|
32
doc/sql/20201201.sql
Normal file
32
doc/sql/20201201.sql
Normal file
@ -0,0 +1,32 @@
|
||||
INSERT INTO `sys_menu`(`menu_id`, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`, `gmt_create`, `gmt_modified`) VALUES (246, 241, '批量删除', NULL, 'novel:news:batchRemove', 2, NULL, 6, NULL, NULL);
|
||||
INSERT INTO `sys_menu`(`menu_id`, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`, `gmt_create`, `gmt_modified`) VALUES (245, 241, '删除', NULL, 'novel:news:remove', 2, NULL, 6, NULL, NULL);
|
||||
INSERT INTO `sys_menu`(`menu_id`, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`, `gmt_create`, `gmt_modified`) VALUES (244, 241, '修改', NULL, 'novel:news:edit', 2, NULL, 6, NULL, NULL);
|
||||
INSERT INTO `sys_menu`(`menu_id`, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`, `gmt_create`, `gmt_modified`) VALUES (243, 241, '新增', NULL, 'novel:news:add', 2, NULL, 6, NULL, NULL);
|
||||
INSERT INTO `sys_menu`(`menu_id`, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`, `gmt_create`, `gmt_modified`) VALUES (242, 241, '查看', NULL, 'novel:news:detail', 2, NULL, 6, NULL, NULL);
|
||||
INSERT INTO `sys_menu`(`menu_id`, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`, `gmt_create`, `gmt_modified`) VALUES (241, 234, '新闻列表', 'novel/news', 'novel:news:news', 1, 'fa', 8, NULL, NULL);
|
||||
INSERT INTO `sys_menu`(`menu_id`, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`, `gmt_create`, `gmt_modified`) VALUES (240, 235, '批量删除', NULL, 'novel:category:batchRemove', 2, NULL, 6, NULL, NULL);
|
||||
INSERT INTO `sys_menu`(`menu_id`, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`, `gmt_create`, `gmt_modified`) VALUES (239, 235, '删除', NULL, 'novel:category:remove', 2, NULL, 6, NULL, NULL);
|
||||
INSERT INTO `sys_menu`(`menu_id`, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`, `gmt_create`, `gmt_modified`) VALUES (238, 235, '修改', NULL, 'novel:category:edit', 2, NULL, 6, NULL, NULL);
|
||||
INSERT INTO `sys_menu`(`menu_id`, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`, `gmt_create`, `gmt_modified`) VALUES (237, 235, '新增', NULL, 'novel:category:add', 2, NULL, 6, NULL, NULL);
|
||||
INSERT INTO `sys_menu`(`menu_id`, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`, `gmt_create`, `gmt_modified`) VALUES (236, 235, '查看', NULL, 'novel:category:detail', 2, NULL, 6, NULL, NULL);
|
||||
INSERT INTO `sys_menu`(`menu_id`, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`, `gmt_create`, `gmt_modified`) VALUES (235, 234, '类别管理', 'novel/category', 'novel:category:category', 1, 'fa', 6, NULL, NULL);
|
||||
INSERT INTO `sys_menu`(`menu_id`, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`, `gmt_create`, `gmt_modified`) VALUES (234, 0, '新闻管理', '', '', 0, 'fa fa-newspaper-o', 8, NULL, NULL);
|
||||
|
||||
|
||||
|
||||
INSERT INTO `sys_role_menu`(`id`, `role_id`, `menu_id`) VALUES (4889, 1, 246);
|
||||
INSERT INTO `sys_role_menu`(`id`, `role_id`, `menu_id`) VALUES (4890, 1, 245);
|
||||
INSERT INTO `sys_role_menu`(`id`, `role_id`, `menu_id`) VALUES (4891, 1, 244);
|
||||
INSERT INTO `sys_role_menu`(`id`, `role_id`, `menu_id`) VALUES (4892, 1, 243);
|
||||
INSERT INTO `sys_role_menu`(`id`, `role_id`, `menu_id`) VALUES (4893, 1, 242);
|
||||
INSERT INTO `sys_role_menu`(`id`, `role_id`, `menu_id`) VALUES (4899, 1, 241);
|
||||
INSERT INTO `sys_role_menu`(`id`, `role_id`, `menu_id`) VALUES (4894, 1, 240);
|
||||
INSERT INTO `sys_role_menu`(`id`, `role_id`, `menu_id`) VALUES (4895, 1, 239);
|
||||
INSERT INTO `sys_role_menu`(`id`, `role_id`, `menu_id`) VALUES (4896, 1, 238);
|
||||
INSERT INTO `sys_role_menu`(`id`, `role_id`, `menu_id`) VALUES (4897, 1, 237);
|
||||
INSERT INTO `sys_role_menu`(`id`, `role_id`, `menu_id`) VALUES (4898, 1, 236);
|
||||
INSERT INTO `sys_role_menu`(`id`, `role_id`, `menu_id`) VALUES (4900, 1, 235);
|
||||
INSERT INTO `sys_role_menu`(`id`, `role_id`, `menu_id`) VALUES (4888, 1, 234);
|
||||
|
||||
|
||||
delete from sys_menu where menu_id = 202;
|
1
doc/sql/20210726.sql
Normal file
1
doc/sql/20210726.sql
Normal file
@ -0,0 +1 @@
|
||||
alter table news add column `read_count` BIGINT NOT NULL DEFAULT '0' COMMENT '阅读量' after content;
|
@ -2,19 +2,65 @@
|
||||
Navicat MySQL Data Transfer
|
||||
|
||||
Source Server : localhost
|
||||
Source Server Version : 50624
|
||||
Source Server Version : 50725
|
||||
Source Host : localhost:3306
|
||||
Source Database : novel_biz
|
||||
Source Database : novel_plus
|
||||
|
||||
Target Server Type : MYSQL
|
||||
Target Server Version : 50624
|
||||
Target Server Version : 50725
|
||||
File Encoding : 65001
|
||||
|
||||
Date: 2020-05-02 10:53:04
|
||||
Date: 2020-05-18 13:59:04
|
||||
*/
|
||||
|
||||
SET FOREIGN_KEY_CHECKS=0;
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for author
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `author`;
|
||||
CREATE TABLE `author` (
|
||||
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
|
||||
`user_id` bigint(20) DEFAULT NULL COMMENT '用户ID',
|
||||
`invite_code` varchar(20) DEFAULT NULL COMMENT '邀请码',
|
||||
`pen_name` varchar(20) DEFAULT NULL COMMENT '笔名',
|
||||
`tel_phone` varchar(20) DEFAULT NULL COMMENT '手机号码',
|
||||
`chat_account` varchar(50) DEFAULT NULL COMMENT 'QQ或微信账号',
|
||||
`email` varchar(50) DEFAULT NULL COMMENT '电子邮箱',
|
||||
`work_direction` tinyint(4) DEFAULT NULL COMMENT '作品方向,0:男频,1:女频',
|
||||
`status` tinyint(4) DEFAULT '0' COMMENT '0:正常,1:封禁',
|
||||
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COMMENT='作者表';
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of author
|
||||
-- ----------------------------
|
||||
INSERT INTO `author` VALUES ('1', null, 'reerer', 'abc', '13560487656', '23484388', '23484388@qq.com', '0', '0', null);
|
||||
INSERT INTO `author` VALUES ('2', '1255060328322027520', 'rwrr445554', '梦入神机', '13560421324', '1179705413', 'reerer@qq.com', '0', '0', '2020-05-13 14:01:31');
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for author_code
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `author_code`;
|
||||
CREATE TABLE `author_code` (
|
||||
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
|
||||
`invite_code` varchar(100) DEFAULT NULL COMMENT '邀请码',
|
||||
`validity_time` datetime DEFAULT NULL COMMENT '有效时间',
|
||||
`is_use` tinyint(1) DEFAULT '0' COMMENT '是否使用过,0:未使用,1:使用过',
|
||||
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
|
||||
`create_user_id` bigint(20) DEFAULT NULL COMMENT '创建人ID',
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `key_code` (`invite_code`) USING BTREE
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8mb4 COMMENT='作家邀请码表';
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of author_code
|
||||
-- ----------------------------
|
||||
INSERT INTO `author_code` VALUES ('3', 'reerer', '2020-05-27 22:43:45', '1', '2020-05-13 11:40:56', '1');
|
||||
INSERT INTO `author_code` VALUES ('4', '123456', '2020-05-28 00:00:00', '0', '2020-05-13 14:09:55', '1');
|
||||
INSERT INTO `author_code` VALUES ('5', 'ww34343', '2020-05-21 00:00:00', '0', '2020-05-13 14:18:58', '1');
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for book
|
||||
-- ----------------------------
|
||||
@ -49,7 +95,7 @@ CREATE TABLE `book` (
|
||||
UNIQUE KEY `key_uq_bookName_authorName` (`book_name`,`author_name`) USING BTREE,
|
||||
KEY `key_lastIndexUpdateTime` (`last_index_update_time`) USING BTREE,
|
||||
KEY `key_createTime` (`create_time`) USING BTREE
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=1256127379949019137 DEFAULT CHARSET=utf8mb4 COMMENT='小说表';
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=1262260513468559361 DEFAULT CHARSET=utf8mb4 COMMENT='小说表';
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of book
|
||||
@ -156,7 +202,7 @@ CREATE TABLE `book_content` (
|
||||
`content` mediumtext COMMENT '小说章节内容',
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `key_uq_indexId` (`index_id`) USING BTREE
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=3342428 DEFAULT CHARSET=utf8mb4 COMMENT='小说内容表';
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=3347665 DEFAULT CHARSET=utf8mb4 COMMENT='小说内容表';
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of book_content
|
||||
@ -179,7 +225,7 @@ CREATE TABLE `book_index` (
|
||||
UNIQUE KEY `key_uq_bookId_indexNum` (`book_id`,`index_num`) USING BTREE,
|
||||
KEY `key_bookId` (`book_id`) USING BTREE,
|
||||
KEY `key_indexNum` (`index_num`) USING BTREE
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=1256373101432717313 DEFAULT CHARSET=utf8mb4 COMMENT='小说目录表';
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=1262260612777095169 DEFAULT CHARSET=utf8mb4 COMMENT='小说目录表';
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of book_index
|
||||
@ -303,13 +349,15 @@ CREATE TABLE `crawl_source` (
|
||||
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
|
||||
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COMMENT='爬虫源表';
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4 COMMENT='爬虫源表';
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of crawl_source
|
||||
-- ----------------------------
|
||||
INSERT INTO `crawl_source` VALUES ('2', '百书斋', '{\r\n \"bookListUrl\": \"https://m.baishuzhai.com/blhb/{catId}/{page}.html\",\r\n \"catIdRule\": {\r\n \"catId1\": \"1\",\r\n \"catId2\": \"2\",\r\n \"catId3\": \"3\",\r\n \"catId4\": \"4\",\r\n \"catId5\": \"5\",\r\n \"catId6\": \"6\",\r\n \"catId7\": \"7\"\r\n },\r\n \"bookIdPatten\": \"href=\\\"/ibook/(\\\\d+/\\\\d+)/\\\"\",\r\n \"pagePatten\": \"value=\\\"(\\\\d+)/\\\\d+\\\"\",\r\n \"totalPagePatten\": \"value=\\\"\\\\d+/(\\\\d+)\\\"\",\r\n \"bookDetailUrl\": \"https://m.baishuzhai.com/ibook/{bookId}/\",\r\n \"bookNamePatten\": \"<span class=\\\"title\\\">([^/]+)</span>\",\r\n \"authorNamePatten\": \">作者:([^/]+)<\",\r\n \"picUrlPatten\": \"<img src=\\\"([^>]+)\\\"\\\\s+onerror=\\\"this.src=\",\r\n \"statusPatten\": \"状态:([^/]+)</li>\",\r\n \"bookStatusRule\": {\r\n \"连载\": 0,\r\n \"完成\": 1\r\n },\r\n \"scorePatten\": \"<em>([^<]+)</em>\",\r\n \"descStart\": \"<p class=\\\"review\\\">\",\r\n \"descEnd\": \"</p>\",\r\n \"upadateTimePatten\": \"更新:(\\\\d+-\\\\d+-\\\\d+)</li>\",\r\n \"upadateTimeFormatPatten\": \"yy-MM-dd\",\r\n \"bookIndexUrl\": \"https://m.baishuzhai.com/ibook/{bookId}/all.html\",\r\n \"indexIdPatten\": \"<a\\\\s+style=\\\"\\\"\\\\s+href=\\\"/ibook/\\\\d+/\\\\d+/(\\\\d+)\\\\.html\\\">[^/]+</a>\",\r\n \"indexNamePatten\": \"<a\\\\s+style=\\\"\\\"\\\\s+href=\\\"/ibook/\\\\d+/\\\\d+/\\\\d+\\\\.html\\\">([^/]+)</a>\",\r\n \"bookContentUrl\": \"https://baishuzhai.com/ibook/{bookId}/{indexId}.html\",\r\n \"contentStart\": \"id=\\\"content\\\">\",\r\n \"contentEnd\": \"<script>\"\r\n}', '0', '2020-05-01 14:22:50', '2020-05-01 14:22:50');
|
||||
INSERT INTO `crawl_source` VALUES ('3', '书包网', '{\r\n \"bookListUrl\": \"https://www.bookbao8.com/booklist-p_{page}-c_{catId}-t_0-o_0.html\",\r\n \"catIdRule\": {\r\n \"catId1\": \"5\",\r\n \"catId2\": \"4\",\r\n \"catId3\": \"8\",\r\n \"catId4\": \"9\",\r\n \"catId5\": \"3\",\r\n \"catId6\": \"7\"\r\n },\r\n \"bookIdPatten\": \"href=\\\"/book/(\\\\d+/\\\\d+/id_[^.]+).html\\\"\",\r\n \"pagePatten\": \"<span\\\\s+class=\\\"current\\\">([^<]+)</span>\",\r\n \"totalPagePatten\": \"/共(\\\\d+)页\",\r\n \"bookDetailUrl\": \"https://www.bookbao8.com/book/{bookId}.html\",\r\n \"bookNamePatten\": \"<div\\\\s+id=\\\"info\\\">\\\\s*<h1>([^<]+)</h1>\",\r\n \"authorNamePatten\": \"<p>作者:<a\\\\s+href=\\\"/Search/[^\\\"]+\\\"\\\\s+target=\\\"_blank\\\">([^<]+)</a></p>\",\r\n \"picUrlPatten\": \"<div\\\\s+id=\\\"fmimg\\\">\\\\s*<img\\\\s+alt=\\\"[^\\\"]+\\\"\\\\s+src=\\\"([^\\\"]+)\\\"\",\r\n \"statusPatten\": \"<p>状态:([^<]+)</p>\",\r\n \"bookStatusRule\": {\r\n \"连载中\": 0,\r\n \"已完结\": 1\r\n },\r\n \"visitCountPatten\": \"<em\\\\s+id=\\\"hits\\\">(\\\\d+)</em>\",\r\n \"descStart\": \"<div class=\\\"infocontent\\\">\",\r\n \"descEnd\": \"</div>\",\r\n \"upadateTimePatten\": \"<p>更新时间:(\\\\d+-\\\\d+-\\\\d+\\\\s\\\\d+:\\\\d+:\\\\d+)</p>\",\r\n \"upadateTimeFormatPatten\": \"yyyy-MM-dd HH:mm:ss\",\r\n \"bookIndexUrl\": \"https://www.bookbao8.com/book/{bookId}.html\",\r\n \"indexIdPatten\": \"<li>\\\\s*<a\\\\s+href=\\\"/views/\\\\d+/\\\\d+/id_[^_]+_(\\\\d+).html\\\"\\\\s+target=\\\"_blank\\\">\",\r\n \"indexNamePatten\": \"<li>\\\\s*<a\\\\s+href=\\\"/views/\\\\d+/\\\\d+/id_[^_]+_\\\\d+.html\\\"\\\\s+target=\\\"_blank\\\">([^<]+)</a>\",\r\n \"bookContentUrl\": \"https://www.bookbao8.com/views/{bookId}_{indexId}.html\",\r\n \"contentStart\": \"<dd id=\\\"contents\\\">\",\r\n \"contentEnd\": \"</dd>\"\r\n}', '0', '2020-05-04 17:42:22', '2020-05-04 17:42:22');
|
||||
INSERT INTO `crawl_source` VALUES ('4', '书趣阁', '{\r\n \"bookListUrl\": \"http://m.shuquge.com/sort/{catId}/0_{page}.html\",\r\n \"catIdRule\": {\r\n \"catId1\": \"1\",\r\n \"catId2\": \"2\",\r\n \"catId3\": \"3\",\r\n \"catId4\": \"4\",\r\n \"catId5\": \"7\",\r\n \"catId6\": \"6\",\r\n \"catId7\": \"8\"\r\n },\r\n \"bookIdPatten\": \"href=\\\"/s/(\\\\d+)\\\\.html\\\"\",\r\n \"pagePatten\": \"第(\\\\d+)/\\\\d+页\",\r\n \"totalPagePatten\": \"第\\\\d+/(\\\\d+)页\",\r\n \"bookDetailUrl\": \"http://m.shuquge.com/s/{bookId}.html\",\r\n \"bookNamePatten\": \"<a\\\\s+href=\\\"/s/\\\\d+\\\\.html\\\"><h2>([^/]+)</h2></a>\",\r\n \"authorNamePatten\": \"<p>作者:([^/]+)</p>\",\r\n \"picUrlPatten\": \"src=\\\"(http://www.shuquge.com/files/article/image/\\\\d+/\\\\d+/\\\\d+s\\\\.jpg)\\\"\",\r\n \"statusPatten\": \"<p>状态:([^/]+)</p>\",\r\n \"bookStatusRule\": {\r\n \"连载中\": 0,\r\n \"完本\": 1\r\n },\r\n \"descStart\": \"<div class=\\\"intro_info\\\">\",\r\n \"descEnd\": \"最新章节推荐地址\",\r\n \"bookIndexUrl\": \"http://www.shuquge.com/txt/{bookId}/index.html\",\r\n \"bookIndexStart\": \"》正文\",\r\n \"indexIdPatten\": \"<dd><a\\\\s+href=\\\"(\\\\d+)\\\\.html\\\">[^/]+</a></dd>\",\r\n \"indexNamePatten\": \"<dd><a\\\\s+href=\\\"\\\\d+\\\\.html\\\">([^/]+)</a></dd>\",\r\n \"bookContentUrl\": \"http://www.shuquge.com/txt/{bookId}/{indexId}.html\",\r\n \"contentStart\": \"<div id=\\\"content\\\" class=\\\"showtxt\\\">\",\r\n \"contentEnd\": \"http://www.shuquge.com\"\r\n}', '1', '2020-05-18 12:02:34', '2020-05-18 12:02:34');
|
||||
INSERT INTO `crawl_source` (`id`, `source_name`, `crawl_rule`, `source_status`, `create_time`, `update_time`) VALUES ('5', '笔趣阁', '{\"bookListUrl\":\"http://m.mcmssc.com/xclass/{catId}/{page}.html\",\"catIdRule\":{\"catId1\":\"1\",\"catId2\":\"2\",\"catId3\":\"3\",\"catId4\":\"4\",\"catId5\":\"5\",\"catId6\":\"6\",\"catId7\":\"7\"},\"bookIdPatten\":\"href=\\\"/(\\\\d+_\\\\d+)/\\\"\",\"pagePatten\":\"class=\\\"page_txt\\\"\\\\s+value=\\\"(\\\\d+)/\\\\d+\\\"\\\\s+size=\",\"totalPagePatten\":\"class=\\\"page_txt\\\"\\\\s+value=\\\"\\\\d+/(\\\\d+)\\\"\\\\s+size=\",\"bookDetailUrl\":\"http://m.mcmssc.com/{bookId}/\",\"bookNamePatten\":\"<span\\\\s+class=\\\"title\\\">([^/]+)</span>\",\"authorNamePatten\":\"<a\\\\s+href=\\\"/author/\\\\d+/\\\">([^/]+)</a>\",\"picUrlPatten\":\"<img\\\\s+src=\\\"([^>]+)\\\"\\\\s+onerror=\",\"picUrlPrefix\":\"http://m.mcmssc.com/\",\"statusPatten\":\">状态:([^/]+)<\",\"bookStatusRule\":{\"连载\":0,\"全本\":1},\"visitCountPatten\":\">点击:(\\\\d+)<\",\"descStart\":\"<p class=\\\"review\\\">\",\"descEnd\":\"</p>\",\"bookIndexUrl\":\"http://m.mcmssc.com/{bookId}/all.html\",\"indexIdPatten\":\"<a\\\\s+href=\\\"/\\\\d+_\\\\d+/(\\\\d+)\\\\.html\\\">[^/]+</a>\",\"indexNamePatten\":\"<a\\\\s+href=\\\"/\\\\d+_\\\\d+/\\\\d+\\\\.html\\\">([^/]+)</a>\",\"bookContentUrl\":\"http://www.mcmssc.com/{bookId}/{indexId}.html\",\"contentStart\":\"</p>\",\"contentEnd\":\"<div align=\\\"center\\\">\"}', '1', '2020-05-18 15:57:41', '2020-05-18 15:57:41');
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for friend_link
|
||||
@ -378,6 +426,27 @@ CREATE TABLE `news_category` (
|
||||
INSERT INTO `news_category` VALUES ('1', '招募', '10', null, null, null, null);
|
||||
INSERT INTO `news_category` VALUES ('3', '公告', '11', null, null, null, null);
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for order_pay
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `order_pay`;
|
||||
CREATE TABLE `order_pay` (
|
||||
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
|
||||
`out_trade_no` bigint(20) NOT NULL COMMENT '商户订单号',
|
||||
`trade_no` varchar(64) DEFAULT NULL COMMENT '支付宝/微信交易号',
|
||||
`pay_channel` tinyint(1) NOT NULL DEFAULT '1' COMMENT '支付渠道,1:支付宝,2:微信',
|
||||
`total_amount` int(11) NOT NULL COMMENT '交易金额(单位元)',
|
||||
`user_id` bigint(20) NOT NULL COMMENT '支付用户ID',
|
||||
`pay_status` tinyint(1) DEFAULT '2' COMMENT '支付状态:0:支付失败,1:支付成功,2:待支付',
|
||||
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
|
||||
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=15 DEFAULT CHARSET=utf8mb4 COMMENT='充值订单';
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of order_pay
|
||||
-- ----------------------------
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for sys_data_perm
|
||||
-- ----------------------------
|
||||
@ -422,13 +491,6 @@ CREATE TABLE `sys_dept` (
|
||||
-- ----------------------------
|
||||
-- Records of sys_dept
|
||||
-- ----------------------------
|
||||
INSERT INTO `sys_dept` VALUES ('6', '0', '研发部', '1', '1');
|
||||
INSERT INTO `sys_dept` VALUES ('7', '6', '研發一部', '1', '1');
|
||||
INSERT INTO `sys_dept` VALUES ('8', '6', '研发二部', '2', '1');
|
||||
INSERT INTO `sys_dept` VALUES ('9', '0', '销售部', '2', '1');
|
||||
INSERT INTO `sys_dept` VALUES ('10', '9', '销售一部', '1', '1');
|
||||
INSERT INTO `sys_dept` VALUES ('11', '0', '产品部', '3', '1');
|
||||
INSERT INTO `sys_dept` VALUES ('12', '11', '产品一部', '1', '1');
|
||||
INSERT INTO `sys_dept` VALUES ('13', '0', '测试部', '5', '1');
|
||||
INSERT INTO `sys_dept` VALUES ('14', '13', '测试一部', '1', '1');
|
||||
INSERT INTO `sys_dept` VALUES ('15', '13', '测试二部', '2', '1');
|
||||
@ -456,7 +518,7 @@ CREATE TABLE `sys_dict` (
|
||||
KEY `sys_dict_value` (`value`),
|
||||
KEY `sys_dict_label` (`name`),
|
||||
KEY `sys_dict_del_flag` (`del_flag`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=140 DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='字典表';
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=142 DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='字典表';
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of sys_dict
|
||||
@ -589,6 +651,8 @@ INSERT INTO `sys_dict` VALUES ('136', '富文本', '6', 'page_type', '页面显
|
||||
INSERT INTO `sys_dict` VALUES ('137', '上传图片【单文件】', '7', 'page_type', '页面显示类型', '7', null, null, null, null, null, '', null);
|
||||
INSERT INTO `sys_dict` VALUES ('138', '隐藏域', '11', 'page_type', '页面显示类型', '11', null, null, null, null, null, '', null);
|
||||
INSERT INTO `sys_dict` VALUES ('139', '不显示', '12', 'page_type', '页面显示类型', '12', null, null, null, null, null, '', null);
|
||||
INSERT INTO `sys_dict` VALUES ('140', '男频', '0', 'work_direction', '作品方向', '0', null, null, null, null, null, '', null);
|
||||
INSERT INTO `sys_dict` VALUES ('141', '女频', '1', 'work_direction', '作品方向', '1', null, null, null, null, null, '', null);
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for sys_file
|
||||
@ -664,7 +728,7 @@ CREATE TABLE `sys_gen_columns` (
|
||||
`is_required` tinyint(1) DEFAULT NULL COMMENT '是否必填',
|
||||
`dict_type` varchar(100) CHARACTER SET utf8 DEFAULT '' COMMENT '页面显示为下拉时使用,字典类型从字典表中取出',
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=801 DEFAULT CHARSET=utf8mb4;
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=815 DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of sys_gen_columns
|
||||
@ -728,6 +792,20 @@ INSERT INTO `sys_gen_columns` VALUES ('797', 'fb_order', 'push_time', 'datetime'
|
||||
INSERT INTO `sys_gen_columns` VALUES ('798', 'fb_order', 'push_ip', 'varchar', 'String', '推送IP', '31', '推送IP', '6', '0', 'del_flag');
|
||||
INSERT INTO `sys_gen_columns` VALUES ('799', 'fb_order', 'mcht_id', 'bigint', 'BigDecimal', '商户id', '90', '商户id', '3', '0', 'theme');
|
||||
INSERT INTO `sys_gen_columns` VALUES ('800', 'fb_order', 'sn', 'char', 'String', 'QR编号', '100', 'QR编号', '1', '0', 'del_flag');
|
||||
INSERT INTO `sys_gen_columns` VALUES ('801', 'author', 'user_id', 'bigint', 'Long', '用户ID', '2', '用户ID', '1', '0', null);
|
||||
INSERT INTO `sys_gen_columns` VALUES ('802', 'author', 'invite_code', 'varchar', 'String', '邀请码', '3', '邀请码', '1', '0', null);
|
||||
INSERT INTO `sys_gen_columns` VALUES ('803', 'author', 'pen_name', 'varchar', 'String', '笔名', '4', '笔名', '1', '0', null);
|
||||
INSERT INTO `sys_gen_columns` VALUES ('804', 'author', 'tel_phone', 'varchar', 'String', '手机号码', '5', '手机号码', '1', '0', null);
|
||||
INSERT INTO `sys_gen_columns` VALUES ('805', 'author', 'chat_account', 'varchar', 'String', 'QQ或微信账号', '6', 'QQ或微信账号', '1', '0', null);
|
||||
INSERT INTO `sys_gen_columns` VALUES ('806', 'author', 'email', 'varchar', 'String', '电子邮箱', '7', '电子邮箱', '1', '0', null);
|
||||
INSERT INTO `sys_gen_columns` VALUES ('807', 'author', 'work_direction', 'tinyint', 'Integer', '作品方向,0:男频,1:女频', '8', '作品方向,0:男频,1:女频', '2', '0', 'work_direction');
|
||||
INSERT INTO `sys_gen_columns` VALUES ('808', 'author', 'status', 'tinyint', 'Integer', '0:正常,1:封禁', '10', '0:正常,1:封禁', '1', '0', null);
|
||||
INSERT INTO `sys_gen_columns` VALUES ('809', 'author', 'create_time', 'datetime', 'Date', '创建时间', '9', '入驻时间', '4', '0', null);
|
||||
INSERT INTO `sys_gen_columns` VALUES ('810', 'author_code', 'invite_code', 'varchar', 'String', '邀请码', '2', '邀请码', '1', '1', null);
|
||||
INSERT INTO `sys_gen_columns` VALUES ('811', 'author_code', 'validity_time', 'datetime', 'Date', '有效时间', '3', '有效时间', '4', '1', null);
|
||||
INSERT INTO `sys_gen_columns` VALUES ('812', 'author_code', 'is_use', 'tinyint', 'Integer', '是否使用过,0:未使用,1:使用过', '4', '是否使用过,0:未使用,1:使用过', '1', '0', null);
|
||||
INSERT INTO `sys_gen_columns` VALUES ('813', 'author_code', 'create_time', 'datetime', 'Date', '创建时间', '5', '创建时间', '4', '0', null);
|
||||
INSERT INTO `sys_gen_columns` VALUES ('814', 'author_code', 'create_user_id', 'bigint', 'Long', '创建人ID', '6', '创建人ID', '1', '0', null);
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for sys_gen_table
|
||||
@ -807,11 +885,8 @@ CREATE TABLE `sys_log` (
|
||||
`ip` varchar(64) DEFAULT NULL COMMENT 'IP地址',
|
||||
`gmt_create` datetime DEFAULT NULL COMMENT '创建时间',
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=1369 DEFAULT CHARSET=utf8 COMMENT='系统日志';
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=1412 DEFAULT CHARSET=utf8 COMMENT='系统日志';
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of sys_log
|
||||
-- ----------------------------
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for sys_menu
|
||||
@ -829,7 +904,7 @@ CREATE TABLE `sys_menu` (
|
||||
`gmt_create` datetime DEFAULT NULL COMMENT '创建时间',
|
||||
`gmt_modified` datetime DEFAULT NULL COMMENT '修改时间',
|
||||
PRIMARY KEY (`menu_id`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=215 DEFAULT CHARSET=utf8 COMMENT='菜单管理';
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=234 DEFAULT CHARSET=utf8 COMMENT='菜单管理';
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of sys_menu
|
||||
@ -886,6 +961,19 @@ INSERT INTO `sys_menu` VALUES ('211', '209', '新增', null, 'system:dataPerm:ad
|
||||
INSERT INTO `sys_menu` VALUES ('212', '209', '修改', null, 'system:dataPerm:edit', '2', null, '6', null, null);
|
||||
INSERT INTO `sys_menu` VALUES ('213', '209', '删除', null, 'system:dataPerm:remove', '2', null, '6', null, null);
|
||||
INSERT INTO `sys_menu` VALUES ('214', '209', '批量删除', null, 'system:dataPerm:batchRemove', '2', null, '6', null, null);
|
||||
INSERT INTO `sys_menu` VALUES ('221', '0', '作家管理', '', '', '0', 'fa fa-user-o', '10', null, null);
|
||||
INSERT INTO `sys_menu` VALUES ('222', '221', '作者列表', 'novel/author', 'novel:author:author', '1', 'fa', '6', null, null);
|
||||
INSERT INTO `sys_menu` VALUES ('223', '222', '查看', null, 'novel:author:detail', '2', null, '6', null, null);
|
||||
INSERT INTO `sys_menu` VALUES ('224', '222', '新增', null, 'novel:author:add', '2', null, '6', null, null);
|
||||
INSERT INTO `sys_menu` VALUES ('225', '222', '修改', null, 'novel:author:edit', '2', null, '6', null, null);
|
||||
INSERT INTO `sys_menu` VALUES ('226', '222', '删除', null, 'novel:author:remove', '2', null, '6', null, null);
|
||||
INSERT INTO `sys_menu` VALUES ('227', '222', '批量删除', null, 'novel:author:batchRemove', '2', null, '6', null, null);
|
||||
INSERT INTO `sys_menu` VALUES ('228', '221', '邀请码管理', 'novel/authorCode', 'novel:authorCode:authorCode', '1', 'fa', '3', null, null);
|
||||
INSERT INTO `sys_menu` VALUES ('229', '228', '查看', null, 'novel:authorCode:detail', '2', null, '6', null, null);
|
||||
INSERT INTO `sys_menu` VALUES ('230', '228', '新增', null, 'novel:authorCode:add', '2', null, '6', null, null);
|
||||
INSERT INTO `sys_menu` VALUES ('231', '228', '修改', null, 'novel:authorCode:edit', '2', null, '6', null, null);
|
||||
INSERT INTO `sys_menu` VALUES ('232', '228', '删除', null, 'novel:authorCode:remove', '2', null, '6', null, null);
|
||||
INSERT INTO `sys_menu` VALUES ('233', '228', '批量删除', null, 'novel:authorCode:batchRemove', '2', null, '6', null, null);
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for sys_role
|
||||
@ -906,9 +994,6 @@ CREATE TABLE `sys_role` (
|
||||
-- Records of sys_role
|
||||
-- ----------------------------
|
||||
INSERT INTO `sys_role` VALUES ('1', '超级用户角色', 'admin', '拥有最高权限', '2', '2017-08-12 00:43:52', '2017-08-12 19:14:59');
|
||||
INSERT INTO `sys_role` VALUES ('59', '普通用户', null, '基本用户权限', null, null, null);
|
||||
INSERT INTO `sys_role` VALUES ('60', '测试', null, '<div>', null, null, null);
|
||||
INSERT INTO `sys_role` VALUES ('61', 'test', null, '测试', null, null, null);
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for sys_role_data_perm
|
||||
@ -919,22 +1004,22 @@ CREATE TABLE `sys_role_data_perm` (
|
||||
`role_id` bigint(20) DEFAULT NULL COMMENT '角色ID',
|
||||
`perm_id` bigint(20) DEFAULT NULL COMMENT '权限ID',
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=63 DEFAULT CHARSET=utf8 COMMENT='角色与数据权限对应关系';
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=79 DEFAULT CHARSET=utf8 COMMENT='角色与数据权限对应关系';
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of sys_role_data_perm
|
||||
-- ----------------------------
|
||||
INSERT INTO `sys_role_data_perm` VALUES ('49', '1', '214');
|
||||
INSERT INTO `sys_role_data_perm` VALUES ('50', '1', '213');
|
||||
INSERT INTO `sys_role_data_perm` VALUES ('51', '1', '212');
|
||||
INSERT INTO `sys_role_data_perm` VALUES ('52', '1', '211');
|
||||
INSERT INTO `sys_role_data_perm` VALUES ('53', '1', '210');
|
||||
INSERT INTO `sys_role_data_perm` VALUES ('54', '1', '1199168630769283072');
|
||||
INSERT INTO `sys_role_data_perm` VALUES ('55', '1', '-1');
|
||||
INSERT INTO `sys_role_data_perm` VALUES ('56', '1', '1199168630454710272');
|
||||
INSERT INTO `sys_role_data_perm` VALUES ('60', '60', '211');
|
||||
INSERT INTO `sys_role_data_perm` VALUES ('61', '60', '-1');
|
||||
INSERT INTO `sys_role_data_perm` VALUES ('62', '60', '1199170283966787584');
|
||||
INSERT INTO `sys_role_data_perm` VALUES ('71', '1', '214');
|
||||
INSERT INTO `sys_role_data_perm` VALUES ('72', '1', '213');
|
||||
INSERT INTO `sys_role_data_perm` VALUES ('73', '1', '212');
|
||||
INSERT INTO `sys_role_data_perm` VALUES ('74', '1', '211');
|
||||
INSERT INTO `sys_role_data_perm` VALUES ('75', '1', '210');
|
||||
INSERT INTO `sys_role_data_perm` VALUES ('76', '1', '1260412100929482752');
|
||||
INSERT INTO `sys_role_data_perm` VALUES ('77', '1', '-1');
|
||||
INSERT INTO `sys_role_data_perm` VALUES ('78', '1', '1260412099998347264');
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for sys_role_menu
|
||||
@ -945,7 +1030,7 @@ CREATE TABLE `sys_role_menu` (
|
||||
`role_id` bigint(20) DEFAULT NULL COMMENT '角色ID',
|
||||
`menu_id` bigint(20) DEFAULT NULL COMMENT '菜单ID',
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=4704 DEFAULT CHARSET=utf8 COMMENT='角色与菜单对应关系';
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=4830 DEFAULT CHARSET=utf8 COMMENT='角色与菜单对应关系';
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of sys_role_menu
|
||||
@ -1166,59 +1251,6 @@ INSERT INTO `sys_role_menu` VALUES ('3280', '59', '3');
|
||||
INSERT INTO `sys_role_menu` VALUES ('3281', '59', '78');
|
||||
INSERT INTO `sys_role_menu` VALUES ('3282', '59', '1');
|
||||
INSERT INTO `sys_role_menu` VALUES ('3283', '59', '-1');
|
||||
INSERT INTO `sys_role_menu` VALUES ('4505', '1', '208');
|
||||
INSERT INTO `sys_role_menu` VALUES ('4506', '1', '207');
|
||||
INSERT INTO `sys_role_menu` VALUES ('4507', '1', '206');
|
||||
INSERT INTO `sys_role_menu` VALUES ('4508', '1', '205');
|
||||
INSERT INTO `sys_role_menu` VALUES ('4509', '1', '204');
|
||||
INSERT INTO `sys_role_menu` VALUES ('4510', '1', '92');
|
||||
INSERT INTO `sys_role_menu` VALUES ('4511', '1', '57');
|
||||
INSERT INTO `sys_role_menu` VALUES ('4512', '1', '30');
|
||||
INSERT INTO `sys_role_menu` VALUES ('4513', '1', '29');
|
||||
INSERT INTO `sys_role_menu` VALUES ('4514', '1', '28');
|
||||
INSERT INTO `sys_role_menu` VALUES ('4515', '1', '104');
|
||||
INSERT INTO `sys_role_menu` VALUES ('4516', '1', '48');
|
||||
INSERT INTO `sys_role_menu` VALUES ('4517', '1', '214');
|
||||
INSERT INTO `sys_role_menu` VALUES ('4518', '1', '213');
|
||||
INSERT INTO `sys_role_menu` VALUES ('4519', '1', '212');
|
||||
INSERT INTO `sys_role_menu` VALUES ('4520', '1', '211');
|
||||
INSERT INTO `sys_role_menu` VALUES ('4521', '1', '210');
|
||||
INSERT INTO `sys_role_menu` VALUES ('4522', '1', '76');
|
||||
INSERT INTO `sys_role_menu` VALUES ('4523', '1', '75');
|
||||
INSERT INTO `sys_role_menu` VALUES ('4524', '1', '74');
|
||||
INSERT INTO `sys_role_menu` VALUES ('4525', '1', '62');
|
||||
INSERT INTO `sys_role_menu` VALUES ('4526', '1', '56');
|
||||
INSERT INTO `sys_role_menu` VALUES ('4527', '1', '55');
|
||||
INSERT INTO `sys_role_menu` VALUES ('4528', '1', '15');
|
||||
INSERT INTO `sys_role_menu` VALUES ('4529', '1', '26');
|
||||
INSERT INTO `sys_role_menu` VALUES ('4530', '1', '25');
|
||||
INSERT INTO `sys_role_menu` VALUES ('4531', '1', '24');
|
||||
INSERT INTO `sys_role_menu` VALUES ('4532', '1', '14');
|
||||
INSERT INTO `sys_role_menu` VALUES ('4533', '1', '13');
|
||||
INSERT INTO `sys_role_menu` VALUES ('4534', '1', '12');
|
||||
INSERT INTO `sys_role_menu` VALUES ('4535', '1', '61');
|
||||
INSERT INTO `sys_role_menu` VALUES ('4536', '1', '22');
|
||||
INSERT INTO `sys_role_menu` VALUES ('4537', '1', '21');
|
||||
INSERT INTO `sys_role_menu` VALUES ('4538', '1', '20');
|
||||
INSERT INTO `sys_role_menu` VALUES ('4539', '1', '83');
|
||||
INSERT INTO `sys_role_menu` VALUES ('4540', '1', '81');
|
||||
INSERT INTO `sys_role_menu` VALUES ('4541', '1', '80');
|
||||
INSERT INTO `sys_role_menu` VALUES ('4542', '1', '79');
|
||||
INSERT INTO `sys_role_menu` VALUES ('4543', '1', '71');
|
||||
INSERT INTO `sys_role_menu` VALUES ('4544', '1', '203');
|
||||
INSERT INTO `sys_role_menu` VALUES ('4545', '1', '202');
|
||||
INSERT INTO `sys_role_menu` VALUES ('4546', '1', '27');
|
||||
INSERT INTO `sys_role_menu` VALUES ('4547', '1', '91');
|
||||
INSERT INTO `sys_role_menu` VALUES ('4548', '1', '77');
|
||||
INSERT INTO `sys_role_menu` VALUES ('4549', '1', '209');
|
||||
INSERT INTO `sys_role_menu` VALUES ('4550', '1', '73');
|
||||
INSERT INTO `sys_role_menu` VALUES ('4551', '1', '7');
|
||||
INSERT INTO `sys_role_menu` VALUES ('4552', '1', '6');
|
||||
INSERT INTO `sys_role_menu` VALUES ('4553', '1', '2');
|
||||
INSERT INTO `sys_role_menu` VALUES ('4554', '1', '3');
|
||||
INSERT INTO `sys_role_menu` VALUES ('4555', '1', '78');
|
||||
INSERT INTO `sys_role_menu` VALUES ('4556', '1', '1');
|
||||
INSERT INTO `sys_role_menu` VALUES ('4557', '1', '-1');
|
||||
INSERT INTO `sys_role_menu` VALUES ('4611', '61', '208');
|
||||
INSERT INTO `sys_role_menu` VALUES ('4612', '61', '207');
|
||||
INSERT INTO `sys_role_menu` VALUES ('4613', '61', '206');
|
||||
@ -1312,6 +1344,72 @@ INSERT INTO `sys_role_menu` VALUES ('4700', '60', '78');
|
||||
INSERT INTO `sys_role_menu` VALUES ('4701', '60', '1');
|
||||
INSERT INTO `sys_role_menu` VALUES ('4702', '60', '-1');
|
||||
INSERT INTO `sys_role_menu` VALUES ('4703', '60', '3');
|
||||
INSERT INTO `sys_role_menu` VALUES ('4764', '1', '227');
|
||||
INSERT INTO `sys_role_menu` VALUES ('4765', '1', '226');
|
||||
INSERT INTO `sys_role_menu` VALUES ('4766', '1', '225');
|
||||
INSERT INTO `sys_role_menu` VALUES ('4767', '1', '224');
|
||||
INSERT INTO `sys_role_menu` VALUES ('4768', '1', '223');
|
||||
INSERT INTO `sys_role_menu` VALUES ('4769', '1', '208');
|
||||
INSERT INTO `sys_role_menu` VALUES ('4770', '1', '207');
|
||||
INSERT INTO `sys_role_menu` VALUES ('4771', '1', '206');
|
||||
INSERT INTO `sys_role_menu` VALUES ('4772', '1', '205');
|
||||
INSERT INTO `sys_role_menu` VALUES ('4773', '1', '204');
|
||||
INSERT INTO `sys_role_menu` VALUES ('4774', '1', '92');
|
||||
INSERT INTO `sys_role_menu` VALUES ('4775', '1', '57');
|
||||
INSERT INTO `sys_role_menu` VALUES ('4776', '1', '30');
|
||||
INSERT INTO `sys_role_menu` VALUES ('4777', '1', '29');
|
||||
INSERT INTO `sys_role_menu` VALUES ('4778', '1', '28');
|
||||
INSERT INTO `sys_role_menu` VALUES ('4779', '1', '104');
|
||||
INSERT INTO `sys_role_menu` VALUES ('4780', '1', '48');
|
||||
INSERT INTO `sys_role_menu` VALUES ('4781', '1', '214');
|
||||
INSERT INTO `sys_role_menu` VALUES ('4782', '1', '213');
|
||||
INSERT INTO `sys_role_menu` VALUES ('4783', '1', '212');
|
||||
INSERT INTO `sys_role_menu` VALUES ('4784', '1', '211');
|
||||
INSERT INTO `sys_role_menu` VALUES ('4785', '1', '210');
|
||||
INSERT INTO `sys_role_menu` VALUES ('4786', '1', '76');
|
||||
INSERT INTO `sys_role_menu` VALUES ('4787', '1', '75');
|
||||
INSERT INTO `sys_role_menu` VALUES ('4788', '1', '74');
|
||||
INSERT INTO `sys_role_menu` VALUES ('4789', '1', '62');
|
||||
INSERT INTO `sys_role_menu` VALUES ('4790', '1', '56');
|
||||
INSERT INTO `sys_role_menu` VALUES ('4791', '1', '55');
|
||||
INSERT INTO `sys_role_menu` VALUES ('4792', '1', '15');
|
||||
INSERT INTO `sys_role_menu` VALUES ('4793', '1', '26');
|
||||
INSERT INTO `sys_role_menu` VALUES ('4794', '1', '25');
|
||||
INSERT INTO `sys_role_menu` VALUES ('4795', '1', '24');
|
||||
INSERT INTO `sys_role_menu` VALUES ('4796', '1', '14');
|
||||
INSERT INTO `sys_role_menu` VALUES ('4797', '1', '13');
|
||||
INSERT INTO `sys_role_menu` VALUES ('4798', '1', '12');
|
||||
INSERT INTO `sys_role_menu` VALUES ('4799', '1', '61');
|
||||
INSERT INTO `sys_role_menu` VALUES ('4800', '1', '22');
|
||||
INSERT INTO `sys_role_menu` VALUES ('4801', '1', '21');
|
||||
INSERT INTO `sys_role_menu` VALUES ('4802', '1', '20');
|
||||
INSERT INTO `sys_role_menu` VALUES ('4803', '1', '83');
|
||||
INSERT INTO `sys_role_menu` VALUES ('4804', '1', '81');
|
||||
INSERT INTO `sys_role_menu` VALUES ('4805', '1', '80');
|
||||
INSERT INTO `sys_role_menu` VALUES ('4806', '1', '79');
|
||||
INSERT INTO `sys_role_menu` VALUES ('4807', '1', '71');
|
||||
INSERT INTO `sys_role_menu` VALUES ('4808', '1', '222');
|
||||
INSERT INTO `sys_role_menu` VALUES ('4809', '1', '203');
|
||||
INSERT INTO `sys_role_menu` VALUES ('4810', '1', '202');
|
||||
INSERT INTO `sys_role_menu` VALUES ('4811', '1', '27');
|
||||
INSERT INTO `sys_role_menu` VALUES ('4812', '1', '91');
|
||||
INSERT INTO `sys_role_menu` VALUES ('4813', '1', '77');
|
||||
INSERT INTO `sys_role_menu` VALUES ('4814', '1', '209');
|
||||
INSERT INTO `sys_role_menu` VALUES ('4815', '1', '73');
|
||||
INSERT INTO `sys_role_menu` VALUES ('4816', '1', '7');
|
||||
INSERT INTO `sys_role_menu` VALUES ('4817', '1', '6');
|
||||
INSERT INTO `sys_role_menu` VALUES ('4818', '1', '2');
|
||||
INSERT INTO `sys_role_menu` VALUES ('4819', '1', '3');
|
||||
INSERT INTO `sys_role_menu` VALUES ('4820', '1', '78');
|
||||
INSERT INTO `sys_role_menu` VALUES ('4821', '1', '1');
|
||||
INSERT INTO `sys_role_menu` VALUES ('4822', '1', '228');
|
||||
INSERT INTO `sys_role_menu` VALUES ('4823', '1', '233');
|
||||
INSERT INTO `sys_role_menu` VALUES ('4824', '1', '232');
|
||||
INSERT INTO `sys_role_menu` VALUES ('4825', '1', '231');
|
||||
INSERT INTO `sys_role_menu` VALUES ('4826', '1', '230');
|
||||
INSERT INTO `sys_role_menu` VALUES ('4827', '1', '229');
|
||||
INSERT INTO `sys_role_menu` VALUES ('4828', '1', '221');
|
||||
INSERT INTO `sys_role_menu` VALUES ('4829', '1', '-1');
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for sys_user
|
||||
@ -1343,19 +1441,7 @@ CREATE TABLE `sys_user` (
|
||||
-- ----------------------------
|
||||
-- Records of sys_user
|
||||
-- ----------------------------
|
||||
INSERT INTO `sys_user` VALUES ('1', 'admin', '超级管理员', 'd633268afedf209e1e4ea0f5f43228a8', '6', 'admin@example.com', '17699999999', '1', '1', '2017-08-15 21:40:39', '2017-08-15 21:41:00', '96', '2017-12-14 00:00:00', '148', 'ccc', '122;121;', '北京市', '北京市市辖区', '东城区');
|
||||
INSERT INTO `sys_user` VALUES ('2', 'test', '临时用户', 'd0af8fa1272ef5a152d9e27763eea293', '6', 'test@bootdo.com', null, '1', '1', '2017-08-14 13:43:05', '2017-08-14 21:15:36', null, null, null, null, null, null, null, null);
|
||||
INSERT INTO `sys_user` VALUES ('36', 'ldh', '刘德华', 'bfd9394475754fbe45866eba97738c36', '7', 'ldh@bootdo.com', null, '1', null, null, null, null, null, null, null, null, null, null, null);
|
||||
INSERT INTO `sys_user` VALUES ('123', 'zxy', '张学友', '35174ba93f5fe7267f1fb3c1bf903781', '6', 'zxy@bootdo', null, '0', null, null, null, null, null, null, null, null, null, null, null);
|
||||
INSERT INTO `sys_user` VALUES ('124', 'wyf', '吴亦凡', 'e179e6f687bbd57b9d7efc4746c8090a', '6', 'wyf@bootdo.com', null, '1', null, null, null, null, null, null, null, null, null, null, null);
|
||||
INSERT INTO `sys_user` VALUES ('130', 'lh', '鹿晗', '7924710cd673f68967cde70e188bb097', '9', 'lh@bootdo.com', null, '1', null, null, null, null, null, null, null, null, null, null, null);
|
||||
INSERT INTO `sys_user` VALUES ('131', 'lhc', '令狐冲', 'd515538e17ecb570ba40344b5618f5d4', '6', 'lhc@bootdo.com', null, '0', null, null, null, null, null, null, null, null, null, null, null);
|
||||
INSERT INTO `sys_user` VALUES ('132', 'lyf', '刘亦菲', '7fdb1d9008f45950c1620ba0864e5fbd', '13', 'lyf@bootdo.com', null, '1', null, null, null, null, null, null, null, null, null, null, null);
|
||||
INSERT INTO `sys_user` VALUES ('134', 'lyh', '李彦宏', 'dc26092b3244d9d432863f2738180e19', '8', 'lyh@bootdo.com', null, '1', null, null, null, null, null, null, null, null, null, null, null);
|
||||
INSERT INTO `sys_user` VALUES ('135', 'wjl', '王健林', '3967697dfced162cf6a34080259b83aa', '6', 'wjl@bootod.com', null, '1', null, null, null, null, null, null, null, null, null, null, null);
|
||||
INSERT INTO `sys_user` VALUES ('136', 'gdg', '郭德纲', '3bb1bda86bc02bf6478cd91e42135d2f', '9', 'gdg@bootdo.com', null, '1', null, null, null, null, null, null, null, null, null, null, null);
|
||||
INSERT INTO `sys_user` VALUES ('137', 'test2', 'test2', '649169898e69272c0e5bc899baf1e904', null, '1179705413@qq.com', null, '1', null, null, null, null, null, null, null, null, null, null, null);
|
||||
INSERT INTO `sys_user` VALUES ('138', 'test3', 'test3', '4428f69c806f51128f3974f948a2f272', '16', '1179705413@qq.com', null, '1', null, null, null, null, null, null, null, null, null, null, null);
|
||||
INSERT INTO `sys_user` VALUES ('1', 'admin', '超级管理员', 'd633268afedf209e1e4ea0f5f43228a8', '14', 'admin@example.com', '17699999999', '1', '1', '2017-08-15 21:40:39', '2017-08-15 21:41:00', '96', '2017-12-14 00:00:00', '148', 'ccc', '122;121;', '北京市', '北京市市辖区', '东城区');
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for sys_user_role
|
||||
@ -1460,6 +1546,29 @@ INSERT INTO `user_bookshelf` VALUES ('39', '1255060328322027520', '1254681071191
|
||||
INSERT INTO `user_bookshelf` VALUES ('40', '1255060328322027520', '1254676970567565312', '3264258', '2020-04-30 09:57:18', '2020-04-30 19:19:11');
|
||||
INSERT INTO `user_bookshelf` VALUES ('41', '1255060328322027520', '1254675594315759616', '1254675594496114688', '2020-04-30 18:37:18', null);
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for user_buy_record
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `user_buy_record`;
|
||||
CREATE TABLE `user_buy_record` (
|
||||
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
|
||||
`user_id` bigint(20) NOT NULL COMMENT '用户ID',
|
||||
`book_id` bigint(20) DEFAULT NULL COMMENT '购买的小说ID',
|
||||
`book_name` varchar(50) DEFAULT NULL COMMENT '购买的小说名',
|
||||
`book_index_id` bigint(20) DEFAULT NULL COMMENT '购买的章节ID',
|
||||
`book_index_name` varchar(100) DEFAULT NULL COMMENT '购买的章节名',
|
||||
`buy_amount` int(11) DEFAULT NULL COMMENT '购买使用的屋币数量',
|
||||
`create_time` datetime DEFAULT NULL COMMENT '购买时间',
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `key_userId_indexId` (`user_id`,`book_index_id`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COMMENT='用户消费记录表';
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of user_buy_record
|
||||
-- ----------------------------
|
||||
INSERT INTO `user_buy_record` VALUES ('1', '1255060328322027520', '1260400284744613890', '我是一只消消乐2', '1260522024606953472', '第三章', '10', '2020-05-13 21:29:09');
|
||||
INSERT INTO `user_buy_record` VALUES ('2', '1255060328322027520', '1260400284744613890', '我是一只消消乐2', '1260564410687107072', '第四章', '10', '2020-05-13 21:40:38');
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for user_feedback
|
||||
-- ----------------------------
|
||||
@ -1513,3 +1622,222 @@ INSERT INTO `user_read_history` VALUES ('111', '1255060328322027520', '125495762
|
||||
INSERT INTO `user_read_history` VALUES ('113', '1255060328322027520', '1254676970567565312', '3264258', '2020-04-30 19:19:11', '2020-04-30 19:19:11');
|
||||
INSERT INTO `user_read_history` VALUES ('117', '1255060328322027520', '1254946661743603712', '1254946914001629184', '2020-04-30 19:37:09', '2020-04-30 19:37:09');
|
||||
INSERT INTO `user_read_history` VALUES ('118', '1255060328322027520', '1254957312633352192', '3335449', '2020-04-30 19:37:36', '2020-04-30 19:37:36');
|
||||
|
||||
|
||||
|
||||
DROP TABLE IF EXISTS `book_content0`;
|
||||
CREATE TABLE `book_content0` (
|
||||
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
|
||||
`index_id` bigint(20) DEFAULT NULL COMMENT '目录ID',
|
||||
`content` mediumtext COMMENT '小说章节内容',
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `key_uq_indexId` (`index_id`) USING BTREE
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=1155 DEFAULT CHARSET=utf8mb4 COMMENT='小说内容表';
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for book_content1
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `book_content1`;
|
||||
CREATE TABLE `book_content1` (
|
||||
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
|
||||
`index_id` bigint(20) DEFAULT NULL COMMENT '目录ID',
|
||||
`content` mediumtext COMMENT '小说章节内容',
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `key_uq_indexId` (`index_id`) USING BTREE
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=406 DEFAULT CHARSET=utf8mb4 COMMENT='小说内容表';
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for book_content2
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `book_content2`;
|
||||
CREATE TABLE `book_content2` (
|
||||
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
|
||||
`index_id` bigint(20) DEFAULT NULL COMMENT '目录ID',
|
||||
`content` mediumtext COMMENT '小说章节内容',
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `key_uq_indexId` (`index_id`) USING BTREE
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=1222 DEFAULT CHARSET=utf8mb4 COMMENT='小说内容表';
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for book_content3
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `book_content3`;
|
||||
CREATE TABLE `book_content3` (
|
||||
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
|
||||
`index_id` bigint(20) DEFAULT NULL COMMENT '目录ID',
|
||||
`content` mediumtext COMMENT '小说章节内容',
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `key_uq_indexId` (`index_id`) USING BTREE
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=410 DEFAULT CHARSET=utf8mb4 COMMENT='小说内容表';
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for book_content4
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `book_content4`;
|
||||
CREATE TABLE `book_content4` (
|
||||
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
|
||||
`index_id` bigint(20) DEFAULT NULL COMMENT '目录ID',
|
||||
`content` mediumtext COMMENT '小说章节内容',
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `key_uq_indexId` (`index_id`) USING BTREE
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=1188 DEFAULT CHARSET=utf8mb4 COMMENT='小说内容表';
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for book_content5
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `book_content5`;
|
||||
CREATE TABLE `book_content5` (
|
||||
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
|
||||
`index_id` bigint(20) DEFAULT NULL COMMENT '目录ID',
|
||||
`content` mediumtext COMMENT '小说章节内容',
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `key_uq_indexId` (`index_id`) USING BTREE
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=416 DEFAULT CHARSET=utf8mb4 COMMENT='小说内容表';
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for book_content6
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `book_content6`;
|
||||
CREATE TABLE `book_content6` (
|
||||
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
|
||||
`index_id` bigint(20) DEFAULT NULL COMMENT '目录ID',
|
||||
`content` mediumtext COMMENT '小说章节内容',
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `key_uq_indexId` (`index_id`) USING BTREE
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=1180 DEFAULT CHARSET=utf8mb4 COMMENT='小说内容表';
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for book_content7
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `book_content7`;
|
||||
CREATE TABLE `book_content7` (
|
||||
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
|
||||
`index_id` bigint(20) DEFAULT NULL COMMENT '目录ID',
|
||||
`content` mediumtext COMMENT '小说章节内容',
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `key_uq_indexId` (`index_id`) USING BTREE
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=404 DEFAULT CHARSET=utf8mb4 COMMENT='小说内容表';
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for book_content8
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `book_content8`;
|
||||
CREATE TABLE `book_content8` (
|
||||
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
|
||||
`index_id` bigint(20) DEFAULT NULL COMMENT '目录ID',
|
||||
`content` mediumtext COMMENT '小说章节内容',
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `key_uq_indexId` (`index_id`) USING BTREE
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=1134 DEFAULT CHARSET=utf8mb4 COMMENT='小说内容表';
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for book_content9
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `book_content9`;
|
||||
CREATE TABLE `book_content9` (
|
||||
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
|
||||
`index_id` bigint(20) DEFAULT NULL COMMENT '目录ID',
|
||||
`content` mediumtext COMMENT '小说章节内容',
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `key_uq_indexId` (`index_id`) USING BTREE
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=415 DEFAULT CHARSET=utf8mb4 COMMENT='小说内容表';
|
||||
|
||||
|
||||
DROP TABLE IF EXISTS `crawl_single_task`;
|
||||
CREATE TABLE `crawl_single_task` (
|
||||
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
|
||||
`source_id` int(11) DEFAULT NULL COMMENT '爬虫源ID',
|
||||
`source_name` varchar(50) DEFAULT NULL COMMENT '爬虫源名',
|
||||
`source_book_id` varchar(255) DEFAULT NULL COMMENT '源站小说ID',
|
||||
`cat_id` int(11) DEFAULT NULL COMMENT '分类ID',
|
||||
`book_name` varchar(50) DEFAULT NULL COMMENT '爬取的小说名',
|
||||
`author_name` varchar(50) DEFAULT NULL COMMENT '爬取的小说作者名',
|
||||
`task_status` tinyint(1) DEFAULT '2' COMMENT '任务状态,0:失败,1:成功,2;未执行',
|
||||
`exc_count` tinyint(2) DEFAULT '0' COMMENT '已经执行次数,最多执行5次',
|
||||
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8mb4 COMMENT='抓取单本小说任务表';
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of crawl_single_task
|
||||
-- ----------------------------
|
||||
INSERT INTO `crawl_single_task` VALUES ('6', '2', '百书斋', '1', '1', '1', '1', '0', '5', '2020-06-15 14:36:07');
|
||||
INSERT INTO `crawl_single_task` VALUES ('7', '5', '笔趣阁', '108_108291', '1', '衍天志之不朽仙', '白衣少年丶', '1', '1', '2020-06-15 14:46:08');
|
||||
UPDATE `crawl_source` SET `source_name` = '书趣阁', `crawl_rule` = '{\n \"bookListUrl\": \"http://m.shuquge.com/sort/{catId}/0_{page}.html\",\n \"catIdRule\": {\n \"catId1\": \"1\",\n \"catId2\": \"2\",\n \"catId3\": \"3\",\n \"catId4\": \"4\",\n \"catId5\": \"7\",\n \"catId6\": \"6\",\n \"catId7\": \"8\"\n },\n \"bookIdPatten\": \"href=\\\"/s/(\\\\d+)\\\\.html\\\"\",\n \"pagePatten\": \"第(\\\\d+)/\\\\d+页\",\n \"totalPagePatten\": \"第\\\\d+/(\\\\d+)页\",\n \"bookDetailUrl\": \"http://m.shuquge.com/s/{bookId}.html\",\n \"bookNamePatten\": \"<a\\\\s+href=\\\"/s/\\\\d+\\\\.html\\\"><h2>([^/]+)</h2></a>\",\n \"authorNamePatten\": \"<p>作者:([^/]+)</p>\",\n \"picUrlPatten\": \"src=\\\"(http://www.shuquge.com/files/article/image/\\\\d+/\\\\d+/\\\\d+s\\\\.jpg)\\\"\",\n \"statusPatten\": \"<p>状态:([^/]+)</p>\",\n \"bookStatusRule\": {\n \"连载中\": 0,\n \"完本\": 1\n },\n \"descStart\": \"<div class=\\\"intro_info\\\">\",\n \"descEnd\": \"最新章节推荐地址\",\n \"bookIndexUrl\": \"http://www.shuquge.com/txt/{bookId}/index.html\",\n \"bookIndexStart\": \"<dt>《\",\n \"indexIdPatten\": \"<dd><a\\\\s+href=\\\"(\\\\d+)\\\\.html\\\">[^/]+</a></dd>\",\n \"indexNamePatten\": \"<dd><a\\\\s+href=\\\"\\\\d+\\\\.html\\\">([^/]+)</a></dd>\",\n \"bookContentUrl\": \"http://www.shuquge.com/txt/{bookId}/{indexId}.html\",\n \"contentStart\": \"<div id=\\\"content\\\" class=\\\"showtxt\\\">\",\n \"contentEnd\": \"http://www.shuquge.com\"\n}', `source_status` = 1, `create_time` = '2020-05-18 12:02:34', `update_time` = '2020-05-18 12:02:34' WHERE `id` = 4;
|
||||
|
||||
INSERT INTO `friend_link` ( `link_name`, `link_url`, `sort`, `is_open`, `create_user_id`, `create_time`, `update_user_id`, `update_time`) VALUES
|
||||
('小羊影视', 'http://video.java2nb.com/', 11, 1, NULL, NULL, NULL, NULL),
|
||||
('官方论坛', 'http://bbs.java2nb.com', 21, 1, NULL, NULL, NULL, NULL);
|
||||
|
||||
|
||||
CREATE TABLE `author_income_detail` (
|
||||
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
|
||||
`user_id` bigint(20) NOT NULL COMMENT '用户ID',
|
||||
`author_id` bigint(20) NOT NULL COMMENT '作家ID',
|
||||
`book_id` bigint(20) NOT NULL DEFAULT '0' COMMENT '作品ID,0表示全部作品',
|
||||
`income_date` date NOT NULL COMMENT '收入日期',
|
||||
`income_account` int(11) NOT NULL DEFAULT '0' COMMENT '订阅总额',
|
||||
`income_count` int(11) NOT NULL DEFAULT '0' COMMENT '订阅次数',
|
||||
`income_number` int(11) NOT NULL DEFAULT '0' COMMENT '订阅人数',
|
||||
`create_time` datetime DEFAULT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='稿费收入明细统计表';
|
||||
|
||||
CREATE TABLE `author_income` (
|
||||
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
|
||||
`user_id` bigint(20) NOT NULL COMMENT '用户ID',
|
||||
`author_id` bigint(20) NOT NULL COMMENT '作家ID',
|
||||
`book_id` bigint(20) NOT NULL COMMENT '作品ID',
|
||||
`income_month` date NOT NULL COMMENT '收入月份',
|
||||
`pre_tax_income` bigint(20) NOT NULL DEFAULT '0' COMMENT '税前收入(分)',
|
||||
`after_tax_income` bigint(20) NOT NULL DEFAULT '0' COMMENT '税后收入(分)',
|
||||
`pay_status` tinyint(1) NOT NULL DEFAULT '0' COMMENT '支付状态,0:待支付,1:已支付',
|
||||
`confirm_status` tinyint(1) NOT NULL DEFAULT '0' COMMENT '稿费确认状态,0:待确认,1:已确认',
|
||||
`detail` varchar(255) DEFAULT NULL COMMENT '详情',
|
||||
`create_time` datetime DEFAULT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='稿费收入统计表';
|
||||
|
||||
|
||||
alter table book add column `yesterday_buy` int(11) DEFAULT '0' COMMENT '昨日订阅数' after comment_count;
|
||||
|
||||
alter table book_index add column `book_price` int(3) DEFAULT 0 COMMENT '章节费用(屋币)' after `is_vip`;
|
||||
|
||||
|
||||
|
||||
INSERT INTO `sys_menu`(`menu_id`, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`, `gmt_create`, `gmt_modified`) VALUES (246, 241, '批量删除', NULL, 'novel:news:batchRemove', 2, NULL, 6, NULL, NULL);
|
||||
INSERT INTO `sys_menu`(`menu_id`, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`, `gmt_create`, `gmt_modified`) VALUES (245, 241, '删除', NULL, 'novel:news:remove', 2, NULL, 6, NULL, NULL);
|
||||
INSERT INTO `sys_menu`(`menu_id`, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`, `gmt_create`, `gmt_modified`) VALUES (244, 241, '修改', NULL, 'novel:news:edit', 2, NULL, 6, NULL, NULL);
|
||||
INSERT INTO `sys_menu`(`menu_id`, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`, `gmt_create`, `gmt_modified`) VALUES (243, 241, '新增', NULL, 'novel:news:add', 2, NULL, 6, NULL, NULL);
|
||||
INSERT INTO `sys_menu`(`menu_id`, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`, `gmt_create`, `gmt_modified`) VALUES (242, 241, '查看', NULL, 'novel:news:detail', 2, NULL, 6, NULL, NULL);
|
||||
INSERT INTO `sys_menu`(`menu_id`, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`, `gmt_create`, `gmt_modified`) VALUES (241, 234, '新闻列表', 'novel/news', 'novel:news:news', 1, 'fa', 8, NULL, NULL);
|
||||
INSERT INTO `sys_menu`(`menu_id`, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`, `gmt_create`, `gmt_modified`) VALUES (240, 235, '批量删除', NULL, 'novel:category:batchRemove', 2, NULL, 6, NULL, NULL);
|
||||
INSERT INTO `sys_menu`(`menu_id`, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`, `gmt_create`, `gmt_modified`) VALUES (239, 235, '删除', NULL, 'novel:category:remove', 2, NULL, 6, NULL, NULL);
|
||||
INSERT INTO `sys_menu`(`menu_id`, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`, `gmt_create`, `gmt_modified`) VALUES (238, 235, '修改', NULL, 'novel:category:edit', 2, NULL, 6, NULL, NULL);
|
||||
INSERT INTO `sys_menu`(`menu_id`, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`, `gmt_create`, `gmt_modified`) VALUES (237, 235, '新增', NULL, 'novel:category:add', 2, NULL, 6, NULL, NULL);
|
||||
INSERT INTO `sys_menu`(`menu_id`, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`, `gmt_create`, `gmt_modified`) VALUES (236, 235, '查看', NULL, 'novel:category:detail', 2, NULL, 6, NULL, NULL);
|
||||
INSERT INTO `sys_menu`(`menu_id`, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`, `gmt_create`, `gmt_modified`) VALUES (235, 234, '类别管理', 'novel/category', 'novel:category:category', 1, 'fa', 6, NULL, NULL);
|
||||
INSERT INTO `sys_menu`(`menu_id`, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`, `gmt_create`, `gmt_modified`) VALUES (234, 0, '新闻管理', '', '', 0, 'fa fa-newspaper-o', 8, NULL, NULL);
|
||||
|
||||
|
||||
|
||||
INSERT INTO `sys_role_menu`(`id`, `role_id`, `menu_id`) VALUES (4889, 1, 246);
|
||||
INSERT INTO `sys_role_menu`(`id`, `role_id`, `menu_id`) VALUES (4890, 1, 245);
|
||||
INSERT INTO `sys_role_menu`(`id`, `role_id`, `menu_id`) VALUES (4891, 1, 244);
|
||||
INSERT INTO `sys_role_menu`(`id`, `role_id`, `menu_id`) VALUES (4892, 1, 243);
|
||||
INSERT INTO `sys_role_menu`(`id`, `role_id`, `menu_id`) VALUES (4893, 1, 242);
|
||||
INSERT INTO `sys_role_menu`(`id`, `role_id`, `menu_id`) VALUES (4899, 1, 241);
|
||||
INSERT INTO `sys_role_menu`(`id`, `role_id`, `menu_id`) VALUES (4894, 1, 240);
|
||||
INSERT INTO `sys_role_menu`(`id`, `role_id`, `menu_id`) VALUES (4895, 1, 239);
|
||||
INSERT INTO `sys_role_menu`(`id`, `role_id`, `menu_id`) VALUES (4896, 1, 238);
|
||||
INSERT INTO `sys_role_menu`(`id`, `role_id`, `menu_id`) VALUES (4897, 1, 237);
|
||||
INSERT INTO `sys_role_menu`(`id`, `role_id`, `menu_id`) VALUES (4898, 1, 236);
|
||||
INSERT INTO `sys_role_menu`(`id`, `role_id`, `menu_id`) VALUES (4900, 1, 235);
|
||||
INSERT INTO `sys_role_menu`(`id`, `role_id`, `menu_id`) VALUES (4888, 1, 234);
|
||||
|
||||
|
||||
delete from sys_menu where menu_id = 202;
|
||||
|
||||
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;
|
3
doc/sql/sql文件说明.txt
Normal file
3
doc/sql/sql文件说明.txt
Normal file
@ -0,0 +1,3 @@
|
||||
novel_plus.sqlΪȫ<CEAA><C8AB>sql<71>ļ<EFBFBD><C4BC><EFBFBD>yyyyMMdd.sqlΪ<6C><CEAA><EFBFBD><EFBFBD>sql<71>ļ<EFBFBD><C4BC><EFBFBD>
|
||||
<EFBFBD><EFBFBD><EFBFBD>û<EFBFBD>ֻ<EFBFBD><EFBFBD>Ҫִ<EFBFBD><EFBFBD>novel_plus.sql<71>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD>ɡ<EFBFBD>
|
||||
<EFBFBD><EFBFBD><EFBFBD>û<EFBFBD><EFBFBD><EFBFBD><EFBFBD>´<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϴδ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ĸ<EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD>䣬ִ<EFBFBD>и<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֮<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>sql<EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD>
|
6
novel-admin/Dockerfile
Normal file
6
novel-admin/Dockerfile
Normal file
@ -0,0 +1,6 @@
|
||||
FROM java:8
|
||||
ADD novel-admin-1.0.0.jar /root
|
||||
ENV dburl=""
|
||||
ENV username=""
|
||||
ENV password=""
|
||||
ENTRYPOINT ["sh","-c","java -Dspring.datasource.url=${dburl} -Dspring.datasource.username=${username} -Dspring.datasource.password=${password} -jar /root/novel-admin-1.0.0.jar"]
|
264
novel-admin/pom.xml
Normal file
264
novel-admin/pom.xml
Normal file
@ -0,0 +1,264 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>com.java2nb</groupId>
|
||||
<artifactId>novel-admin</artifactId>
|
||||
<version>3.6.0</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>novel-admin</name>
|
||||
<description>小说精品屋后台管理</description>
|
||||
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>2.0.1.RELEASE</version>
|
||||
<relativePath/>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||
<java.version>1.8</java.version>
|
||||
<velocity.version>1.7</velocity.version>
|
||||
<activiti.version>5.22.0</activiti.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-aop</artifactId>
|
||||
</dependency>
|
||||
<!--web -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-thymeleaf</artifactId>
|
||||
</dependency>
|
||||
<!-- NekoHTML 是一个简单地HTML扫描器和标签补偿器(tag balancer) ,使得程序能解析HTML文档并用标准的XML接口来访问其中的信息。
|
||||
这个解析器能投扫描HTML文件并“修正”许多作者(人或机器)在编写HTML文档过程中常犯的错误。
|
||||
NekoHTML 能增补缺失的父元素、自动用结束标签关闭相应的元素,以及不匹配的内嵌元素标签。
|
||||
NekoHTML 的开发使用了Xerces Native Interface (XNI),后者是Xerces2的实现基础。-->
|
||||
<dependency>
|
||||
<groupId>net.sourceforge.nekohtml</groupId>
|
||||
<artifactId>nekohtml</artifactId>
|
||||
</dependency>
|
||||
<!--mybatis -->
|
||||
<dependency>
|
||||
<groupId>mysql</groupId>
|
||||
<artifactId>mysql-connector-java</artifactId>
|
||||
<version>8.0.11</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mybatis</groupId>
|
||||
<artifactId>mybatis</artifactId>
|
||||
<version>3.4.4</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.mybatis.spring.boot</groupId>
|
||||
<artifactId>mybatis-spring-boot-starter</artifactId>
|
||||
<version>1.1.1</version>
|
||||
</dependency>
|
||||
<!--druid -->
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>druid</artifactId>
|
||||
<version>1.0.28</version>
|
||||
</dependency>
|
||||
<!--commons -->
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
<version>3.6</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-configuration</groupId>
|
||||
<artifactId>commons-configuration</artifactId>
|
||||
<version>1.10</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-io</groupId>
|
||||
<artifactId>commons-io</artifactId>
|
||||
<version>2.5</version>
|
||||
</dependency>
|
||||
<!--shiro -->
|
||||
<dependency>
|
||||
<groupId>org.apache.shiro</groupId>
|
||||
<artifactId>shiro-core</artifactId>
|
||||
<version>1.3.2</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.shiro</groupId>
|
||||
<artifactId>shiro-spring</artifactId>
|
||||
<version>1.3.2</version>
|
||||
</dependency>
|
||||
<!-- shiro ehcache -->
|
||||
<dependency>
|
||||
<groupId>org.apache.shiro</groupId>
|
||||
<artifactId>shiro-ehcache</artifactId>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>net.sf.ehcache</groupId>
|
||||
<artifactId>ehcache-core</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
<version>1.4.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.github.theborakompanioni</groupId>
|
||||
<artifactId>thymeleaf-extras-shiro</artifactId>
|
||||
<version>2.0.0</version>
|
||||
</dependency>
|
||||
<!-- utils -->
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>fastjson</artifactId>
|
||||
<version>1.2.31</version>
|
||||
</dependency>
|
||||
<!--velocity代码生成使用模板 -->
|
||||
<dependency>
|
||||
<groupId>org.apache.velocity</groupId>
|
||||
<artifactId>velocity</artifactId>
|
||||
<version>1.7</version>
|
||||
</dependency>
|
||||
<!--<dependency>-->
|
||||
<!--<groupId>org.springframework.boot</groupId>-->
|
||||
<!--<artifactId>spring-boot-starter-data-redis</artifactId>-->
|
||||
<!--</dependency>-->
|
||||
<!-- quartz -->
|
||||
<!--<dependency>-->
|
||||
<!--<groupId>org.springframework.boot</groupId>-->
|
||||
<!--<artifactId>spring-boot-starter-cache</artifactId>-->
|
||||
<!--</dependency>-->
|
||||
|
||||
<!--<dependency>-->
|
||||
<!--<groupId>net.sf.ehcache</groupId>-->
|
||||
<!--<artifactId>ehcache</artifactId>-->
|
||||
<!--</dependency>-->
|
||||
|
||||
|
||||
<!--<dependency>-->
|
||||
<!--<groupId>org.springframework.boot</groupId>-->
|
||||
<!--<artifactId>spring-boot-devtools</artifactId>-->
|
||||
<!--<optional>true</optional>-->
|
||||
<!--</dependency>-->
|
||||
|
||||
<!--swagger2-->
|
||||
<dependency>
|
||||
<groupId>io.springfox</groupId>
|
||||
<artifactId>springfox-swagger2</artifactId>
|
||||
<version>2.6.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.springfox</groupId>
|
||||
<artifactId>springfox-swagger-ui</artifactId>
|
||||
<version>2.6.1</version>
|
||||
</dependency>
|
||||
|
||||
<!-- 添加redis支持-->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-redis</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>redis.clients</groupId>
|
||||
<artifactId>jedis</artifactId>
|
||||
<version>2.9.0</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-text</artifactId>
|
||||
<version>1.4</version>
|
||||
</dependency>
|
||||
|
||||
<!-- ehchache -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-cache</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.sf.ehcache</groupId>
|
||||
<artifactId>ehcache</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!--war包部署需要-->
|
||||
<!--<dependency>-->
|
||||
<!--<groupId>org.springframework.boot</groupId>-->
|
||||
<!--<artifactId>spring-boot-starter-web</artifactId>-->
|
||||
<!--<!– 移除嵌入式tomcat插件 –>-->
|
||||
<!--<exclusions>-->
|
||||
<!--<exclusion>-->
|
||||
<!--<groupId>org.springframework.boot</groupId>-->
|
||||
<!--<artifactId>spring-boot-starter-tomcat</artifactId>-->
|
||||
<!--</exclusion>-->
|
||||
<!--</exclusions>-->
|
||||
<!--</dependency>-->
|
||||
<!--<dependency>-->
|
||||
<!--<groupId>javax.servlet</groupId>-->
|
||||
<!--<artifactId>javax.servlet-api</artifactId>-->
|
||||
<!--<version>3.1.0</version>-->
|
||||
<!--<scope>provided</scope>-->
|
||||
<!--</dependency>-->
|
||||
</dependencies>
|
||||
<build>
|
||||
<plugins>
|
||||
<!--<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<configuration>
|
||||
<executable>true</executable>
|
||||
</configuration>
|
||||
</plugin>-->
|
||||
<!--SpringBoot项目默认使用spring-boot-maven-plugin,要打成被其他项目引用的jar包,需要更换此插件-->
|
||||
<!-- <plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<source>1.8</source>
|
||||
<target>1.8</target>
|
||||
<encoding>UTF-8</encoding>
|
||||
</configuration>
|
||||
</plugin>-->
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<!--<distributionManagement>
|
||||
<repository>
|
||||
<id>nexus_release</id>
|
||||
<name>release</name>
|
||||
<url>http://47.106.243.172:8081/nexus/content/repositories/releases/</url>
|
||||
</repository>
|
||||
<snapshotRepository>
|
||||
<id>nexus_snapshots</id>
|
||||
<name>snapshots</name>
|
||||
<url>http://47.106.243.172:8081/nexus/content/repositories/snapshots/</url>
|
||||
</snapshotRepository>
|
||||
</distributionManagement>-->
|
||||
</project>
|
23
novel-admin/src/main/java/com/java2nb/AdminApplication.java
Normal file
23
novel-admin/src/main/java/com/java2nb/AdminApplication.java
Normal file
@ -0,0 +1,23 @@
|
||||
package com.java2nb;
|
||||
|
||||
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.transaction.annotation.EnableTransactionManagement;
|
||||
|
||||
|
||||
@EnableTransactionManagement
|
||||
@ServletComponentScan
|
||||
@MapperScan("com.java2nb.*.dao")
|
||||
@SpringBootApplication(exclude = {
|
||||
org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration.class
|
||||
})
|
||||
@EnableCaching
|
||||
public class AdminApplication {
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(AdminApplication.class, args);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
package com.java2nb.common.annotation;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Target;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
@Target(ElementType.METHOD)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface Log {
|
||||
String value() default "";
|
||||
}
|
@ -0,0 +1,104 @@
|
||||
package com.java2nb.common.aspect;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Date;
|
||||
import java.util.concurrent.ArrayBlockingQueue;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import com.java2nb.common.service.LogService;
|
||||
import com.java2nb.system.domain.UserToken;
|
||||
import org.aspectj.lang.ProceedingJoinPoint;
|
||||
import org.aspectj.lang.annotation.Around;
|
||||
import org.aspectj.lang.annotation.Aspect;
|
||||
import org.aspectj.lang.annotation.Pointcut;
|
||||
import org.aspectj.lang.reflect.MethodSignature;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.scheduling.annotation.Async;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.java2nb.common.annotation.Log;
|
||||
import com.java2nb.common.dao.LogDao;
|
||||
import com.java2nb.common.domain.LogDO;
|
||||
import com.java2nb.common.utils.HttpContextUtils;
|
||||
import com.java2nb.common.utils.IPUtils;
|
||||
import com.java2nb.common.utils.JSONUtils;
|
||||
import com.java2nb.common.utils.ShiroUtils;
|
||||
import com.java2nb.system.domain.UserDO;
|
||||
|
||||
@Aspect
|
||||
@Component
|
||||
public class LogAspect {
|
||||
private static final Logger logger = LoggerFactory.getLogger(LogAspect.class);
|
||||
|
||||
@Autowired
|
||||
LogService logService;
|
||||
|
||||
|
||||
@Pointcut("@annotation(com.java2nb.common.annotation.Log)")
|
||||
public void logPointCut() {
|
||||
}
|
||||
|
||||
@Around("logPointCut()")
|
||||
public Object around(ProceedingJoinPoint point) throws Throwable {
|
||||
long beginTime = System.currentTimeMillis();
|
||||
// 执行方法
|
||||
Object result = point.proceed();
|
||||
// 执行时长(毫秒)
|
||||
long time = System.currentTimeMillis() - beginTime;
|
||||
//异步保存日志
|
||||
saveLog(point, time);
|
||||
return result;
|
||||
}
|
||||
|
||||
void saveLog(ProceedingJoinPoint joinPoint, long time) throws InterruptedException {
|
||||
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
|
||||
Method method = signature.getMethod();
|
||||
LogDO sysLog = new LogDO();
|
||||
Log syslog = method.getAnnotation(Log.class);
|
||||
if (syslog != null) {
|
||||
// 注解上的描述
|
||||
sysLog.setOperation(syslog.value());
|
||||
}
|
||||
// 请求的方法名
|
||||
String className = joinPoint.getTarget().getClass().getName();
|
||||
String methodName = signature.getName();
|
||||
sysLog.setMethod(className + "." + methodName + "()");
|
||||
// 请求的参数
|
||||
Object[] args = joinPoint.getArgs();
|
||||
try {
|
||||
String params = JSONUtils.beanToJson(args[0]).substring(0, 4999);
|
||||
sysLog.setParams(params);
|
||||
} catch (Exception e) {
|
||||
|
||||
}
|
||||
// 获取request
|
||||
HttpServletRequest request = HttpContextUtils.getHttpServletRequest();
|
||||
// 设置IP地址
|
||||
sysLog.setIp(IPUtils.getIpAddr(request));
|
||||
// 用户名
|
||||
UserDO currUser = ShiroUtils.getUser();
|
||||
if (null == currUser) {
|
||||
if (null != sysLog.getParams()) {
|
||||
sysLog.setUserId(-1L);
|
||||
sysLog.setUsername(sysLog.getParams());
|
||||
} else {
|
||||
sysLog.setUserId(-1L);
|
||||
sysLog.setUsername("获取用户信息为空");
|
||||
}
|
||||
} else {
|
||||
sysLog.setUserId(ShiroUtils.getUserId());
|
||||
sysLog.setUsername(ShiroUtils.getUser().getUsername());
|
||||
}
|
||||
sysLog.setTime((int) time);
|
||||
// 系统当前时间
|
||||
Date date = new Date();
|
||||
sysLog.setGmtCreate(date);
|
||||
// 保存系统日志
|
||||
logService.save(sysLog);
|
||||
}
|
||||
}
|
@ -0,0 +1,61 @@
|
||||
package com.java2nb.common.aspect;
|
||||
|
||||
import com.java2nb.common.utils.HttpContextUtils;
|
||||
import org.aspectj.lang.JoinPoint;
|
||||
import org.aspectj.lang.ProceedingJoinPoint;
|
||||
import org.aspectj.lang.annotation.*;
|
||||
import org.aspectj.lang.reflect.MethodSignature;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.context.request.RequestContextHolder;
|
||||
import org.springframework.web.context.request.ServletRequestAttributes;
|
||||
import sun.net.util.IPAddressUtil;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Arrays;
|
||||
|
||||
@Aspect
|
||||
@Component
|
||||
public class WebLogAspect {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(WebLogAspect.class);
|
||||
|
||||
@Pointcut("execution( * com.java2nb..controller.*.*(..))")//两个..代表所有子目录,最后括号里的两个..代表所有参数
|
||||
public void logPointCut() {
|
||||
}
|
||||
|
||||
|
||||
@Before("logPointCut()")
|
||||
public void doBefore(JoinPoint joinPoint) throws Throwable {
|
||||
// 接收到请求,记录请求内容
|
||||
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
|
||||
HttpServletRequest request = attributes.getRequest();
|
||||
|
||||
// 记录下请求内容
|
||||
logger.info("请求地址 : " + request.getRequestURL().toString());
|
||||
logger.info("HTTP METHOD : " + request.getMethod());
|
||||
// 获取真实的ip地址
|
||||
//logger.info("IP : " + IPAddressUtil.getClientIpAddress(request));
|
||||
logger.info("CLASS_METHOD : " + joinPoint.getSignature().getDeclaringTypeName() + "."
|
||||
+ joinPoint.getSignature().getName());
|
||||
logger.info("参数 : " + Arrays.toString(joinPoint.getArgs()));
|
||||
// loggger.info("参数 : " + joinPoint.getArgs());
|
||||
|
||||
}
|
||||
|
||||
@AfterReturning(returning = "ret", pointcut = "logPointCut()")// returning的值和doAfterReturning的参数名一致
|
||||
public void doAfterReturning(Object ret) throws Throwable {
|
||||
// 处理完请求,返回内容(返回值太复杂时,打印的是物理存储空间的地址)
|
||||
logger.debug("返回值 : " + ret);
|
||||
}
|
||||
|
||||
@Around("logPointCut()")
|
||||
public Object doAround(ProceedingJoinPoint pjp) throws Throwable {
|
||||
long startTime = System.currentTimeMillis();
|
||||
Object ob = pjp.proceed();// ob 为方法的返回值
|
||||
logger.info("耗时 : " + (System.currentTimeMillis() - startTime));
|
||||
return ob;
|
||||
}
|
||||
}
|
@ -0,0 +1,50 @@
|
||||
package com.java2nb.common.config;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author xiongxy
|
||||
* @date 2019-09-25 15:09:21
|
||||
* <p>
|
||||
* Email 122741482@qq.com
|
||||
* <p>
|
||||
* Describe:
|
||||
*/
|
||||
@Component
|
||||
public class ApplicationContextRegister implements ApplicationContextAware {
|
||||
private static Logger logger = LoggerFactory.getLogger(ApplicationContextRegister.class);
|
||||
private static ApplicationContext APPLICATION_CONTEXT;
|
||||
/**
|
||||
* 设置spring上下文
|
||||
* @param applicationContext spring上下文
|
||||
* @throws BeansException
|
||||
* */
|
||||
@Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
|
||||
logger.debug("ApplicationContext registed-->{}", applicationContext);
|
||||
APPLICATION_CONTEXT = applicationContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取容器
|
||||
* @return
|
||||
*/
|
||||
public static ApplicationContext getApplicationContext() {
|
||||
return APPLICATION_CONTEXT;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取容器对象
|
||||
* @param type
|
||||
* @param <T>
|
||||
* @return
|
||||
*/
|
||||
public static <T> T getBean(Class<T> type) {
|
||||
return APPLICATION_CONTEXT.getBean(type);
|
||||
}
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
package com.java2nb.common.config;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import org.apache.shiro.session.Session;
|
||||
import org.apache.shiro.session.SessionListener;
|
||||
|
||||
public class BDSessionListener implements SessionListener {
|
||||
|
||||
private final AtomicInteger sessionCount = new AtomicInteger(0);
|
||||
|
||||
@Override
|
||||
public void onStart(Session session) {
|
||||
sessionCount.incrementAndGet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStop(Session session) {
|
||||
sessionCount.decrementAndGet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onExpiration(Session session) {
|
||||
sessionCount.decrementAndGet();
|
||||
|
||||
}
|
||||
|
||||
public int getSessionCount() {
|
||||
return sessionCount.get();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
package com.java2nb.common.config;
|
||||
|
||||
public class Constant {
|
||||
//演示系统账户
|
||||
public static String DEMO_ACCOUNT = "test";
|
||||
//自动去除表前缀
|
||||
public static String AUTO_REOMVE_PRE = "true";
|
||||
//停止计划任务
|
||||
public static String STATUS_RUNNING_STOP = "stop";
|
||||
//开启计划任务
|
||||
public static String STATUS_RUNNING_START = "start";
|
||||
//通知公告阅读状态-未读
|
||||
public static String OA_NOTIFY_READ_NO = "0";
|
||||
//通知公告阅读状态-已读
|
||||
public static int OA_NOTIFY_READ_YES = 1;
|
||||
//部门根节点id
|
||||
public static Long DEPT_ROOT_ID = 0l;
|
||||
//缓存方式
|
||||
public static String CACHE_TYPE_REDIS ="redis";
|
||||
|
||||
public static String LOG_ERROR = "error";
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,40 @@
|
||||
package com.java2nb.common.config;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.zip.DataFormatException;
|
||||
|
||||
/**
|
||||
* @author xiongxy
|
||||
* @date 2019-09-25 15:09:21
|
||||
*/
|
||||
@Configuration
|
||||
public class DateConverConfig {
|
||||
@Bean
|
||||
public Converter<String, Date> stringDateConvert() {
|
||||
return new Converter<String, Date>() {
|
||||
@Override
|
||||
public Date convert(String source) {
|
||||
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||
Date date = null;
|
||||
try {
|
||||
date = sdf.parse((String) source);
|
||||
} catch (Exception e) {
|
||||
SimpleDateFormat sdfday = new SimpleDateFormat("yyyy-MM-dd");
|
||||
try {
|
||||
date = sdfday.parse((String) source);
|
||||
} catch (ParseException e1) {
|
||||
e1.printStackTrace();
|
||||
}
|
||||
}
|
||||
return date;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,132 @@
|
||||
package com.java2nb.common.config;
|
||||
import com.alibaba.druid.pool.DruidDataSource;
|
||||
import com.alibaba.druid.support.http.StatViewServlet;
|
||||
import com.alibaba.druid.support.http.WebStatFilter;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.web.servlet.FilterRegistrationBean;
|
||||
import org.springframework.boot.web.servlet.ServletRegistrationBean;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Primary;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
import java.sql.SQLException;
|
||||
|
||||
/**
|
||||
* Created by PrimaryKey on 17/2/4.
|
||||
*/
|
||||
@SuppressWarnings("AlibabaRemoveCommentedCode")
|
||||
@Configuration
|
||||
public class DruidDBConfig {
|
||||
private Logger logger = LoggerFactory.getLogger(DruidDBConfig.class);
|
||||
@Value("${spring.datasource.url}")
|
||||
private String dbUrl;
|
||||
|
||||
@Value("${spring.datasource.username}")
|
||||
private String username;
|
||||
|
||||
@Value("${spring.datasource.password}")
|
||||
private String password;
|
||||
|
||||
@Value("${spring.datasource.driverClassName}")
|
||||
private String driverClassName;
|
||||
|
||||
@Value("${spring.datasource.initialSize}")
|
||||
private int initialSize;
|
||||
|
||||
@Value("${spring.datasource.minIdle}")
|
||||
private int minIdle;
|
||||
|
||||
@Value("${spring.datasource.maxActive}")
|
||||
private int maxActive;
|
||||
|
||||
@Value("${spring.datasource.maxWait}")
|
||||
private int maxWait;
|
||||
|
||||
@Value("${spring.datasource.timeBetweenEvictionRunsMillis}")
|
||||
private int timeBetweenEvictionRunsMillis;
|
||||
|
||||
@Value("${spring.datasource.minEvictableIdleTimeMillis}")
|
||||
private int minEvictableIdleTimeMillis;
|
||||
|
||||
@Value("${spring.datasource.validationQuery}")
|
||||
private String validationQuery;
|
||||
|
||||
@Value("${spring.datasource.testWhileIdle}")
|
||||
private boolean testWhileIdle;
|
||||
|
||||
@Value("${spring.datasource.testOnBorrow}")
|
||||
private boolean testOnBorrow;
|
||||
|
||||
@Value("${spring.datasource.testOnReturn}")
|
||||
private boolean testOnReturn;
|
||||
|
||||
@Value("${spring.datasource.poolPreparedStatements}")
|
||||
private boolean poolPreparedStatements;
|
||||
|
||||
@Value("${spring.datasource.maxPoolPreparedStatementPerConnectionSize}")
|
||||
private int maxPoolPreparedStatementPerConnectionSize;
|
||||
|
||||
@Value("${spring.datasource.filters}")
|
||||
private String filters;
|
||||
|
||||
@Value("{spring.datasource.connectionProperties}")
|
||||
private String connectionProperties;
|
||||
|
||||
@Bean(initMethod = "init", destroyMethod = "close") //声明其为Bean实例
|
||||
@Primary //在同样的DataSource中,首先使用被标注的DataSource
|
||||
public DataSource dataSource() {
|
||||
DruidDataSource datasource = new DruidDataSource();
|
||||
|
||||
datasource.setUrl(this.dbUrl);
|
||||
datasource.setUsername(username);
|
||||
datasource.setPassword(password);
|
||||
datasource.setDriverClassName(driverClassName);
|
||||
|
||||
//configuration
|
||||
datasource.setInitialSize(initialSize);
|
||||
datasource.setMinIdle(minIdle);
|
||||
datasource.setMaxActive(maxActive);
|
||||
datasource.setMaxWait(maxWait);
|
||||
datasource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);
|
||||
datasource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
|
||||
datasource.setValidationQuery(validationQuery);
|
||||
datasource.setTestWhileIdle(testWhileIdle);
|
||||
datasource.setTestOnBorrow(testOnBorrow);
|
||||
datasource.setTestOnReturn(testOnReturn);
|
||||
datasource.setPoolPreparedStatements(poolPreparedStatements);
|
||||
datasource.setMaxPoolPreparedStatementPerConnectionSize(maxPoolPreparedStatementPerConnectionSize);
|
||||
try {
|
||||
datasource.setFilters(filters);
|
||||
} catch (SQLException e) {
|
||||
logger.error("druid configuration initialization filter", e);
|
||||
}
|
||||
datasource.setConnectionProperties(connectionProperties);
|
||||
|
||||
return datasource;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ServletRegistrationBean druidServlet() {
|
||||
ServletRegistrationBean reg = new ServletRegistrationBean();
|
||||
reg.setServlet(new StatViewServlet());
|
||||
reg.addUrlMappings("/druid/*");
|
||||
reg.addInitParameter("allow", ""); //白名单
|
||||
return reg;
|
||||
}
|
||||
|
||||
@Bean public FilterRegistrationBean filterRegistrationBean() {
|
||||
FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
|
||||
filterRegistrationBean.setFilter(new WebStatFilter());
|
||||
filterRegistrationBean.addUrlPatterns("/*");
|
||||
filterRegistrationBean.addInitParameter("exclusions", "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*");
|
||||
filterRegistrationBean.addInitParameter("profileEnable", "true");
|
||||
filterRegistrationBean.addInitParameter("principalCookieName","USER_COOKIE");
|
||||
filterRegistrationBean.addInitParameter("principalSessionName","USER_SESSION");
|
||||
filterRegistrationBean.addInitParameter("DruidWebStatFilter","/*");
|
||||
return filterRegistrationBean;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,39 @@
|
||||
package com.java2nb.common.config;
|
||||
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
@ConfigurationProperties(prefix="java2nb")
|
||||
public class JnConfig {
|
||||
//上传路径
|
||||
private String uploadPath;
|
||||
|
||||
private String username;
|
||||
|
||||
private String password;
|
||||
|
||||
public String getUploadPath() {
|
||||
return uploadPath;
|
||||
}
|
||||
|
||||
public void setUploadPath(String uploadPath) {
|
||||
this.uploadPath = uploadPath;
|
||||
}
|
||||
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
||||
public void setUsername(String username) {
|
||||
this.username = username;
|
||||
}
|
||||
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
public void setPassword(String password) {
|
||||
this.password = password;
|
||||
}
|
||||
}
|
@ -0,0 +1,82 @@
|
||||
package com.java2nb.common.config;
|
||||
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonAutoDetect;
|
||||
import com.fasterxml.jackson.annotation.PropertyAccessor;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.data.redis.connection.RedisConnectionFactory;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
|
||||
import org.springframework.data.redis.serializer.StringRedisSerializer;
|
||||
|
||||
@Configuration
|
||||
public class RedisConfig {
|
||||
|
||||
|
||||
@Bean
|
||||
@SuppressWarnings("all")
|
||||
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
|
||||
|
||||
|
||||
RedisTemplate<String, Object> template = new RedisTemplate<String, Object>();
|
||||
|
||||
|
||||
template.setConnectionFactory(factory);
|
||||
|
||||
|
||||
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
|
||||
|
||||
|
||||
ObjectMapper om = new ObjectMapper();
|
||||
|
||||
|
||||
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
|
||||
|
||||
|
||||
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
|
||||
|
||||
|
||||
jackson2JsonRedisSerializer.setObjectMapper(om);
|
||||
|
||||
|
||||
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
|
||||
|
||||
|
||||
// key采用String的序列化方式
|
||||
|
||||
|
||||
template.setKeySerializer(stringRedisSerializer);
|
||||
|
||||
|
||||
// hash的key也采用String的序列化方式
|
||||
|
||||
|
||||
template.setHashKeySerializer(stringRedisSerializer);
|
||||
|
||||
|
||||
// value序列化方式采用jackson
|
||||
|
||||
|
||||
template.setValueSerializer(jackson2JsonRedisSerializer);
|
||||
|
||||
|
||||
// hash的value序列化方式采用jackson
|
||||
|
||||
|
||||
template.setHashValueSerializer(jackson2JsonRedisSerializer);
|
||||
|
||||
|
||||
template.afterPropertiesSet();
|
||||
|
||||
|
||||
return template;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,13 @@
|
||||
package com.java2nb.common.config;
|
||||
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
@EnableAutoConfiguration(exclude = {
|
||||
org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration.class
|
||||
})
|
||||
@Configuration
|
||||
public class SecuityConfig {
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,202 @@
|
||||
package com.java2nb.common.config;
|
||||
|
||||
import at.pollux.thymeleaf.shiro.dialect.ShiroDialect;
|
||||
import com.java2nb.common.redis.shiro.RedisCacheManager;
|
||||
import com.java2nb.common.redis.shiro.RedisManager;
|
||||
import com.java2nb.common.redis.shiro.RedisSessionDAO;
|
||||
import com.java2nb.system.shiro.UserRealm;
|
||||
import net.sf.ehcache.CacheManager;
|
||||
import org.apache.shiro.cache.ehcache.EhCacheManager;
|
||||
import org.apache.shiro.mgt.SecurityManager;
|
||||
import org.apache.shiro.session.SessionListener;
|
||||
import org.apache.shiro.session.mgt.eis.MemorySessionDAO;
|
||||
import org.apache.shiro.session.mgt.eis.SessionDAO;
|
||||
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
|
||||
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
|
||||
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
|
||||
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
|
||||
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedHashMap;
|
||||
|
||||
/**
|
||||
* @author xiongxy
|
||||
*/
|
||||
@Configuration
|
||||
public class ShiroConfig {
|
||||
@Value("${spring.redis.host}")
|
||||
private String host;
|
||||
@Value("${spring.redis.password}")
|
||||
private String password;
|
||||
@Value("${spring.redis.port}")
|
||||
private int port;
|
||||
@Value("${spring.redis.timeout}")
|
||||
private int timeout;
|
||||
|
||||
@Value("${spring.cache.type}")
|
||||
private String cacheType ;
|
||||
|
||||
@Value("${server.session-timeout}")
|
||||
private int tomcatTimeout;
|
||||
|
||||
@Bean
|
||||
public static LifecycleBeanPostProcessor getLifecycleBeanPostProcessor() {
|
||||
return new LifecycleBeanPostProcessor();
|
||||
}
|
||||
|
||||
/**
|
||||
* ShiroDialect,为了在thymeleaf里使用shiro的标签的bean
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Bean
|
||||
public ShiroDialect shiroDialect() {
|
||||
return new ShiroDialect();
|
||||
}
|
||||
|
||||
@Bean
|
||||
ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) {
|
||||
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
|
||||
shiroFilterFactoryBean.setSecurityManager(securityManager);
|
||||
shiroFilterFactoryBean.setLoginUrl("/login");
|
||||
shiroFilterFactoryBean.setSuccessUrl("/index");
|
||||
shiroFilterFactoryBean.setUnauthorizedUrl("/403");
|
||||
LinkedHashMap<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
|
||||
filterChainDefinitionMap.put("/login","anon");
|
||||
filterChainDefinitionMap.put("/getVerify","anon");
|
||||
filterChainDefinitionMap.put("/css/**", "anon");
|
||||
filterChainDefinitionMap.put("/js/**", "anon");
|
||||
filterChainDefinitionMap.put("/fonts/**", "anon");
|
||||
filterChainDefinitionMap.put("/img/**", "anon");
|
||||
filterChainDefinitionMap.put("/docs/**", "anon");
|
||||
filterChainDefinitionMap.put("/layuimini/**", "anon");
|
||||
filterChainDefinitionMap.put("/upload/**", "anon");
|
||||
filterChainDefinitionMap.put("/files/**", "anon");
|
||||
filterChainDefinitionMap.put("/logout", "logout");
|
||||
filterChainDefinitionMap.put("/blog", "anon");
|
||||
filterChainDefinitionMap.put("/blog/open/**", "anon");
|
||||
filterChainDefinitionMap.put("/**", "authc");
|
||||
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
|
||||
return shiroFilterFactoryBean;
|
||||
}
|
||||
|
||||
|
||||
@Bean
|
||||
public SecurityManager securityManager() {
|
||||
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
|
||||
//设置realm.
|
||||
securityManager.setRealm(userRealm());
|
||||
// 自定义缓存实现 使用redis
|
||||
if (Constant.CACHE_TYPE_REDIS.equals(cacheType)) {
|
||||
securityManager.setCacheManager(rediscacheManager());
|
||||
} else {
|
||||
securityManager.setCacheManager(ehCacheManager());
|
||||
}
|
||||
securityManager.setSessionManager(sessionManager());
|
||||
return securityManager;
|
||||
}
|
||||
|
||||
@Bean
|
||||
UserRealm userRealm() {
|
||||
UserRealm userRealm = new UserRealm();
|
||||
return userRealm;
|
||||
}
|
||||
|
||||
/**
|
||||
* 开启shiro aop注解支持.
|
||||
* 使用代理方式;所以需要开启代码支持;
|
||||
*
|
||||
* @param securityManager
|
||||
* @return
|
||||
*/
|
||||
@Bean
|
||||
public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
|
||||
AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
|
||||
authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
|
||||
return authorizationAttributeSourceAdvisor;
|
||||
}
|
||||
|
||||
/**
|
||||
* 配置shiro redisManager
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Bean
|
||||
public RedisManager redisManager() {
|
||||
RedisManager redisManager = new RedisManager();
|
||||
redisManager.setHost(host);
|
||||
redisManager.setPort(port);
|
||||
redisManager.setExpire(1800);// 配置缓存过期时间
|
||||
//redisManager.setTimeout(1800);
|
||||
redisManager.setPassword(password);
|
||||
return redisManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* cacheManager 缓存 redis实现
|
||||
* 使用的是shiro-redis开源插件
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public RedisCacheManager rediscacheManager() {
|
||||
RedisCacheManager redisCacheManager = new RedisCacheManager();
|
||||
redisCacheManager.setRedisManager(redisManager());
|
||||
return redisCacheManager;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* RedisSessionDAO shiro sessionDao层的实现 通过redis
|
||||
* 使用的是shiro-redis开源插件
|
||||
*/
|
||||
@Bean
|
||||
public RedisSessionDAO redisSessionDAO() {
|
||||
RedisSessionDAO redisSessionDAO = new RedisSessionDAO();
|
||||
redisSessionDAO.setRedisManager(redisManager());
|
||||
return redisSessionDAO;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public SessionDAO sessionDAO() {
|
||||
if (Constant.CACHE_TYPE_REDIS.equals(cacheType)) {
|
||||
return redisSessionDAO();
|
||||
} else {
|
||||
return new MemorySessionDAO();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* shiro session的管理
|
||||
*/
|
||||
@Bean
|
||||
public DefaultWebSessionManager sessionManager() {
|
||||
DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();
|
||||
sessionManager.setGlobalSessionTimeout(tomcatTimeout * 1000);
|
||||
sessionManager.setSessionDAO(sessionDAO());
|
||||
Collection<SessionListener> listeners = new ArrayList<SessionListener>();
|
||||
listeners.add(new BDSessionListener());
|
||||
sessionManager.setSessionListeners(listeners);
|
||||
return sessionManager;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public EhCacheManager ehCacheManager() {
|
||||
EhCacheManager em = new EhCacheManager();
|
||||
em.setCacheManager(cacheManager());
|
||||
return em;
|
||||
}
|
||||
|
||||
@Bean("cacheManager2")
|
||||
CacheManager cacheManager(){
|
||||
return CacheManager.create();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
package com.java2nb.common.config;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.task.AsyncTaskExecutor;
|
||||
import org.springframework.scheduling.annotation.EnableAsync;
|
||||
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
|
||||
|
||||
import java.util.concurrent.RejectedExecutionHandler;
|
||||
import java.util.concurrent.SynchronousQueue;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@Configuration
|
||||
@EnableAsync
|
||||
public class SpringAsyncConfig {
|
||||
// @Bean
|
||||
// public AsyncTaskExecutor taskExecutor() {
|
||||
// ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
|
||||
// executor.setMaxPoolSize(10);
|
||||
// return executor;
|
||||
// }
|
||||
}
|
@ -0,0 +1,48 @@
|
||||
package com.java2nb.common.config;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import springfox.documentation.builders.ApiInfoBuilder;
|
||||
import springfox.documentation.builders.PathSelectors;
|
||||
import springfox.documentation.builders.RequestHandlerSelectors;
|
||||
import springfox.documentation.service.ApiInfo;
|
||||
import springfox.documentation.service.Contact;
|
||||
import springfox.documentation.spi.DocumentationType;
|
||||
import springfox.documentation.spring.web.plugins.Docket;
|
||||
import springfox.documentation.swagger2.annotations.EnableSwagger2;
|
||||
|
||||
/**
|
||||
* ${DESCRIPTION}
|
||||
*
|
||||
* @author xiongxy
|
||||
* @create 2019-11-02 23:53
|
||||
*/
|
||||
@EnableSwagger2
|
||||
@Configuration
|
||||
public class Swagger2Config {
|
||||
|
||||
@Bean
|
||||
public Docket createRestApi() {
|
||||
return new Docket(DocumentationType.SWAGGER_2)
|
||||
.apiInfo(apiInfo())
|
||||
.select()
|
||||
//为当前包路径
|
||||
.apis(RequestHandlerSelectors.any())
|
||||
.paths(PathSelectors.any())
|
||||
.build();
|
||||
}
|
||||
|
||||
//构建 api文档的详细信息函数
|
||||
private ApiInfo apiInfo() {
|
||||
return new ApiInfoBuilder()
|
||||
//页面标题
|
||||
.title("功能测试")
|
||||
//创建人
|
||||
.contact(new Contact("xiongxy", "1179705413@qq.com", "1179705413@qq.com"))
|
||||
//版本号
|
||||
.version("1.0")
|
||||
//描述
|
||||
.description("API 描述")
|
||||
.build();
|
||||
}
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
package com.java2nb.common.config;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
|
||||
|
||||
@Component
|
||||
class WebConfigurer extends WebMvcConfigurerAdapter {
|
||||
@Autowired
|
||||
JnConfig jnConfig;
|
||||
@Override
|
||||
public void addResourceHandlers(ResourceHandlerRegistry registry) {
|
||||
registry.addResourceHandler("/files/**").addResourceLocations("file:///"+ jnConfig.getUploadPath());
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
package com.java2nb.common.controller;
|
||||
|
||||
import com.java2nb.system.domain.UserToken;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import com.java2nb.common.utils.ShiroUtils;
|
||||
import com.java2nb.system.domain.UserDO;
|
||||
|
||||
@Controller
|
||||
public class BaseController {
|
||||
public UserDO getUser() {
|
||||
return ShiroUtils.getUser();
|
||||
}
|
||||
|
||||
public Long getUserId() {
|
||||
return getUser().getUserId();
|
||||
}
|
||||
|
||||
public String getUsername() {
|
||||
return getUser().getUsername();
|
||||
}
|
||||
}
|
@ -0,0 +1,148 @@
|
||||
package com.java2nb.common.controller;
|
||||
|
||||
import com.java2nb.common.config.Constant;
|
||||
import com.java2nb.common.domain.DictDO;
|
||||
import com.java2nb.common.service.DictService;
|
||||
import com.java2nb.common.utils.PageBean;
|
||||
import com.java2nb.common.utils.Query;
|
||||
import com.java2nb.common.utils.R;
|
||||
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 java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 字典表
|
||||
* @author xiongxy
|
||||
* @email 1179705413@qq.com
|
||||
* @date 2019-09-29 18:28:07
|
||||
*/
|
||||
|
||||
@Controller
|
||||
@RequestMapping("/common/dict")
|
||||
public class DictController extends BaseController {
|
||||
@Autowired
|
||||
private DictService dictService;
|
||||
|
||||
@GetMapping()
|
||||
@RequiresPermissions("common:dict:dict")
|
||||
String dict() {
|
||||
return "common/dict/dict";
|
||||
}
|
||||
|
||||
@ResponseBody
|
||||
@GetMapping("/list")
|
||||
@RequiresPermissions("common:dict:dict")
|
||||
public PageBean list(@RequestParam Map<String, Object> params) {
|
||||
// 查询列表数据
|
||||
Query query = new Query(params);
|
||||
List<DictDO> dictList = dictService.list(query);
|
||||
int total = dictService.count(query);
|
||||
PageBean pageBean = new PageBean(dictList, total);
|
||||
return pageBean;
|
||||
}
|
||||
|
||||
@GetMapping("/add")
|
||||
@RequiresPermissions("common:dict:add")
|
||||
String add() {
|
||||
return "common/dict/add";
|
||||
}
|
||||
|
||||
@GetMapping("/edit/{id}")
|
||||
@RequiresPermissions("common:dict:edit")
|
||||
String edit(@PathVariable("id") Long id, Model model) {
|
||||
DictDO dict = dictService.get(id);
|
||||
model.addAttribute("dict", dict);
|
||||
return "common/dict/edit";
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存
|
||||
*/
|
||||
@ResponseBody
|
||||
@PostMapping("/save")
|
||||
@RequiresPermissions("common:dict:add")
|
||||
public R save(DictDO dict) {
|
||||
if (Constant.DEMO_ACCOUNT.equals(getUsername())) {
|
||||
return R.error(1, "演示系统不允许修改,完整体验请部署程序");
|
||||
}
|
||||
if (dictService.save(dict) > 0) {
|
||||
return R.ok();
|
||||
}
|
||||
return R.error();
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改
|
||||
*/
|
||||
@ResponseBody
|
||||
@RequestMapping("/update")
|
||||
@RequiresPermissions("common:dict:edit")
|
||||
public R update(DictDO dict) {
|
||||
if (Constant.DEMO_ACCOUNT.equals(getUsername())) {
|
||||
return R.error(1, "演示系统不允许修改,完整体验请部署程序");
|
||||
}
|
||||
dictService.update(dict);
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除
|
||||
*/
|
||||
@PostMapping("/remove")
|
||||
@ResponseBody
|
||||
@RequiresPermissions("common:dict:remove")
|
||||
public R remove(Long id) {
|
||||
if (Constant.DEMO_ACCOUNT.equals(getUsername())) {
|
||||
return R.error(1, "演示系统不允许修改,完整体验请部署程序");
|
||||
}
|
||||
if (dictService.remove(id) > 0) {
|
||||
return R.ok();
|
||||
}
|
||||
return R.error();
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除
|
||||
*/
|
||||
@PostMapping("/batchRemove")
|
||||
@ResponseBody
|
||||
@RequiresPermissions("common:dict:batchRemove")
|
||||
public R remove(@RequestParam("ids[]") Long[] ids) {
|
||||
if (Constant.DEMO_ACCOUNT.equals(getUsername())) {
|
||||
return R.error(1, "演示系统不允许修改,完整体验请部署程序");
|
||||
}
|
||||
dictService.batchRemove(ids);
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
@GetMapping("/type")
|
||||
@ResponseBody
|
||||
public List<DictDO> listType() {
|
||||
return dictService.listType();
|
||||
};
|
||||
|
||||
// 类别已经指定增加
|
||||
@GetMapping("/add/{type}/{description}")
|
||||
@RequiresPermissions("common:dict:add")
|
||||
String addD(Model model, @PathVariable("type") String type, @PathVariable("description") String description) {
|
||||
model.addAttribute("type", type);
|
||||
model.addAttribute("description", description);
|
||||
return "common/dict/add";
|
||||
}
|
||||
|
||||
@ResponseBody
|
||||
@GetMapping("/list/{type}")
|
||||
public List<DictDO> listByType(@PathVariable("type") String type) {
|
||||
// 查询列表数据
|
||||
Map<String, Object> map = new HashMap<>(16);
|
||||
map.put("type", type);
|
||||
List<DictDO> dictList = dictService.list(map);
|
||||
return dictList;
|
||||
}
|
||||
}
|
@ -0,0 +1,196 @@
|
||||
package com.java2nb.common.controller;
|
||||
|
||||
import com.java2nb.common.config.JnConfig;
|
||||
import com.java2nb.common.domain.FileDO;
|
||||
import com.java2nb.common.service.FileService;
|
||||
import com.java2nb.common.utils.*;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
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.multipart.MultipartFile;
|
||||
|
||||
import java.io.*;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 文件上传
|
||||
*
|
||||
* @author xiongxy
|
||||
* @email 1179705413@qq.com
|
||||
* @date 2019-09-19 16:02:20
|
||||
*/
|
||||
@Controller
|
||||
@RequestMapping("/common/sysFile")
|
||||
public class FileController extends BaseController {
|
||||
|
||||
@Autowired
|
||||
private FileService sysFileService;
|
||||
|
||||
@Autowired
|
||||
private JnConfig jnConfig;
|
||||
|
||||
@GetMapping()
|
||||
@RequiresPermissions("common:sysFile:sysFile")
|
||||
String sysFile(Model model) {
|
||||
Map<String, Object> params = new HashMap<>(16);
|
||||
return "common/file/file";
|
||||
}
|
||||
|
||||
@ResponseBody
|
||||
@GetMapping("/list")
|
||||
@RequiresPermissions("common:sysFile:sysFile")
|
||||
public PageBean list(@RequestParam Map<String, Object> params) {
|
||||
// 查询列表数据
|
||||
Query query = new Query(params);
|
||||
List<FileDO> sysFileList = sysFileService.list(query);
|
||||
int total = sysFileService.count(query);
|
||||
PageBean pageBean = new PageBean(sysFileList, total);
|
||||
return pageBean;
|
||||
}
|
||||
|
||||
@GetMapping("/add")
|
||||
// @RequiresPermissions("common:bComments")
|
||||
String add() {
|
||||
return "common/sysFile/add";
|
||||
}
|
||||
|
||||
@GetMapping("/edit")
|
||||
// @RequiresPermissions("common:bComments")
|
||||
String edit(Long id, Model model) {
|
||||
FileDO sysFile = sysFileService.get(id);
|
||||
model.addAttribute("sysFile", sysFile);
|
||||
return "common/sysFile/edit";
|
||||
}
|
||||
|
||||
/**
|
||||
* 信息
|
||||
*/
|
||||
@RequestMapping("/info/{id}")
|
||||
@RequiresPermissions("common:info")
|
||||
public R info(@PathVariable("id") Long id) {
|
||||
FileDO sysFile = sysFileService.get(id);
|
||||
return R.ok().put("sysFile", sysFile);
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存
|
||||
*/
|
||||
@ResponseBody
|
||||
@PostMapping("/save")
|
||||
@RequiresPermissions("common:save")
|
||||
public R save(FileDO sysFile) {
|
||||
if (sysFileService.save(sysFile) > 0) {
|
||||
return R.ok();
|
||||
}
|
||||
return R.error();
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改
|
||||
*/
|
||||
@RequestMapping("/update")
|
||||
@RequiresPermissions("common:update")
|
||||
public R update(@RequestBody FileDO sysFile) {
|
||||
sysFileService.update(sysFile);
|
||||
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除
|
||||
*/
|
||||
@PostMapping("/remove")
|
||||
@ResponseBody
|
||||
// @RequiresPermissions("common:remove")
|
||||
public R remove(Long id, HttpServletRequest request) {
|
||||
if ("test".equals(getUsername())) {
|
||||
return R.error(1, "演示系统不允许修改,完整体验请部署程序");
|
||||
}
|
||||
String fileName = jnConfig.getUploadPath() + sysFileService.get(id).getUrl().replace("/files/", "");
|
||||
if (sysFileService.remove(id) > 0) {
|
||||
boolean b = FileUtil.deleteFile(fileName);
|
||||
if (!b) {
|
||||
return R.error("数据库记录删除成功,文件删除失败");
|
||||
}
|
||||
return R.ok();
|
||||
} else {
|
||||
return R.error();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除
|
||||
*/
|
||||
@PostMapping("/batchRemove")
|
||||
@ResponseBody
|
||||
@RequiresPermissions("common:remove")
|
||||
public R remove(@RequestParam("ids[]") Long[] ids) {
|
||||
if ("test".equals(getUsername())) {
|
||||
return R.error(1, "演示系统不允许修改,完整体验请部署程序");
|
||||
}
|
||||
sysFileService.batchRemove(ids);
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
@ResponseBody
|
||||
@PostMapping("/upload")
|
||||
R upload(@RequestParam("file") MultipartFile file, HttpServletRequest request) {
|
||||
if ("test".equals(getUsername())) {
|
||||
return R.error(1, "演示系统不允许修改,完整体验请部署程序");
|
||||
}
|
||||
Date date = new Date();
|
||||
String year = DateUtils.format(date,DateUtils.YEAR_PATTERN);
|
||||
String month = DateUtils.format(date,DateUtils.MONTH_PATTERN);
|
||||
String day = DateUtils.format(date,DateUtils.DAY_PATTERN);
|
||||
|
||||
String fileName = file.getOriginalFilename();
|
||||
String fileDir = year+"/"+month+"/"+day + "/";
|
||||
fileName = FileUtil.renameToUUID(fileName);
|
||||
FileDO sysFile = new FileDO(FileType.fileType(fileName), "/files/" + fileDir + fileName, date);
|
||||
try {
|
||||
FileUtil.uploadFile(file.getBytes(), jnConfig.getUploadPath()+fileDir, fileName);
|
||||
} catch (Exception e) {
|
||||
return R.error();
|
||||
}
|
||||
|
||||
if (sysFileService.save(sysFile) > 0) {
|
||||
return R.ok().put("fileName",sysFile.getUrl());
|
||||
}
|
||||
return R.error();
|
||||
}
|
||||
|
||||
/**
|
||||
* 文件下载
|
||||
*/
|
||||
@RequestMapping(value = "/download")
|
||||
public void fileDownload(String filePath,String fileName, HttpServletResponse resp) throws Exception {
|
||||
String realFilePath = jnConfig.getUploadPath() + filePath;
|
||||
InputStream in = new FileInputStream(realFilePath);
|
||||
//设置响应头,对文件进行url编码
|
||||
fileName = URLEncoder.encode(fileName, "UTF-8");
|
||||
resp.setHeader("Content-Disposition", "attachment;filename=" + fileName);
|
||||
|
||||
resp.setContentLength(in.available());
|
||||
|
||||
OutputStream out = resp.getOutputStream();
|
||||
byte[] b = new byte[1024];
|
||||
int len = 0;
|
||||
while ((len = in.read(b)) != -1) {
|
||||
out.write(b, 0, len);
|
||||
}
|
||||
out.flush();
|
||||
out.close();
|
||||
in.close();
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,157 @@
|
||||
package com.java2nb.common.controller;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.java2nb.common.domain.GenColumnsDO;
|
||||
import com.java2nb.common.service.GeneratorService;
|
||||
import com.java2nb.common.utils.GenUtils;
|
||||
import com.java2nb.common.utils.PageBean;
|
||||
import com.java2nb.common.utils.R;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import lombok.SneakyThrows;
|
||||
import org.apache.commons.configuration.Configuration;
|
||||
import org.apache.commons.configuration.ConfigurationException;
|
||||
import org.apache.commons.configuration.PropertiesConfiguration;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@RequestMapping("/common/generator")
|
||||
@Controller
|
||||
public class GeneratorController {
|
||||
String prefix = "common/generator";
|
||||
@Autowired
|
||||
GeneratorService generatorService;
|
||||
|
||||
@Autowired
|
||||
private ObjectMapper objectMapper;
|
||||
|
||||
@GetMapping()
|
||||
String generator() {
|
||||
return prefix + "/list";
|
||||
}
|
||||
|
||||
@ResponseBody
|
||||
@GetMapping("/list")
|
||||
List<Map<String, Object>> list(String tableName) {
|
||||
List<Map<String, Object>> list = generatorService.list(tableName);
|
||||
return list;
|
||||
}
|
||||
|
||||
;
|
||||
|
||||
@RequestMapping("/downLoadCode/{tableName}")
|
||||
public void downLoadCode(HttpServletRequest request, HttpServletResponse response,
|
||||
@PathVariable("tableName") String tableName) throws IOException {
|
||||
String[] tableNames = new String[]{tableName};
|
||||
byte[] data = generatorService.downloadCode(tableNames);
|
||||
response.reset();
|
||||
response.setHeader("Content-Disposition", "attachment; filename=\"java2nb.zip\"");
|
||||
response.addHeader("Content-Length", "" + data.length);
|
||||
response.setContentType("application/octet-stream; charset=UTF-8");
|
||||
|
||||
IOUtils.write(data, response.getOutputStream());
|
||||
}
|
||||
|
||||
@ResponseBody
|
||||
@PostMapping("/genCode")
|
||||
public R genCode(String tableName) {
|
||||
String[] tableNames = new String[]{tableName};
|
||||
generatorService.generatorCode(tableNames);
|
||||
return R.ok("代码生成成功,请到本地项目中查看!");
|
||||
}
|
||||
|
||||
@RequestMapping("/batchDownload")
|
||||
public void batchDownload(HttpServletRequest request, HttpServletResponse response, String tables) throws IOException {
|
||||
String[] tableNames = new String[]{};
|
||||
tableNames = JSON.parseArray(tables).toArray(tableNames);
|
||||
byte[] data = generatorService.downloadCode(tableNames);
|
||||
response.reset();
|
||||
response.setHeader("Content-Disposition", "attachment; filename=\"java2nb.zip\"");
|
||||
response.addHeader("Content-Length", "" + data.length);
|
||||
response.setContentType("application/octet-stream; charset=UTF-8");
|
||||
|
||||
IOUtils.write(data, response.getOutputStream());
|
||||
}
|
||||
|
||||
@ResponseBody
|
||||
@PostMapping("/batchCode")
|
||||
public R batchCode(String tables) {
|
||||
String[] tableNames = new String[]{};
|
||||
tableNames = JSON.parseArray(tables).toArray(tableNames);
|
||||
generatorService.generatorCode(tableNames);
|
||||
return R.ok("代码批量生成成功,请到本地项目中查看!");
|
||||
}
|
||||
|
||||
@GetMapping("/edit")
|
||||
public String edit(Model model) {
|
||||
Configuration conf = GenUtils.getConfig();
|
||||
Map<String, Object> property = new HashMap<>(16);
|
||||
property.put("author", conf.getProperty("author"));
|
||||
property.put("email", conf.getProperty("email"));
|
||||
property.put("package", conf.getProperty("package"));
|
||||
property.put("autoRemovePre", conf.getProperty("autoRemovePre"));
|
||||
property.put("tablePrefix", conf.getProperty("tablePrefix"));
|
||||
property.put("srcPath", conf.getProperty("srcPath"));
|
||||
model.addAttribute("property", property);
|
||||
return prefix + "/edit";
|
||||
}
|
||||
|
||||
@ResponseBody
|
||||
@PostMapping("/update")
|
||||
R update(@RequestParam Map<String, Object> map) {
|
||||
try {
|
||||
PropertiesConfiguration conf = new PropertiesConfiguration("generator.properties");
|
||||
conf.setProperty("author", map.get("author"));
|
||||
conf.setProperty("email", map.get("email"));
|
||||
conf.setProperty("package", map.get("package"));
|
||||
conf.setProperty("autoRemovePre", map.get("autoRemovePre"));
|
||||
conf.setProperty("tablePrefix", map.get("tablePrefix"));
|
||||
conf.setProperty("srcPath", map.get("srcPath"));
|
||||
conf.save();
|
||||
} catch (ConfigurationException e) {
|
||||
return R.error("保存配置文件出错");
|
||||
}
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
@GetMapping("/genColumns")
|
||||
String genColumns(String tableName, Model model) {
|
||||
model.addAttribute("tableName", tableName);
|
||||
return "common/genColumns/genColumns";
|
||||
}
|
||||
|
||||
|
||||
@ResponseBody
|
||||
@GetMapping("/genColumns/list")
|
||||
@SneakyThrows
|
||||
public R genColumnsList(String tableName) {
|
||||
List<GenColumnsDO> genColumns = generatorService.listColumnsByTableName(tableName);
|
||||
int total = genColumns.size();
|
||||
PageBean pageBean = new PageBean(genColumns, total);
|
||||
return R.ok().put("data", pageBean);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 保存
|
||||
*/
|
||||
@ApiOperation(value = "新增", notes = "新增")
|
||||
@ResponseBody
|
||||
@PostMapping("/genColumns/save")
|
||||
public R save(@RequestBody List<GenColumnsDO> list) {
|
||||
generatorService.genColumnsSave(list);
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,57 @@
|
||||
package com.java2nb.common.controller;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
|
||||
import com.java2nb.common.domain.LogDO;
|
||||
import com.java2nb.common.domain.PageDO;
|
||||
import com.java2nb.common.service.LogService;
|
||||
import com.java2nb.common.utils.Query;
|
||||
import com.java2nb.common.utils.R;
|
||||
|
||||
@RequestMapping("/common/log")
|
||||
@Controller
|
||||
public class LogController {
|
||||
@Autowired
|
||||
LogService logService;
|
||||
String prefix = "common/log";
|
||||
|
||||
@GetMapping()
|
||||
String log() {
|
||||
return prefix + "/log";
|
||||
}
|
||||
|
||||
@ResponseBody
|
||||
@GetMapping("/list")
|
||||
PageDO<LogDO> list(@RequestParam Map<String, Object> params) {
|
||||
Query query = new Query(params);
|
||||
PageDO<LogDO> page = logService.queryList(query);
|
||||
return page;
|
||||
}
|
||||
|
||||
@ResponseBody
|
||||
@PostMapping("/remove")
|
||||
R remove(Long id) {
|
||||
if (logService.remove(id)>0) {
|
||||
return R.ok();
|
||||
}
|
||||
return R.error();
|
||||
}
|
||||
|
||||
@ResponseBody
|
||||
@PostMapping("/batchRemove")
|
||||
R batchRemove(@RequestParam("ids[]") Long[] ids) {
|
||||
int r = logService.batchRemove(ids);
|
||||
if (r > 0) {
|
||||
return R.ok();
|
||||
}
|
||||
return R.error();
|
||||
}
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
package com.java2nb.common.dao;
|
||||
|
||||
import com.java2nb.common.domain.DictDO;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
/**
|
||||
* 字典表
|
||||
*
|
||||
* @author xiongxy
|
||||
* @email 1179705413@qq.com
|
||||
* @date 2019-10-03 15:45:42
|
||||
*/
|
||||
@Mapper
|
||||
public interface DictDao {
|
||||
|
||||
DictDO get(Long id);
|
||||
|
||||
List<DictDO> list(Map<String, Object> map);
|
||||
|
||||
int count(Map<String, Object> map);
|
||||
|
||||
int save(DictDO dict);
|
||||
|
||||
int update(DictDO dict);
|
||||
|
||||
int remove(Long id);
|
||||
|
||||
int batchRemove(Long[] ids);
|
||||
|
||||
List<DictDO> listType();
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
package com.java2nb.common.dao;
|
||||
|
||||
import com.java2nb.common.domain.FileDO;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
/**
|
||||
* 文件上传
|
||||
* @author xiongxy
|
||||
* @email 1179705413@qq.com
|
||||
* @date 2019-10-03 15:45:42
|
||||
*/
|
||||
@Mapper
|
||||
public interface FileDao {
|
||||
|
||||
FileDO get(Long id);
|
||||
|
||||
List<FileDO> list(Map<String,Object> map);
|
||||
|
||||
int count(Map<String,Object> map);
|
||||
|
||||
int save(FileDO file);
|
||||
|
||||
int update(FileDO file);
|
||||
|
||||
int remove(Long id);
|
||||
|
||||
int batchRemove(Long[] ids);
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
package com.java2nb.common.dao;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.java2nb.common.domain.GenColumnsDO;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author xiongxy
|
||||
* @email 1179705413@qq.com
|
||||
* @date 2019-11-22 10:39:29
|
||||
*/
|
||||
@Mapper
|
||||
public interface GenColumnsDao {
|
||||
|
||||
|
||||
GenColumnsDO get(Long id);
|
||||
|
||||
List<GenColumnsDO> list(Map<String,Object> map);
|
||||
|
||||
int count(Map<String,Object> map);
|
||||
|
||||
int save(GenColumnsDO genColumns);
|
||||
|
||||
int update(GenColumnsDO genColumns);
|
||||
|
||||
int remove(Long id);
|
||||
|
||||
int batchRemove(Long[] ids);
|
||||
|
||||
|
||||
void saveBatch(List<GenColumnsDO> list);
|
||||
|
||||
void deleteByTableName(@Param("tableName") String tableName);
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
package com.java2nb.common.dao;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.apache.ibatis.annotations.Select;
|
||||
|
||||
public interface GeneratorMapper {
|
||||
@Select("select table_name tableName, engine, table_comment tableComment, create_time createTime from information_schema.tables"
|
||||
+ " where table_schema = (select database()) and table_name like concat('%',#{tableName},'%')")
|
||||
List<Map<String, Object>> list(@Param("tableName") String tableName);
|
||||
|
||||
@Select("select count(*) from information_schema.tables where table_schema = (select database())")
|
||||
int count(Map<String, Object> map);
|
||||
|
||||
@Select("select table_name tableName, engine, table_comment tableComment, create_time createTime from information_schema.tables \r\n"
|
||||
+ " where table_schema = (select database()) and table_name = #{tableName}")
|
||||
Map<String, String> get(String tableName);
|
||||
|
||||
@Select("select column_name columnName, data_type dataType, column_comment columnComment, column_key columnKey, extra from information_schema.columns\r\n"
|
||||
+ " where table_name = #{tableName} and table_schema = (select database()) order by ordinal_position")
|
||||
List<Map<String, String>> listColumns(String tableName);
|
||||
|
||||
@Select("select column_name columnName, data_type dataType, column_comment columnComment, column_key columnKey, extra from information_schema.columns\r\n"
|
||||
+ " where table_name = #{tableName} and table_schema = (select database()) and column_key = 'PRI' limit 1")
|
||||
Map<String, String> getPriColumn(String tableName);
|
||||
}
|
32
novel-admin/src/main/java/com/java2nb/common/dao/LogDao.java
Normal file
32
novel-admin/src/main/java/com/java2nb/common/dao/LogDao.java
Normal file
@ -0,0 +1,32 @@
|
||||
package com.java2nb.common.dao;
|
||||
|
||||
import com.java2nb.common.domain.LogDO;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
/**
|
||||
* 系统日志
|
||||
* @author xiongxy
|
||||
* @email 1179705413@qq.com
|
||||
* @date 2019-10-03 15:45:42
|
||||
*/
|
||||
@Mapper
|
||||
public interface LogDao {
|
||||
|
||||
LogDO get(Long id);
|
||||
|
||||
List<LogDO> list(Map<String,Object> map);
|
||||
|
||||
int count(Map<String,Object> map);
|
||||
|
||||
int save(LogDO log);
|
||||
|
||||
int update(LogDO log);
|
||||
|
||||
int remove(Long id);
|
||||
|
||||
int batchRemove(Long[] ids);
|
||||
}
|
@ -0,0 +1,93 @@
|
||||
package com.java2nb.common.domain;
|
||||
|
||||
/**
|
||||
* 列的属性
|
||||
*
|
||||
*
|
||||
*/
|
||||
public class ColumnDO {
|
||||
// 列名
|
||||
private String columnName;
|
||||
// 列名类型
|
||||
private String dataType;
|
||||
// 列名备注
|
||||
private String comments;
|
||||
|
||||
// 属性名称(第一个字母大写),如:user_name => UserName
|
||||
private String attrName;
|
||||
// 属性名称(第一个字母小写),如:user_name => userName
|
||||
private String attrname;
|
||||
// 属性类型
|
||||
private String attrType;
|
||||
// auto_increment
|
||||
private String extra;
|
||||
|
||||
public String getColumnName() {
|
||||
return columnName;
|
||||
}
|
||||
|
||||
public void setColumnName(String columnName) {
|
||||
this.columnName = columnName;
|
||||
}
|
||||
|
||||
public String getDataType() {
|
||||
return dataType;
|
||||
}
|
||||
|
||||
public void setDataType(String dataType) {
|
||||
this.dataType = dataType;
|
||||
}
|
||||
|
||||
public String getComments() {
|
||||
return comments;
|
||||
}
|
||||
|
||||
public void setComments(String comments) {
|
||||
this.comments = comments;
|
||||
}
|
||||
|
||||
public String getAttrname() {
|
||||
return attrname;
|
||||
}
|
||||
|
||||
public void setAttrname(String attrname) {
|
||||
this.attrname = attrname;
|
||||
}
|
||||
|
||||
public String getAttrName() {
|
||||
return attrName;
|
||||
}
|
||||
|
||||
public void setAttrName(String attrName) {
|
||||
this.attrName = attrName;
|
||||
}
|
||||
|
||||
public String getAttrType() {
|
||||
return attrType;
|
||||
}
|
||||
|
||||
public void setAttrType(String attrType) {
|
||||
this.attrType = attrType;
|
||||
}
|
||||
|
||||
public String getExtra() {
|
||||
return extra;
|
||||
}
|
||||
|
||||
public void setExtra(String extra) {
|
||||
this.extra = extra;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ColumnDO{" +
|
||||
"columnName='" + columnName + '\'' +
|
||||
", dataType='" + dataType + '\'' +
|
||||
", comments='" + comments + '\'' +
|
||||
", attrName='" + attrName + '\'' +
|
||||
", attrname='" + attrname + '\'' +
|
||||
", attrType='" + attrType + '\'' +
|
||||
", extra='" + extra + '\'' +
|
||||
'}';
|
||||
}
|
||||
}
|
221
novel-admin/src/main/java/com/java2nb/common/domain/DictDO.java
Normal file
221
novel-admin/src/main/java/com/java2nb/common/domain/DictDO.java
Normal file
@ -0,0 +1,221 @@
|
||||
package com.java2nb.common.domain;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Date;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 字典表
|
||||
*
|
||||
* @author xiongxy
|
||||
* @email 1179705413@qq.com
|
||||
* @date 2019-09-29 18:28:07
|
||||
*/
|
||||
public class DictDO implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
//编号
|
||||
private Long id;
|
||||
//标签名
|
||||
private String name;
|
||||
//数据值
|
||||
private String value;
|
||||
//类型
|
||||
private String type;
|
||||
//描述
|
||||
private String description;
|
||||
//排序(升序)
|
||||
private BigDecimal sort;
|
||||
//父级编号
|
||||
private Long parentId;
|
||||
//创建者
|
||||
private Integer createBy;
|
||||
//创建时间
|
||||
private Date createDate;
|
||||
//更新者
|
||||
private Long updateBy;
|
||||
//更新时间
|
||||
private Date updateDate;
|
||||
//备注信息
|
||||
private String remarks;
|
||||
//删除标记
|
||||
private String delFlag;
|
||||
|
||||
/**
|
||||
* 设置:编号
|
||||
*/
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
/**
|
||||
* 获取:编号
|
||||
*/
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
/**
|
||||
* 设置:标签名
|
||||
*/
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
/**
|
||||
* 获取:标签名
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
/**
|
||||
* 设置:数据值
|
||||
*/
|
||||
public void setValue(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
/**
|
||||
* 获取:数据值
|
||||
*/
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
/**
|
||||
* 设置:类型
|
||||
*/
|
||||
public void setType(String type) {
|
||||
this.type = type;
|
||||
}
|
||||
/**
|
||||
* 获取:类型
|
||||
*/
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
/**
|
||||
* 设置:描述
|
||||
*/
|
||||
public void setDescription(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
/**
|
||||
* 获取:描述
|
||||
*/
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
/**
|
||||
* 设置:排序(升序)
|
||||
*/
|
||||
public void setSort(BigDecimal sort) {
|
||||
this.sort = sort;
|
||||
}
|
||||
/**
|
||||
* 获取:排序(升序)
|
||||
*/
|
||||
public BigDecimal getSort() {
|
||||
return sort;
|
||||
}
|
||||
/**
|
||||
* 设置:父级编号
|
||||
*/
|
||||
public void setParentId(Long parentId) {
|
||||
this.parentId = parentId;
|
||||
}
|
||||
/**
|
||||
* 获取:父级编号
|
||||
*/
|
||||
public Long getParentId() {
|
||||
return parentId;
|
||||
}
|
||||
/**
|
||||
* 设置:创建者
|
||||
*/
|
||||
public void setCreateBy(Integer createBy) {
|
||||
this.createBy = createBy;
|
||||
}
|
||||
/**
|
||||
* 获取:创建者
|
||||
*/
|
||||
public Integer getCreateBy() {
|
||||
return createBy;
|
||||
}
|
||||
/**
|
||||
* 设置:创建时间
|
||||
*/
|
||||
public void setCreateDate(Date createDate) {
|
||||
this.createDate = createDate;
|
||||
}
|
||||
/**
|
||||
* 获取:创建时间
|
||||
*/
|
||||
public Date getCreateDate() {
|
||||
return createDate;
|
||||
}
|
||||
/**
|
||||
* 设置:更新者
|
||||
*/
|
||||
public void setUpdateBy(Long updateBy) {
|
||||
this.updateBy = updateBy;
|
||||
}
|
||||
/**
|
||||
* 获取:更新者
|
||||
*/
|
||||
public Long getUpdateBy() {
|
||||
return updateBy;
|
||||
}
|
||||
/**
|
||||
* 设置:更新时间
|
||||
*/
|
||||
public void setUpdateDate(Date updateDate) {
|
||||
this.updateDate = updateDate;
|
||||
}
|
||||
/**
|
||||
* 获取:更新时间
|
||||
*/
|
||||
public Date getUpdateDate() {
|
||||
return updateDate;
|
||||
}
|
||||
/**
|
||||
* 设置:备注信息
|
||||
*/
|
||||
public void setRemarks(String remarks) {
|
||||
this.remarks = remarks;
|
||||
}
|
||||
/**
|
||||
* 获取:备注信息
|
||||
*/
|
||||
public String getRemarks() {
|
||||
return remarks;
|
||||
}
|
||||
/**
|
||||
* 设置:删除标记
|
||||
*/
|
||||
public void setDelFlag(String delFlag) {
|
||||
this.delFlag = delFlag;
|
||||
}
|
||||
/**
|
||||
* 获取:删除标记
|
||||
*/
|
||||
public String getDelFlag() {
|
||||
return delFlag;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "DictDO{" +
|
||||
"id=" + id +
|
||||
", name='" + name + '\'' +
|
||||
", value='" + value + '\'' +
|
||||
", type='" + type + '\'' +
|
||||
", description='" + description + '\'' +
|
||||
", sort=" + sort +
|
||||
", parentId=" + parentId +
|
||||
", createBy=" + createBy +
|
||||
", createDate=" + createDate +
|
||||
", updateBy=" + updateBy +
|
||||
", updateDate=" + updateDate +
|
||||
", remarks='" + remarks + '\'' +
|
||||
", delFlag='" + delFlag + '\'' +
|
||||
'}';
|
||||
}
|
||||
}
|
104
novel-admin/src/main/java/com/java2nb/common/domain/FileDO.java
Normal file
104
novel-admin/src/main/java/com/java2nb/common/domain/FileDO.java
Normal file
@ -0,0 +1,104 @@
|
||||
package com.java2nb.common.domain;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 文件上传
|
||||
*
|
||||
* @author xiongxy
|
||||
* @email 1179705413@qq.com
|
||||
* @date 2019-09-19 16:02:20
|
||||
*/
|
||||
public class FileDO implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
//
|
||||
private Long id;
|
||||
// 文件类型
|
||||
private Integer type;
|
||||
// URL地址
|
||||
private String url;
|
||||
// 创建时间
|
||||
private Date createDate;
|
||||
|
||||
|
||||
public FileDO() {
|
||||
super();
|
||||
}
|
||||
|
||||
|
||||
public FileDO(Integer type, String url, Date createDate) {
|
||||
super();
|
||||
this.type = type;
|
||||
this.url = url;
|
||||
this.createDate = createDate;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 设置:
|
||||
*/
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取:
|
||||
*/
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置:文件类型
|
||||
*/
|
||||
public void setType(Integer type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取:文件类型
|
||||
*/
|
||||
public Integer getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置:URL地址
|
||||
*/
|
||||
public void setUrl(String url) {
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取:URL地址
|
||||
*/
|
||||
public String getUrl() {
|
||||
return url;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置:创建时间
|
||||
*/
|
||||
public void setCreateDate(Date createDate) {
|
||||
this.createDate = createDate;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取:创建时间
|
||||
*/
|
||||
public Date getCreateDate() {
|
||||
return createDate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "FileDO{" +
|
||||
"id=" + id +
|
||||
", type=" + type +
|
||||
", url='" + url + '\'' +
|
||||
", createDate=" + createDate +
|
||||
'}';
|
||||
}
|
||||
}
|
@ -0,0 +1,163 @@
|
||||
package com.java2nb.common.domain;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
|
||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||
import com.java2nb.common.jsonserializer.LongToStringSerializer;
|
||||
import lombok.Data;
|
||||
|
||||
|
||||
/**
|
||||
* @author xiongxy
|
||||
* @email 1179705413@qq.com
|
||||
* @date 2019-11-22 18:03:46
|
||||
*/
|
||||
public class GenColumnsDO implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
//主键
|
||||
//java中的long能表示的范围比js中number大,也就意味着部分数值在js中存不下(变成不准确的值)
|
||||
//所以通过序列化成字符串来解决
|
||||
@JsonSerialize(using = LongToStringSerializer.class)
|
||||
private Long id;
|
||||
//表名
|
||||
private String tableName;
|
||||
//列名
|
||||
private String columnName;
|
||||
//列类型
|
||||
private String columnType;
|
||||
//映射java类型
|
||||
private String javaType;
|
||||
//列注释
|
||||
private String columnComment;
|
||||
//列排序(升序)
|
||||
private Integer columnSort;
|
||||
//列标签名
|
||||
private String columnLabel;
|
||||
//页面显示类型:1、文本框 2、下拉框 3、数值4、日期 5、文本域6、富文本 7、上传图片【单文件】 8、上传图片【多文件】9、上传文件【单文件】 10、上传文件【多文件】11、隐藏域 12、不显示
|
||||
private Integer pageType;
|
||||
//是否必填
|
||||
private Integer isRequired;
|
||||
//页面显示为下拉时使用,字典类型从字典表中取出
|
||||
private String dictType;
|
||||
|
||||
// 属性名称(第一个字母大写),如:user_name => UserName
|
||||
private String attrName;
|
||||
// 属性名称(第一个字母小写),如:user_name => userName
|
||||
private String attrname;
|
||||
|
||||
private String extra;
|
||||
|
||||
public String getExtra() {
|
||||
return extra;
|
||||
}
|
||||
|
||||
public void setExtra(String extra) {
|
||||
this.extra = extra;
|
||||
}
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getTableName() {
|
||||
return tableName;
|
||||
}
|
||||
|
||||
public void setTableName(String tableName) {
|
||||
this.tableName = tableName;
|
||||
}
|
||||
|
||||
public String getColumnName() {
|
||||
return columnName;
|
||||
}
|
||||
|
||||
public void setColumnName(String columnName) {
|
||||
this.columnName = columnName;
|
||||
}
|
||||
|
||||
public String getColumnType() {
|
||||
return columnType;
|
||||
}
|
||||
|
||||
public void setColumnType(String columnType) {
|
||||
this.columnType = columnType;
|
||||
}
|
||||
|
||||
public String getJavaType() {
|
||||
return javaType;
|
||||
}
|
||||
|
||||
public void setJavaType(String javaType) {
|
||||
this.javaType = javaType;
|
||||
}
|
||||
|
||||
public String getColumnComment() {
|
||||
return columnComment;
|
||||
}
|
||||
|
||||
public void setColumnComment(String columnComment) {
|
||||
this.columnComment = columnComment;
|
||||
}
|
||||
|
||||
public Integer getColumnSort() {
|
||||
return columnSort;
|
||||
}
|
||||
|
||||
public void setColumnSort(Integer columnSort) {
|
||||
this.columnSort = columnSort;
|
||||
}
|
||||
|
||||
public String getColumnLabel() {
|
||||
return columnLabel;
|
||||
}
|
||||
|
||||
public void setColumnLabel(String columnLabel) {
|
||||
this.columnLabel = columnLabel;
|
||||
}
|
||||
|
||||
public Integer getPageType() {
|
||||
return pageType;
|
||||
}
|
||||
|
||||
public void setPageType(Integer pageType) {
|
||||
this.pageType = pageType;
|
||||
}
|
||||
|
||||
public Integer getIsRequired() {
|
||||
return isRequired;
|
||||
}
|
||||
|
||||
public void setIsRequired(Integer isRequired) {
|
||||
this.isRequired = isRequired;
|
||||
}
|
||||
|
||||
public String getDictType() {
|
||||
return dictType;
|
||||
}
|
||||
|
||||
public void setDictType(String dictType) {
|
||||
this.dictType = dictType;
|
||||
}
|
||||
|
||||
public String getAttrName() {
|
||||
return attrName;
|
||||
}
|
||||
|
||||
public void setAttrName(String attrName) {
|
||||
this.attrName = attrName;
|
||||
}
|
||||
|
||||
public String getAttrname() {
|
||||
return attrname;
|
||||
}
|
||||
|
||||
public void setAttrname(String attrname) {
|
||||
this.attrname = attrname;
|
||||
}
|
||||
}
|
112
novel-admin/src/main/java/com/java2nb/common/domain/LogDO.java
Normal file
112
novel-admin/src/main/java/com/java2nb/common/domain/LogDO.java
Normal file
@ -0,0 +1,112 @@
|
||||
package com.java2nb.common.domain;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
public class LogDO {
|
||||
private Long id;
|
||||
|
||||
private Long userId;
|
||||
|
||||
private String username;
|
||||
|
||||
private String operation;
|
||||
|
||||
private Integer time;
|
||||
|
||||
private String method;
|
||||
|
||||
private String params;
|
||||
|
||||
private String ip;
|
||||
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date gmtCreate;
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public Long getUserId() {
|
||||
return userId;
|
||||
}
|
||||
|
||||
public void setUserId(Long userId) {
|
||||
this.userId = userId;
|
||||
}
|
||||
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
||||
public void setUsername(String username) {
|
||||
this.username = username == null ? null : username.trim();
|
||||
}
|
||||
|
||||
public String getOperation() {
|
||||
return operation;
|
||||
}
|
||||
|
||||
public void setOperation(String operation) {
|
||||
this.operation = operation == null ? null : operation.trim();
|
||||
}
|
||||
|
||||
public Integer getTime() {
|
||||
return time;
|
||||
}
|
||||
|
||||
public void setTime(Integer time) {
|
||||
this.time = time;
|
||||
}
|
||||
|
||||
public String getMethod() {
|
||||
return method;
|
||||
}
|
||||
|
||||
public void setMethod(String method) {
|
||||
this.method = method == null ? null : method.trim();
|
||||
}
|
||||
|
||||
public String getParams() {
|
||||
return params;
|
||||
}
|
||||
|
||||
public void setParams(String params) {
|
||||
this.params = params == null ? null : params.trim();
|
||||
}
|
||||
|
||||
public String getIp() {
|
||||
return ip;
|
||||
}
|
||||
|
||||
public void setIp(String ip) {
|
||||
this.ip = ip == null ? null : ip.trim();
|
||||
}
|
||||
|
||||
public Date getGmtCreate() {
|
||||
return gmtCreate;
|
||||
}
|
||||
|
||||
public void setGmtCreate(Date gmtCreate) {
|
||||
this.gmtCreate = gmtCreate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "LogDO{" +
|
||||
"id=" + id +
|
||||
", userId=" + userId +
|
||||
", username='" + username + '\'' +
|
||||
", operation='" + operation + '\'' +
|
||||
", time=" + time +
|
||||
", method='" + method + '\'' +
|
||||
", params='" + params + '\'' +
|
||||
", ip='" + ip + '\'' +
|
||||
", gmtCreate=" + gmtCreate +
|
||||
'}';
|
||||
}
|
||||
}
|
@ -0,0 +1,86 @@
|
||||
package com.java2nb.common.domain;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class PageDO<T> {
|
||||
|
||||
private int offset;
|
||||
private int limit;
|
||||
private int total;
|
||||
private Map<String, Object> params;
|
||||
private String param;
|
||||
private List<T> rows;
|
||||
|
||||
public PageDO() {
|
||||
super();
|
||||
this.offset = 0;
|
||||
this.limit = 10;
|
||||
this.total = 1;
|
||||
this.params = new HashMap<>();
|
||||
this.param = "";
|
||||
this.rows = new ArrayList<>();
|
||||
}
|
||||
|
||||
public int getOffset() {
|
||||
return offset;
|
||||
}
|
||||
|
||||
public void setOffset(int offset) {
|
||||
this.offset = offset;
|
||||
}
|
||||
|
||||
public int getLimit() {
|
||||
return limit;
|
||||
}
|
||||
|
||||
public void setLimit(int limit) {
|
||||
this.limit = limit;
|
||||
}
|
||||
|
||||
public int getTotal() {
|
||||
return total;
|
||||
}
|
||||
|
||||
public void setTotal(int total) {
|
||||
this.total = total;
|
||||
}
|
||||
|
||||
public Map<String, Object> getParams() {
|
||||
return params;
|
||||
}
|
||||
|
||||
public void setParams(Map<String, Object> params) {
|
||||
this.params = params;
|
||||
}
|
||||
|
||||
public List<T> getRows() {
|
||||
return rows;
|
||||
}
|
||||
|
||||
public void setRows(List<T> rows) {
|
||||
this.rows = rows;
|
||||
}
|
||||
|
||||
public String getParam() {
|
||||
return param;
|
||||
}
|
||||
|
||||
public void setParam(String param) {
|
||||
this.param = param;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "PageDO{" +
|
||||
"offset=" + offset +
|
||||
", limit=" + limit +
|
||||
", total=" + total +
|
||||
", params=" + params +
|
||||
", param='" + param + '\'' +
|
||||
", rows=" + rows +
|
||||
'}';
|
||||
}
|
||||
}
|
@ -0,0 +1,88 @@
|
||||
package com.java2nb.common.domain;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 表数据
|
||||
*
|
||||
* @author chenshun
|
||||
* @email 1179705413@qq.com
|
||||
* @date 2019-09-25 15:09:21
|
||||
*/
|
||||
public class TableDO {
|
||||
//表的名称
|
||||
private String tableName;
|
||||
//表的备注
|
||||
private String comments;
|
||||
//表的主键
|
||||
private GenColumnsDO pk;
|
||||
//表的列名(不包含主键)
|
||||
private List<GenColumnsDO> columns;
|
||||
|
||||
//类名(第一个字母大写),如:sys_user => SysUser
|
||||
private String className;
|
||||
//类名(第一个字母小写),如:sys_user => sysUser
|
||||
private String classname;
|
||||
|
||||
public String getTableName() {
|
||||
return tableName;
|
||||
}
|
||||
|
||||
public void setTableName(String tableName) {
|
||||
this.tableName = tableName;
|
||||
}
|
||||
|
||||
public String getComments() {
|
||||
return comments;
|
||||
}
|
||||
|
||||
public void setComments(String comments) {
|
||||
this.comments = comments;
|
||||
}
|
||||
|
||||
public GenColumnsDO getPk() {
|
||||
return pk;
|
||||
}
|
||||
|
||||
public void setPk(GenColumnsDO pk) {
|
||||
this.pk = pk;
|
||||
}
|
||||
|
||||
public List<GenColumnsDO> getColumns() {
|
||||
return columns;
|
||||
}
|
||||
|
||||
public void setColumns(List<GenColumnsDO> columns) {
|
||||
this.columns = columns;
|
||||
}
|
||||
|
||||
public String getClassName() {
|
||||
return className;
|
||||
}
|
||||
|
||||
public void setClassName(String className) {
|
||||
this.className = className;
|
||||
}
|
||||
|
||||
public String getClassname() {
|
||||
return classname;
|
||||
}
|
||||
|
||||
public void setClassname(String classname) {
|
||||
this.classname = classname;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "TableDO{" +
|
||||
"tableName='" + tableName + '\'' +
|
||||
", comments='" + comments + '\'' +
|
||||
", pk=" + pk +
|
||||
", columns=" + columns +
|
||||
", className='" + className + '\'' +
|
||||
", classname='" + classname + '\'' +
|
||||
'}';
|
||||
}
|
||||
}
|
151
novel-admin/src/main/java/com/java2nb/common/domain/Tree.java
Normal file
151
novel-admin/src/main/java/com/java2nb/common/domain/Tree.java
Normal file
@ -0,0 +1,151 @@
|
||||
package com.java2nb.common.domain;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
|
||||
/**
|
||||
* tree TODO <br>
|
||||
*
|
||||
* @author xiongxy
|
||||
*
|
||||
*/
|
||||
public class Tree<T> {
|
||||
/**
|
||||
* 节点ID
|
||||
*/
|
||||
private String id;
|
||||
/**
|
||||
* 显示节点文本
|
||||
*/
|
||||
private String text;
|
||||
/**
|
||||
* 节点状态,open closed
|
||||
*/
|
||||
private Map<String, Object> state;
|
||||
/**
|
||||
* 节点是否被选中 true false
|
||||
*/
|
||||
private boolean checked = false;
|
||||
/**
|
||||
* 节点属性
|
||||
*/
|
||||
private Map<String, Object> attributes;
|
||||
|
||||
/**
|
||||
* 节点的子节点
|
||||
*/
|
||||
private List<Tree<T>> children = new ArrayList<Tree<T>>();
|
||||
|
||||
/**
|
||||
* 父ID
|
||||
*/
|
||||
private String parentId;
|
||||
/**
|
||||
* 是否有父节点
|
||||
*/
|
||||
private boolean hasParent = false;
|
||||
/**
|
||||
* 是否有子节点
|
||||
*/
|
||||
private boolean hasChildren = false;
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getText() {
|
||||
return text;
|
||||
}
|
||||
|
||||
public void setText(String text) {
|
||||
this.text = text;
|
||||
}
|
||||
|
||||
public Map<String, Object> getState() {
|
||||
return state;
|
||||
}
|
||||
|
||||
public void setState(Map<String, Object> state) {
|
||||
this.state = state;
|
||||
}
|
||||
|
||||
public boolean isChecked() {
|
||||
return checked;
|
||||
}
|
||||
|
||||
public void setChecked(boolean checked) {
|
||||
this.checked = checked;
|
||||
}
|
||||
|
||||
public Map<String, Object> getAttributes() {
|
||||
return attributes;
|
||||
}
|
||||
|
||||
public void setAttributes(Map<String, Object> attributes) {
|
||||
this.attributes = attributes;
|
||||
}
|
||||
|
||||
public List<Tree<T>> getChildren() {
|
||||
return children;
|
||||
}
|
||||
|
||||
public void setChildren(List<Tree<T>> children) {
|
||||
this.children = children;
|
||||
}
|
||||
|
||||
public boolean isHasParent() {
|
||||
return hasParent;
|
||||
}
|
||||
|
||||
public void setHasParent(boolean isParent) {
|
||||
this.hasParent = isParent;
|
||||
}
|
||||
|
||||
public boolean isHasChildren() {
|
||||
return hasChildren;
|
||||
}
|
||||
|
||||
public void setChildren(boolean isChildren) {
|
||||
this.hasChildren = isChildren;
|
||||
}
|
||||
|
||||
public String getParentId() {
|
||||
return parentId;
|
||||
}
|
||||
|
||||
public void setParentId(String parentId) {
|
||||
this.parentId = parentId;
|
||||
}
|
||||
|
||||
public Tree(String id, String text, Map<String, Object> state, boolean checked, Map<String, Object> attributes,
|
||||
List<Tree<T>> children, boolean isParent, boolean isChildren, String parentID) {
|
||||
super();
|
||||
this.id = id;
|
||||
this.text = text;
|
||||
this.state = state;
|
||||
this.checked = checked;
|
||||
this.attributes = attributes;
|
||||
this.children = children;
|
||||
this.hasParent = isParent;
|
||||
this.hasChildren = isChildren;
|
||||
this.parentId = parentID;
|
||||
}
|
||||
|
||||
public Tree() {
|
||||
super();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
|
||||
return JSON.toJSONString(this);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
package com.java2nb.common.exception;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 自定义业务异常
|
||||
*/
|
||||
@Data
|
||||
public class BusinessException extends RuntimeException {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private String msg;
|
||||
private int code;
|
||||
|
||||
public BusinessException(int code,String msg) {
|
||||
//不调用父类Throwable的fillInStackTrace()方法生成栈追踪信息,提高应用性能
|
||||
//构造器之间的调用必须在第一行
|
||||
super(msg, null, false, false);
|
||||
this.code = code;
|
||||
this.msg = msg;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,81 @@
|
||||
package com.java2nb.common.exception;
|
||||
|
||||
import com.java2nb.common.config.Constant;
|
||||
import com.java2nb.common.domain.LogDO;
|
||||
import com.java2nb.common.service.LogService;
|
||||
import com.java2nb.common.utils.HttpServletUtils;
|
||||
import com.java2nb.common.utils.R;
|
||||
import com.java2nb.common.utils.ShiroUtils;
|
||||
import com.java2nb.system.domain.UserDO;
|
||||
import org.apache.shiro.authz.AuthorizationException;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.dao.DuplicateKeyException;
|
||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||
import org.springframework.web.bind.annotation.RestControllerAdvice;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 异常处理器
|
||||
*/
|
||||
@RestControllerAdvice
|
||||
public class CommonExceptionHandler {
|
||||
private Logger logger = LoggerFactory.getLogger(getClass());
|
||||
@Autowired
|
||||
LogService logService;
|
||||
|
||||
/**
|
||||
* 自定义业务异常处理
|
||||
*/
|
||||
@ExceptionHandler(BusinessException.class)
|
||||
public R handleBusinessException(BusinessException e) {
|
||||
logger.error(e.getMessage(), e);
|
||||
return R.error(e.getCode(),e.getMessage());
|
||||
}
|
||||
|
||||
@ExceptionHandler(DuplicateKeyException.class)
|
||||
public R handleDuplicateKeyException(DuplicateKeyException e) {
|
||||
logger.error(e.getMessage(), e);
|
||||
return R.error("数据库中已存在该记录");
|
||||
}
|
||||
|
||||
@ExceptionHandler(org.springframework.web.servlet.NoHandlerFoundException.class)
|
||||
public R noHandlerFoundException(org.springframework.web.servlet.NoHandlerFoundException e) {
|
||||
logger.error(e.getMessage(), e);
|
||||
return R.error(404, "没找找到页面");
|
||||
}
|
||||
|
||||
@ExceptionHandler(AuthorizationException.class)
|
||||
public Object handleAuthorizationException(AuthorizationException e, HttpServletRequest request) {
|
||||
logger.error(e.getMessage(), e);
|
||||
if (HttpServletUtils.jsAjax(request)) {
|
||||
return R.error(403, "未授权");
|
||||
}
|
||||
return new ModelAndView("error/403");
|
||||
}
|
||||
|
||||
|
||||
@ExceptionHandler({Exception.class})
|
||||
public Object handleException(Exception e, HttpServletRequest request) {
|
||||
LogDO logDO = new LogDO();
|
||||
logDO.setGmtCreate(new Date());
|
||||
logDO.setOperation(Constant.LOG_ERROR);
|
||||
logDO.setMethod(request.getRequestURL().toString());
|
||||
logDO.setParams(e.toString());
|
||||
UserDO current = ShiroUtils.getUser();
|
||||
if(null!=current){
|
||||
logDO.setUserId(current.getUserId());
|
||||
logDO.setUsername(current.getUsername());
|
||||
}
|
||||
logService.save(logDO);
|
||||
logger.error(e.getMessage(), e);
|
||||
if (HttpServletUtils.jsAjax(request)) {
|
||||
return R.error(500, "服务器错误,请联系管理员");
|
||||
}
|
||||
return new ModelAndView("error/500");
|
||||
}
|
||||
}
|
@ -0,0 +1,66 @@
|
||||
package com.java2nb.common.exception;
|
||||
|
||||
|
||||
import com.java2nb.common.utils.R;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.web.servlet.error.ErrorAttributes;
|
||||
import org.springframework.boot.web.servlet.error.ErrorController;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.util.Map;
|
||||
|
||||
@RestController
|
||||
public class MainsiteErrorController implements ErrorController {
|
||||
private Logger logger = LoggerFactory.getLogger(getClass());
|
||||
private static final String ERROR_PATH = "/error";
|
||||
|
||||
@Autowired
|
||||
ErrorAttributes errorAttributes;
|
||||
|
||||
@RequestMapping(
|
||||
value = {ERROR_PATH},
|
||||
produces = {"text/html"}
|
||||
)
|
||||
public ModelAndView errorHtml(HttpServletRequest request, HttpServletResponse response) {
|
||||
int code = response.getStatus();
|
||||
if (404 == code) {
|
||||
return new ModelAndView("error/404");
|
||||
} else if (403 == code) {
|
||||
return new ModelAndView("error/403");
|
||||
} else if (401 == code) {
|
||||
return new ModelAndView("login");
|
||||
} else {
|
||||
return new ModelAndView("error/500");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@RequestMapping(value = ERROR_PATH)
|
||||
public R handleError(HttpServletRequest request, HttpServletResponse response) {
|
||||
response.setStatus(200);
|
||||
int code = response.getStatus();
|
||||
if (404 == code) {
|
||||
return R.error(404, "未找到资源");
|
||||
} else if (403 == code) {
|
||||
return R.error(403, "没有访问权限");
|
||||
} else if (401 == code) {
|
||||
return R.error(403, "登录过期");
|
||||
} else {
|
||||
return R.error(500, "服务器错误");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getErrorPath() {
|
||||
// TODO Auto-generated method stub
|
||||
return ERROR_PATH;
|
||||
}
|
||||
}
|
@ -0,0 +1,155 @@
|
||||
package com.java2nb.common.interceptor;
|
||||
|
||||
import com.java2nb.common.utils.ShiroUtils;
|
||||
import com.java2nb.system.domain.DataPermDO;
|
||||
import com.java2nb.system.domain.UserDO;
|
||||
import org.apache.ibatis.cache.CacheKey;
|
||||
import org.apache.ibatis.executor.Executor;
|
||||
import org.apache.ibatis.mapping.BoundSql;
|
||||
import org.apache.ibatis.mapping.MappedStatement;
|
||||
import org.apache.ibatis.plugin.*;
|
||||
import org.apache.ibatis.session.ResultHandler;
|
||||
import org.apache.ibatis.session.RowBounds;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.*;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
@Intercepts({@Signature(
|
||||
type = Executor.class,
|
||||
method = "query",
|
||||
args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class}
|
||||
), @Signature(
|
||||
type = Executor.class,
|
||||
method = "query",
|
||||
args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class, CacheKey.class, BoundSql.class}
|
||||
)})
|
||||
@Component
|
||||
public class DataPermInterceptor implements Interceptor {
|
||||
|
||||
|
||||
public DataPermInterceptor() {
|
||||
super();
|
||||
}
|
||||
|
||||
//插件运行的代码,它将代替原有的方法
|
||||
@Override
|
||||
public Object intercept(Invocation invocation) throws Throwable {
|
||||
Object[] args = invocation.getArgs();
|
||||
MappedStatement mappedStatement = (MappedStatement) args[0];
|
||||
String sqlId = mappedStatement.getId();
|
||||
String methodName = sqlId.substring(sqlId.lastIndexOf(".") + 1);
|
||||
if (methodName.endsWith("ByPerm")) {
|
||||
Object parameter = args[1];
|
||||
RowBounds rowBounds = (RowBounds) args[2];
|
||||
ResultHandler resultHandler = (ResultHandler) args[3];
|
||||
Executor executor = (Executor) invocation.getTarget();
|
||||
CacheKey cacheKey;
|
||||
BoundSql boundSql;
|
||||
if (args.length == 4) {
|
||||
boundSql = mappedStatement.getBoundSql(parameter);
|
||||
cacheKey = executor.createCacheKey(mappedStatement, parameter, rowBounds, boundSql);
|
||||
} else {
|
||||
cacheKey = (CacheKey) args[4];
|
||||
boundSql = (BoundSql) args[5];
|
||||
}
|
||||
Class<BoundSql> boundSqlClass = BoundSql.class;
|
||||
Field field = boundSqlClass.getDeclaredField("sql");
|
||||
field.setAccessible(true);
|
||||
String lastSql = boundSql.getSql();
|
||||
Pattern tableNamePattern = Pattern.compile("\\s+from\\s+([^\\s]+)\\s*");
|
||||
Matcher tableNameMatcher = tableNamePattern.matcher(lastSql);
|
||||
if (tableNameMatcher.find()) {
|
||||
String tableName = tableNameMatcher.group(1);
|
||||
if(!tableName.contains("_")){
|
||||
if(tableNameMatcher.find()) {
|
||||
tableName = tableNameMatcher.group(1);
|
||||
}
|
||||
}
|
||||
UserDO user = ShiroUtils.getUser();
|
||||
List<DataPermDO> perms = user.getDataPerms().get(tableName);
|
||||
String pageSql = "";
|
||||
int limitIndex = lastSql.indexOf(" limit ");
|
||||
if (limitIndex != -1) {
|
||||
pageSql = lastSql.substring(limitIndex);
|
||||
lastSql = lastSql.substring(0, limitIndex);
|
||||
}
|
||||
String orderSql = "";
|
||||
int orderIndex = lastSql.indexOf(" order ");
|
||||
if (orderIndex == -1) {
|
||||
orderIndex = lastSql.indexOf(" ORDER ");
|
||||
}
|
||||
if (orderIndex != -1) {
|
||||
orderSql = lastSql.substring(orderIndex);
|
||||
lastSql = lastSql.substring(0, orderIndex);
|
||||
}
|
||||
|
||||
String linkSql = " WHERE ";
|
||||
String permSql = "";
|
||||
boolean allPerms= false;
|
||||
if (perms != null && perms.size() > 0) {
|
||||
|
||||
Class userClass = UserDO.class;
|
||||
for (DataPermDO perm : perms) {
|
||||
if (allPerms) {
|
||||
break;
|
||||
}
|
||||
|
||||
String attrName = perm.getCrlAttrName();
|
||||
String columnName = perm.getCrlColumnName();
|
||||
String permCode = perm.getPermCode();
|
||||
|
||||
switch (permCode.substring(0, permCode.indexOf("_"))) {
|
||||
case "all": {
|
||||
allPerms = true;
|
||||
break;
|
||||
}
|
||||
case "own": {
|
||||
Field attrNameField = userClass.getDeclaredField(attrName);
|
||||
attrNameField.setAccessible(true);
|
||||
String attrValue = attrNameField.get(user) + "";
|
||||
permSql += ("or " + columnName + "=" + attrValue + " ");
|
||||
break;
|
||||
}
|
||||
case "sup": {
|
||||
Field supAttrNameField = userClass.getDeclaredField("sup" + (attrName.substring(0, 1).toUpperCase() + attrName.substring(1)) + "s");
|
||||
supAttrNameField.setAccessible(true);
|
||||
String supAttrValue = (String) supAttrNameField.get(user);
|
||||
permSql += ("or " + columnName + " in(" + supAttrValue + ") ");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
if (!allPerms) {
|
||||
if(permSql.length()==0){
|
||||
permSql = "0";
|
||||
}else{
|
||||
permSql = permSql.replaceFirst("or","");
|
||||
}
|
||||
lastSql = lastSql + linkSql + "(" + permSql + ")";
|
||||
}
|
||||
lastSql += (orderSql + pageSql);
|
||||
|
||||
}
|
||||
|
||||
field.set(boundSql, lastSql);
|
||||
return executor.query(mappedStatement, parameter, rowBounds, resultHandler, cacheKey, boundSql);
|
||||
}
|
||||
return invocation.proceed();
|
||||
}
|
||||
|
||||
// 拦截类型StatementHandler
|
||||
@Override
|
||||
public Object plugin(Object target) {
|
||||
return Plugin.wrap(target, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setProperties(Properties properties) {
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
package com.java2nb.common.jsonserializer;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonGenerator;
|
||||
import com.fasterxml.jackson.databind.JsonSerializer;
|
||||
import com.fasterxml.jackson.databind.SerializerProvider;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class LongToStringSerializer extends JsonSerializer<Long> {
|
||||
@Override
|
||||
public void serialize(Long value, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
|
||||
|
||||
if(value != null){
|
||||
jsonGenerator.writeString(value+"");
|
||||
}else{
|
||||
jsonGenerator.writeNull();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,194 @@
|
||||
package com.java2nb.common.redis.shiro;
|
||||
|
||||
/**
|
||||
* @author xiongxy
|
||||
* @version V1.0
|
||||
*/
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.shiro.cache.Cache;
|
||||
import org.apache.shiro.cache.CacheException;
|
||||
import org.apache.shiro.util.CollectionUtils;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class RedisCache<K, V> implements Cache<K, V> {
|
||||
|
||||
private Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||
|
||||
/**
|
||||
* The wrapped Jedis instance.
|
||||
*/
|
||||
private RedisManager cache;
|
||||
|
||||
/**
|
||||
* The Redis key prefix for the sessions
|
||||
*/
|
||||
private String keyPrefix = "shiro_redis_session:";
|
||||
|
||||
/**
|
||||
* Returns the Redis session keys
|
||||
* prefix.
|
||||
* @return The prefix
|
||||
*/
|
||||
public String getKeyPrefix() {
|
||||
return keyPrefix;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the Redis sessions key
|
||||
* prefix.
|
||||
* @param keyPrefix The prefix
|
||||
*/
|
||||
public void setKeyPrefix(String keyPrefix) {
|
||||
this.keyPrefix = keyPrefix;
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过一个JedisManager实例构造RedisCache
|
||||
*/
|
||||
public RedisCache(RedisManager cache){
|
||||
if (cache == null) {
|
||||
throw new IllegalArgumentException("Cache argument cannot be null.");
|
||||
}
|
||||
this.cache = cache;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a cache instance with the specified
|
||||
* Redis manager and using a custom key prefix.
|
||||
* @param cache The cache manager instance
|
||||
* @param prefix The Redis key prefix
|
||||
*/
|
||||
public RedisCache(RedisManager cache,
|
||||
String prefix){
|
||||
|
||||
this( cache );
|
||||
|
||||
// set the prefix
|
||||
this.keyPrefix = prefix;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得byte[]型的key
|
||||
* @param key
|
||||
* @return
|
||||
*/
|
||||
private byte[] getByteKey(K key){
|
||||
if(key instanceof String){
|
||||
String preKey = this.keyPrefix + key;
|
||||
return preKey.getBytes();
|
||||
}else{
|
||||
return SerializeUtils.serialize(key);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public V get(K key) throws CacheException {
|
||||
logger.debug("根据key从Redis中获取对象 key [" + key + "]");
|
||||
try {
|
||||
if (key == null) {
|
||||
return null;
|
||||
}else{
|
||||
byte[] rawValue = cache.get(getByteKey(key));
|
||||
@SuppressWarnings("unchecked")
|
||||
V value = (V)SerializeUtils.deserialize(rawValue);
|
||||
return value;
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
throw new CacheException(t);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public V put(K key, V value) throws CacheException {
|
||||
logger.debug("根据key从存储 key [" + key + "]");
|
||||
try {
|
||||
cache.set(getByteKey(key), SerializeUtils.serialize(value));
|
||||
return value;
|
||||
} catch (Throwable t) {
|
||||
throw new CacheException(t);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public V remove(K key) throws CacheException {
|
||||
logger.debug("从redis中删除 key [" + key + "]");
|
||||
try {
|
||||
V previous = get(key);
|
||||
cache.del(getByteKey(key));
|
||||
return previous;
|
||||
} catch (Throwable t) {
|
||||
throw new CacheException(t);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear() throws CacheException {
|
||||
logger.debug("从redis中删除所有元素");
|
||||
try {
|
||||
cache.flushDB();
|
||||
} catch (Throwable t) {
|
||||
throw new CacheException(t);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
try {
|
||||
Long longSize = new Long(cache.dbSize());
|
||||
return longSize.intValue();
|
||||
} catch (Throwable t) {
|
||||
throw new CacheException(t);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public Set<K> keys() {
|
||||
try {
|
||||
Set<byte[]> keys = cache.keys(this.keyPrefix + "*");
|
||||
if (CollectionUtils.isEmpty(keys)) {
|
||||
return Collections.emptySet();
|
||||
}else{
|
||||
Set<K> newKeys = new HashSet<K>();
|
||||
for(byte[] key:keys){
|
||||
newKeys.add((K)key);
|
||||
}
|
||||
return newKeys;
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
throw new CacheException(t);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<V> values() {
|
||||
try {
|
||||
Set<byte[]> keys = cache.keys(this.keyPrefix + "*");
|
||||
if (!CollectionUtils.isEmpty(keys)) {
|
||||
List<V> values = new ArrayList<V>(keys.size());
|
||||
for (byte[] key : keys) {
|
||||
@SuppressWarnings("unchecked")
|
||||
V value = get((K)key);
|
||||
if (value != null) {
|
||||
values.add(value);
|
||||
}
|
||||
}
|
||||
return Collections.unmodifiableList(values);
|
||||
} else {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
throw new CacheException(t);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,77 @@
|
||||
package com.java2nb.common.redis.shiro;
|
||||
|
||||
/**
|
||||
* @author xiongxy
|
||||
* @version V1.0
|
||||
*/
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
|
||||
import org.apache.shiro.cache.Cache;
|
||||
import org.apache.shiro.cache.CacheException;
|
||||
import org.apache.shiro.cache.CacheManager;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class RedisCacheManager implements CacheManager {
|
||||
|
||||
private static final Logger logger = LoggerFactory
|
||||
.getLogger(RedisCacheManager.class);
|
||||
|
||||
// fast lookup by name map
|
||||
private final ConcurrentMap<String, Cache> caches = new ConcurrentHashMap<String, Cache>();
|
||||
|
||||
private RedisManager redisManager;
|
||||
|
||||
/**
|
||||
* The Redis key prefix for caches
|
||||
*/
|
||||
private String keyPrefix = "shiro_redis_cache:";
|
||||
|
||||
/**
|
||||
* Returns the Redis session keys
|
||||
* prefix.
|
||||
* @return The prefix
|
||||
*/
|
||||
public String getKeyPrefix() {
|
||||
return keyPrefix;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the Redis sessions key
|
||||
* prefix.
|
||||
* @param keyPrefix The prefix
|
||||
*/
|
||||
public void setKeyPrefix(String keyPrefix) {
|
||||
this.keyPrefix = keyPrefix;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <K, V> Cache<K, V> getCache(String name) throws CacheException {
|
||||
logger.debug("获取名称为: " + name + " 的RedisCache实例");
|
||||
|
||||
Cache c = caches.get(name);
|
||||
|
||||
if (c == null) {
|
||||
|
||||
// initialize the Redis manager instance
|
||||
redisManager.init();
|
||||
|
||||
// create a new cache instance
|
||||
c = new RedisCache<K, V>(redisManager, keyPrefix);
|
||||
|
||||
// add it to the cache collection
|
||||
caches.put(name, c);
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
public RedisManager getRedisManager() {
|
||||
return redisManager;
|
||||
}
|
||||
|
||||
public void setRedisManager(RedisManager redisManager) {
|
||||
this.redisManager = redisManager;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,228 @@
|
||||
package com.java2nb.common.redis.shiro;
|
||||
|
||||
/**
|
||||
* @author xiongxy
|
||||
* @version V1.0
|
||||
*/
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import redis.clients.jedis.Jedis;
|
||||
import redis.clients.jedis.JedisPool;
|
||||
import redis.clients.jedis.JedisPoolConfig;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class RedisManager {
|
||||
|
||||
@Value("${spring.redis.host}")
|
||||
private String host = "127.0.0.1";
|
||||
|
||||
@Value("${spring.redis.port}")
|
||||
private int port = 6379;
|
||||
|
||||
// 0 - never expire
|
||||
private int expire = 0;
|
||||
|
||||
//timeout for jedis try to connect to redis server, not expire time! In milliseconds
|
||||
@Value("${spring.redis.timeout}")
|
||||
private int timeout = 0;
|
||||
|
||||
@Value("${spring.redis.password}")
|
||||
private String password = "";
|
||||
|
||||
private static JedisPool jedisPool = null;
|
||||
|
||||
public RedisManager() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化方法
|
||||
*/
|
||||
public void init() {
|
||||
if (jedisPool == null) {
|
||||
if (password != null && !"".equals(password)) {
|
||||
jedisPool = new JedisPool(new JedisPoolConfig(), host, port, timeout, password);
|
||||
} else if (timeout != 0) {
|
||||
jedisPool = new JedisPool(new JedisPoolConfig(), host, port, timeout);
|
||||
} else {
|
||||
jedisPool = new JedisPool(new JedisPoolConfig(), host, port);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* get value from redis
|
||||
*
|
||||
* @param key
|
||||
* @return
|
||||
*/
|
||||
public byte[] get(byte[] key) {
|
||||
byte[] value = null;
|
||||
Jedis jedis = jedisPool.getResource();
|
||||
try {
|
||||
value = jedis.get(key);
|
||||
} finally {
|
||||
if (jedis != null) {
|
||||
jedis.close();
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* set
|
||||
*
|
||||
* @param key
|
||||
* @param value
|
||||
* @return
|
||||
*/
|
||||
public byte[] set(byte[] key, byte[] value) {
|
||||
Jedis jedis = jedisPool.getResource();
|
||||
try {
|
||||
jedis.set(key, value);
|
||||
if (this.expire != 0) {
|
||||
jedis.expire(key, this.expire);
|
||||
}
|
||||
} finally {
|
||||
if (jedis != null) {
|
||||
jedis.close();
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* set
|
||||
*
|
||||
* @param key
|
||||
* @param value
|
||||
* @param expire
|
||||
* @return
|
||||
*/
|
||||
public byte[] set(byte[] key, byte[] value, int expire) {
|
||||
Jedis jedis = jedisPool.getResource();
|
||||
try {
|
||||
jedis.set(key, value);
|
||||
if (expire != 0) {
|
||||
jedis.expire(key, expire);
|
||||
}
|
||||
} finally {
|
||||
if (jedis != null) {
|
||||
jedis.close();
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* del
|
||||
*
|
||||
* @param key
|
||||
*/
|
||||
public void del(byte[] key) {
|
||||
Jedis jedis = jedisPool.getResource();
|
||||
try {
|
||||
jedis.del(key);
|
||||
} finally {
|
||||
if (jedis != null) {
|
||||
jedis.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* flush
|
||||
*/
|
||||
public void flushDB() {
|
||||
Jedis jedis = jedisPool.getResource();
|
||||
try {
|
||||
jedis.flushDB();
|
||||
} finally {
|
||||
if (jedis != null) {
|
||||
jedis.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* size
|
||||
*/
|
||||
public Long dbSize() {
|
||||
Long dbSize = 0L;
|
||||
Jedis jedis = jedisPool.getResource();
|
||||
try {
|
||||
dbSize = jedis.dbSize();
|
||||
} finally {
|
||||
if (jedis != null) {
|
||||
jedis.close();
|
||||
}
|
||||
}
|
||||
return dbSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* keys
|
||||
*
|
||||
* @param regex
|
||||
* @return
|
||||
*/
|
||||
public Set<byte[]> keys(String pattern) {
|
||||
Set<byte[]> keys = null;
|
||||
Jedis jedis = jedisPool.getResource();
|
||||
try {
|
||||
keys = jedis.keys(pattern.getBytes());
|
||||
} finally {
|
||||
if (jedis != null) {
|
||||
jedis.close();
|
||||
}
|
||||
}
|
||||
return keys;
|
||||
}
|
||||
|
||||
public String getHost() {
|
||||
return host;
|
||||
}
|
||||
|
||||
public void setHost(String host) {
|
||||
this.host = host;
|
||||
}
|
||||
|
||||
public int getPort() {
|
||||
return port;
|
||||
}
|
||||
|
||||
public void setPort(int port) {
|
||||
this.port = port;
|
||||
}
|
||||
|
||||
public int getExpire() {
|
||||
return expire;
|
||||
}
|
||||
|
||||
public void setExpire(int expire) {
|
||||
this.expire = expire;
|
||||
}
|
||||
|
||||
public int getTimeout() {
|
||||
return timeout;
|
||||
}
|
||||
|
||||
public void setTimeout(int timeout) {
|
||||
this.timeout = timeout;
|
||||
}
|
||||
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
public void setPassword(String password) {
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,139 @@
|
||||
package com.java2nb.common.redis.shiro;
|
||||
|
||||
import org.apache.shiro.session.Session;
|
||||
import org.apache.shiro.session.UnknownSessionException;
|
||||
import org.apache.shiro.session.mgt.eis.AbstractSessionDAO;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author xiongxy
|
||||
* @version V1.0
|
||||
*/
|
||||
public class RedisSessionDAO extends AbstractSessionDAO {
|
||||
|
||||
private static Logger logger = LoggerFactory.getLogger(RedisSessionDAO.class);
|
||||
/**
|
||||
* shiro-redis的session对象前缀
|
||||
*/
|
||||
private RedisManager redisManager;
|
||||
|
||||
/**
|
||||
* The Redis key prefix for the sessions
|
||||
*/
|
||||
private String keyPrefix = "shiro_redis_session:";
|
||||
|
||||
@Override
|
||||
public void update(Session session) throws UnknownSessionException {
|
||||
this.saveSession(session);
|
||||
}
|
||||
|
||||
/**
|
||||
* save session
|
||||
* @param session
|
||||
* @throws UnknownSessionException
|
||||
*/
|
||||
private void saveSession(Session session) throws UnknownSessionException{
|
||||
if(session == null || session.getId() == null){
|
||||
logger.error("session or session id is null");
|
||||
return;
|
||||
}
|
||||
|
||||
byte[] key = getByteKey(session.getId());
|
||||
byte[] value = SerializeUtils.serialize(session);
|
||||
session.setTimeout(redisManager.getExpire()*1000);
|
||||
this.redisManager.set(key, value, redisManager.getExpire());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delete(Session session) {
|
||||
if(session == null || session.getId() == null){
|
||||
logger.error("session or session id is null");
|
||||
return;
|
||||
}
|
||||
redisManager.del(this.getByteKey(session.getId()));
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Session> getActiveSessions() {
|
||||
Set<Session> sessions = new HashSet<Session>();
|
||||
|
||||
Set<byte[]> keys = redisManager.keys(this.keyPrefix + "*");
|
||||
if(keys != null && keys.size()>0){
|
||||
for(byte[] key:keys){
|
||||
Session s = (Session)SerializeUtils.deserialize(redisManager.get(key));
|
||||
sessions.add(s);
|
||||
}
|
||||
}
|
||||
|
||||
return sessions;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Serializable doCreate(Session session) {
|
||||
Serializable sessionId = this.generateSessionId(session);
|
||||
this.assignSessionId(session, sessionId);
|
||||
this.saveSession(session);
|
||||
return sessionId;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Session doReadSession(Serializable sessionId) {
|
||||
if(sessionId == null){
|
||||
logger.error("session id is null");
|
||||
return null;
|
||||
}
|
||||
|
||||
Session s = (Session)SerializeUtils.deserialize(redisManager.get(this.getByteKey(sessionId)));
|
||||
return s;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得byte[]型的key
|
||||
* @param key
|
||||
* @return
|
||||
*/
|
||||
private byte[] getByteKey(Serializable sessionId){
|
||||
String preKey = this.keyPrefix + sessionId;
|
||||
return preKey.getBytes();
|
||||
}
|
||||
|
||||
public RedisManager getRedisManager() {
|
||||
return redisManager;
|
||||
}
|
||||
|
||||
public void setRedisManager(RedisManager redisManager) {
|
||||
this.redisManager = redisManager;
|
||||
|
||||
/**
|
||||
* 初始化redisManager
|
||||
*/
|
||||
this.redisManager.init();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Redis session keys
|
||||
* prefix.
|
||||
* @return The prefix
|
||||
*/
|
||||
public String getKeyPrefix() {
|
||||
return keyPrefix;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the Redis sessions key
|
||||
* prefix.
|
||||
* @param keyPrefix The prefix
|
||||
*/
|
||||
public void setKeyPrefix(String keyPrefix) {
|
||||
this.keyPrefix = keyPrefix;
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,89 @@
|
||||
package com.java2nb.common.redis.shiro;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* @author xiongxy
|
||||
* @version V1.0
|
||||
*/
|
||||
public class SerializeUtils {
|
||||
|
||||
private static Logger logger = LoggerFactory.getLogger(SerializeUtils.class);
|
||||
|
||||
/**
|
||||
* 反序列化
|
||||
* @param bytes
|
||||
* @return
|
||||
*/
|
||||
public static Object deserialize(byte[] bytes) {
|
||||
|
||||
Object result = null;
|
||||
|
||||
if (isEmpty(bytes)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
ByteArrayInputStream byteStream = new ByteArrayInputStream(bytes);
|
||||
try {
|
||||
ObjectInputStream objectInputStream = new ObjectInputStream(byteStream);
|
||||
try {
|
||||
result = objectInputStream.readObject();
|
||||
}
|
||||
catch (ClassNotFoundException ex) {
|
||||
throw new Exception("Failed to deserialize object type", ex);
|
||||
}
|
||||
}
|
||||
catch (Throwable ex) {
|
||||
throw new Exception("Failed to deserialize", ex);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.error("Failed to deserialize",e);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static boolean isEmpty(byte[] data) {
|
||||
return (data == null || data.length == 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* 序列化
|
||||
* @param object
|
||||
* @return
|
||||
*/
|
||||
public static byte[] serialize(Object object) {
|
||||
|
||||
byte[] result = null;
|
||||
|
||||
if (object == null) {
|
||||
return new byte[0];
|
||||
}
|
||||
try {
|
||||
ByteArrayOutputStream byteStream = new ByteArrayOutputStream(128);
|
||||
try {
|
||||
if (!(object instanceof Serializable)) {
|
||||
throw new IllegalArgumentException(SerializeUtils.class.getSimpleName() + " requires a Serializable payload " +
|
||||
"but received an object of type [" + object.getClass().getName() + "]");
|
||||
}
|
||||
ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteStream);
|
||||
objectOutputStream.writeObject(object);
|
||||
objectOutputStream.flush();
|
||||
result = byteStream.toByteArray();
|
||||
}
|
||||
catch (Throwable ex) {
|
||||
throw new Exception("Failed to serialize", ex);
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
logger.error("Failed to serialize",ex);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
@ -0,0 +1,56 @@
|
||||
package com.java2nb.common.service;
|
||||
|
||||
import com.java2nb.common.domain.DictDO;
|
||||
import com.java2nb.system.domain.UserDO;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 字典表
|
||||
*
|
||||
* @author xiongxy
|
||||
* @email 1179705413@qq.com
|
||||
* @date 2019-09-29 18:28:07
|
||||
*/
|
||||
public interface DictService {
|
||||
|
||||
DictDO get(Long id);
|
||||
|
||||
List<DictDO> list(Map<String, Object> map);
|
||||
|
||||
int count(Map<String, Object> map);
|
||||
|
||||
int save(DictDO dict);
|
||||
|
||||
int update(DictDO dict);
|
||||
|
||||
int remove(Long id);
|
||||
|
||||
int batchRemove(Long[] ids);
|
||||
|
||||
List<DictDO> listType();
|
||||
|
||||
String getName(String type,String value);
|
||||
|
||||
/**
|
||||
* 获取爱好列表
|
||||
* @return
|
||||
* @param userDO
|
||||
*/
|
||||
List<DictDO> getHobbyList(UserDO userDO);
|
||||
|
||||
/**
|
||||
* 获取性别列表
|
||||
* @return
|
||||
*/
|
||||
List<DictDO> getSexList();
|
||||
|
||||
/**
|
||||
* 根据type获取数据
|
||||
* @param map
|
||||
* @return
|
||||
*/
|
||||
List<DictDO> listByType(String type);
|
||||
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
package com.java2nb.common.service;
|
||||
|
||||
import com.java2nb.common.domain.FileDO;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 文件上传
|
||||
*
|
||||
* @author xiongxy
|
||||
* @email 1179705413@qq.com
|
||||
* @date 2019-09-19 16:02:20
|
||||
*/
|
||||
public interface FileService {
|
||||
|
||||
FileDO get(Long id);
|
||||
|
||||
List<FileDO> list(Map<String, Object> map);
|
||||
|
||||
int count(Map<String, Object> map);
|
||||
|
||||
int save(FileDO sysFile);
|
||||
|
||||
int update(FileDO sysFile);
|
||||
|
||||
int remove(Long id);
|
||||
|
||||
int batchRemove(Long[] ids);
|
||||
|
||||
/**
|
||||
* 判断一个文件是否存在
|
||||
* @param url FileDO中存的路径
|
||||
* @return
|
||||
*/
|
||||
Boolean isExist(String url);
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
/**
|
||||
*
|
||||
*/
|
||||
package com.java2nb.common.service;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.java2nb.common.domain.GenColumnsDO;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* @author xiongxy
|
||||
* @Time 2019-10-20 11:23:09
|
||||
* @description
|
||||
*
|
||||
*/
|
||||
@Service
|
||||
public interface GeneratorService {
|
||||
List<Map<String, Object>> list(String tableName);
|
||||
|
||||
void generatorCode(String[] tableNames);
|
||||
|
||||
byte[] downloadCode(String[] tableNames);
|
||||
|
||||
|
||||
List<GenColumnsDO> listColumnsByTableName(String tableName);
|
||||
|
||||
boolean genColumnsSave(List<GenColumnsDO> list);
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
package com.java2nb.common.service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.java2nb.common.domain.LogDO;
|
||||
import com.java2nb.common.domain.PageDO;
|
||||
import com.java2nb.common.utils.Query;
|
||||
@Service
|
||||
public interface LogService {
|
||||
void save(LogDO logDO);
|
||||
PageDO<LogDO> queryList(Query query);
|
||||
int remove(Long id);
|
||||
int batchRemove(Long[] ids);
|
||||
}
|
@ -0,0 +1,109 @@
|
||||
package com.java2nb.common.service.impl;
|
||||
|
||||
import com.java2nb.common.utils.StringUtils;
|
||||
import com.java2nb.system.domain.UserDO;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
import com.java2nb.common.dao.DictDao;
|
||||
import com.java2nb.common.domain.DictDO;
|
||||
import com.java2nb.common.service.DictService;
|
||||
|
||||
|
||||
@Service
|
||||
public class DictServiceImpl implements DictService {
|
||||
@Autowired
|
||||
private DictDao dictDao;
|
||||
|
||||
@Override
|
||||
public DictDO get(Long id) {
|
||||
return dictDao.get(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<DictDO> list(Map<String, Object> map) {
|
||||
return dictDao.list(map);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int count(Map<String, Object> map) {
|
||||
return dictDao.count(map);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int save(DictDO dict) {
|
||||
return dictDao.save(dict);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int update(DictDO dict) {
|
||||
return dictDao.update(dict);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int remove(Long id) {
|
||||
return dictDao.remove(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int batchRemove(Long[] ids) {
|
||||
return dictDao.batchRemove(ids);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
public List<DictDO> listType() {
|
||||
return dictDao.listType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName(String type, String value) {
|
||||
Map<String, Object> param = new HashMap<String, Object>(16);
|
||||
param.put("type", type);
|
||||
param.put("value", value);
|
||||
String rString = dictDao.list(param).get(0).getName();
|
||||
return rString;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<DictDO> getHobbyList(UserDO userDO) {
|
||||
Map<String, Object> param = new HashMap<>(16);
|
||||
param.put("type", "hobby");
|
||||
List<DictDO> hobbyList = dictDao.list(param);
|
||||
|
||||
if (StringUtils.isNotEmpty(userDO.getHobby())) {
|
||||
String userHobbys[] = userDO.getHobby().split(";");
|
||||
for (String userHobby : userHobbys) {
|
||||
for (DictDO hobby : hobbyList) {
|
||||
if (!Objects.equals(userHobby, hobby.getId().toString())) {
|
||||
continue;
|
||||
}
|
||||
hobby.setRemarks("true");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return hobbyList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<DictDO> getSexList() {
|
||||
Map<String, Object> param = new HashMap<>(16);
|
||||
param.put("type", "sex");
|
||||
return dictDao.list(param);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<DictDO> listByType(String type) {
|
||||
Map<String, Object> param = new HashMap<>(16);
|
||||
param.put("type", type);
|
||||
return dictDao.list(param);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,72 @@
|
||||
package com.java2nb.common.service.impl;
|
||||
|
||||
import com.java2nb.common.config.JnConfig;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.java2nb.common.dao.FileDao;
|
||||
import com.java2nb.common.domain.FileDO;
|
||||
import com.java2nb.common.service.FileService;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
|
||||
@Service
|
||||
public class FileServiceImpl implements FileService {
|
||||
@Autowired
|
||||
private FileDao sysFileMapper;
|
||||
|
||||
@Autowired
|
||||
private JnConfig jnConfig;
|
||||
@Override
|
||||
public FileDO get(Long id){
|
||||
return sysFileMapper.get(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<FileDO> list(Map<String, Object> map){
|
||||
return sysFileMapper.list(map);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int count(Map<String, Object> map){
|
||||
return sysFileMapper.count(map);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int save(FileDO sysFile){
|
||||
return sysFileMapper.save(sysFile);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int update(FileDO sysFile){
|
||||
return sysFileMapper.update(sysFile);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int remove(Long id){
|
||||
return sysFileMapper.remove(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int batchRemove(Long[] ids){
|
||||
return sysFileMapper.batchRemove(ids);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean isExist(String url) {
|
||||
Boolean isExist = false;
|
||||
if (!StringUtils.isEmpty(url)) {
|
||||
String filePath = url.replace("/files/", "");
|
||||
filePath = jnConfig.getUploadPath() + filePath;
|
||||
File file = new File(filePath);
|
||||
if (file.exists()) {
|
||||
isExist = true;
|
||||
}
|
||||
}
|
||||
return isExist;
|
||||
}
|
||||
}
|
@ -0,0 +1,141 @@
|
||||
package com.java2nb.common.service.impl;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.zip.ZipOutputStream;
|
||||
|
||||
import com.java2nb.common.dao.GenColumnsDao;
|
||||
import com.java2nb.common.domain.GenColumnsDO;
|
||||
import lombok.SneakyThrows;
|
||||
import org.apache.commons.configuration.PropertiesConfiguration;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.java2nb.common.dao.GeneratorMapper;
|
||||
import com.java2nb.common.service.GeneratorService;
|
||||
import com.java2nb.common.utils.GenUtils;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
|
||||
@Service
|
||||
public class GeneratorServiceImpl implements GeneratorService {
|
||||
@Autowired
|
||||
GeneratorMapper generatorMapper;
|
||||
|
||||
@Autowired
|
||||
GenColumnsDao genColumnsDao;
|
||||
|
||||
@Override
|
||||
public List<Map<String, Object>> list(String tableName) {
|
||||
List<Map<String, Object>> list = generatorMapper.list(tableName);
|
||||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void generatorCode(String[] tableNames) {
|
||||
for (String tableName : tableNames) {
|
||||
//查询表信息
|
||||
Map<String, String> table = generatorMapper.get(tableName);
|
||||
//查询列信息
|
||||
List<Map<String, String>> columns = generatorMapper.listColumns(tableName);
|
||||
//生成代码
|
||||
GenUtils.generatorCode(table, columns, null);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] downloadCode(String[] tableNames) {
|
||||
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||
ZipOutputStream zip = new ZipOutputStream(outputStream);
|
||||
for (String tableName : tableNames) {
|
||||
//查询表信息
|
||||
Map<String, String> table = generatorMapper.get(tableName);
|
||||
//查询列信息
|
||||
List<Map<String, String>> columns = generatorMapper.listColumns(tableName);
|
||||
//生成代码
|
||||
GenUtils.generatorCode(table, columns, zip);
|
||||
}
|
||||
IOUtils.closeQuietly(zip);
|
||||
return outputStream.toByteArray();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public List<GenColumnsDO> listColumnsByTableName(String tableName) {
|
||||
Map<String, Object> query = new HashMap<>();
|
||||
query.put("tableName", tableName);
|
||||
query.put("sort", "column_sort");
|
||||
query.put("order", "asc");
|
||||
List<GenColumnsDO> columnList = genColumnsDao.list(query);
|
||||
if (columnList.size() == 0) {
|
||||
//查询列信息
|
||||
List<Map<String, String>> columns = generatorMapper.listColumns(tableName);
|
||||
|
||||
int columnSort = 0;
|
||||
for (Map<String, String> column : columns) {
|
||||
GenColumnsDO genColumnsDO = transGenColumnDO(tableName,column,++columnSort);
|
||||
|
||||
if(!"PRI".equalsIgnoreCase(column.get("columnKey"))) {
|
||||
columnList.add(genColumnsDO);
|
||||
}else{
|
||||
genColumnsDO.setColumnSort(0);
|
||||
genColumnsDO.setPageType(11);
|
||||
columnList.add(0,genColumnsDO);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}else{
|
||||
Map<String, String> column = generatorMapper.getPriColumn(tableName);
|
||||
GenColumnsDO genColumnsDO = transGenColumnDO(tableName,column,0);
|
||||
genColumnsDO.setPageType(11);
|
||||
columnList.add(0,genColumnsDO);
|
||||
}
|
||||
return columnList;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public boolean genColumnsSave(List<GenColumnsDO> list) {
|
||||
GenColumnsDO pkColumn = list.get(0);
|
||||
String tableName = pkColumn.getTableName();
|
||||
genColumnsDao.deleteByTableName(tableName);
|
||||
list.remove(0);
|
||||
genColumnsDao.saveBatch(list);
|
||||
//查询表信息
|
||||
Map<String, String> table = generatorMapper.get(tableName);
|
||||
//生成代码
|
||||
GenUtils.generatorCode(table,pkColumn, list);
|
||||
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public GenColumnsDO transGenColumnDO(String tableName,Map<String, String> column,int columnSort){
|
||||
GenColumnsDO genColumnsDO = new GenColumnsDO();
|
||||
genColumnsDO.setTableName(tableName);
|
||||
genColumnsDO.setColumnName(column.get("columnName"));
|
||||
genColumnsDO.setColumnType(column.get("dataType"));
|
||||
genColumnsDO.setColumnComment(column.get("columnComment"));
|
||||
PropertiesConfiguration conf = new PropertiesConfiguration("generator.properties");
|
||||
genColumnsDO.setJavaType(conf.getString(column.get("dataType")));
|
||||
genColumnsDO.setColumnSort(columnSort);
|
||||
genColumnsDO.setExtra(column.get("extra"));
|
||||
genColumnsDO.setIsRequired(0);
|
||||
if ("Date".equals(conf.getString(column.get("dataType")))) {
|
||||
genColumnsDO.setPageType(4);
|
||||
|
||||
} else {
|
||||
genColumnsDO.setPageType(1);
|
||||
}
|
||||
genColumnsDO.setColumnLabel(column.get("columnComment"));
|
||||
return genColumnsDO;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,45 @@
|
||||
package com.java2nb.common.service.impl;
|
||||
|
||||
import java.util.List;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.scheduling.annotation.Async;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.java2nb.common.dao.LogDao;
|
||||
import com.java2nb.common.domain.LogDO;
|
||||
import com.java2nb.common.domain.PageDO;
|
||||
import com.java2nb.common.service.LogService;
|
||||
import com.java2nb.common.utils.Query;
|
||||
|
||||
@Service
|
||||
public class LogServiceImpl implements LogService {
|
||||
@Autowired
|
||||
LogDao logMapper;
|
||||
|
||||
@Async
|
||||
@Override
|
||||
public void save(LogDO logDO) {
|
||||
logMapper.save(logDO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageDO<LogDO> queryList(Query query) {
|
||||
int total = logMapper.count(query);
|
||||
List<LogDO> logs = logMapper.list(query);
|
||||
PageDO<LogDO> page = new PageDO<>();
|
||||
page.setTotal(total);
|
||||
page.setRows(logs);
|
||||
return page;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int remove(Long id) {
|
||||
int count = logMapper.remove(id);
|
||||
return count;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int batchRemove(Long[] ids){
|
||||
return logMapper.batchRemove(ids);
|
||||
}
|
||||
}
|
@ -0,0 +1,52 @@
|
||||
package com.java2nb.common.utils;
|
||||
|
||||
/**
|
||||
* 自定义异常
|
||||
*
|
||||
*/
|
||||
public class BDException extends RuntimeException {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private String msg;
|
||||
private int code = 500;
|
||||
|
||||
public BDException(String msg) {
|
||||
super(msg);
|
||||
this.msg = msg;
|
||||
}
|
||||
|
||||
public BDException(String msg, Throwable e) {
|
||||
super(msg, e);
|
||||
this.msg = msg;
|
||||
}
|
||||
|
||||
public BDException(String msg, int code) {
|
||||
super(msg);
|
||||
this.msg = msg;
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public BDException(String msg, int code, Throwable e) {
|
||||
super(msg, e);
|
||||
this.msg = msg;
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public String getMsg() {
|
||||
return msg;
|
||||
}
|
||||
|
||||
public void setMsg(String msg) {
|
||||
this.msg = msg;
|
||||
}
|
||||
|
||||
public int getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public void setCode(int code) {
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
package com.java2nb.common.utils;
|
||||
|
||||
public class Base64Utils {
|
||||
|
||||
}
|
@ -0,0 +1,89 @@
|
||||
package com.java2nb.common.utils;
|
||||
|
||||
import com.java2nb.common.domain.Tree;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class BuildTree {
|
||||
|
||||
public static <T> Tree<T> build(List<Tree<T>> nodes) {
|
||||
|
||||
if (nodes == null) {
|
||||
return null;
|
||||
}
|
||||
List<Tree<T>> topNodes = new ArrayList<Tree<T>>();
|
||||
|
||||
for (Tree<T> children : nodes) {
|
||||
|
||||
String pid = children.getParentId();
|
||||
if (pid == null || "0".equals(pid)) {
|
||||
topNodes.add(children);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
for (Tree<T> parent : nodes) {
|
||||
String id = parent.getId();
|
||||
if (id != null && id.equals(pid)) {
|
||||
parent.getChildren().add(children);
|
||||
children.setHasParent(true);
|
||||
parent.setChildren(true);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Tree<T> root = new Tree<T>();
|
||||
if (topNodes.size() == 1) {
|
||||
root = topNodes.get(0);
|
||||
} else {
|
||||
root.setId("-1");
|
||||
root.setParentId("");
|
||||
root.setHasParent(false);
|
||||
root.setChildren(true);
|
||||
root.setChecked(true);
|
||||
root.setChildren(topNodes);
|
||||
root.setText("顶级节点");
|
||||
Map<String, Object> state = new HashMap<>(16);
|
||||
state.put("opened", true);
|
||||
root.setState(state);
|
||||
}
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
public static <T> List<Tree<T>> buildList(List<Tree<T>> nodes, String idParam) {
|
||||
if (nodes == null) {
|
||||
return null;
|
||||
}
|
||||
List<Tree<T>> topNodes = new ArrayList<Tree<T>>();
|
||||
|
||||
for (Tree<T> children : nodes) {
|
||||
|
||||
String pid = children.getParentId();
|
||||
if (pid == null || idParam.equals(pid)) {
|
||||
topNodes.add(children);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
for (Tree<T> parent : nodes) {
|
||||
String id = parent.getId();
|
||||
if (id != null && id.equals(pid)) {
|
||||
parent.getChildren().add(children);
|
||||
children.setHasParent(true);
|
||||
parent.setChildren(true);
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return topNodes;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,131 @@
|
||||
package com.java2nb.common.utils;
|
||||
|
||||
import lombok.SneakyThrows;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 日期处理
|
||||
*/
|
||||
public class DateUtils {
|
||||
private final static Logger logger = LoggerFactory.getLogger(DateUtils.class);
|
||||
public final static String YEAR_PATTERN = "yyyy";
|
||||
public final static String MONTH_PATTERN = "MM";
|
||||
public final static String DAY_PATTERN = "dd";
|
||||
/**
|
||||
* 时间格式(yyyy-MM-dd)
|
||||
*/
|
||||
public final static String DATE_PATTERN = "yyyy-MM-dd";
|
||||
/**
|
||||
* 时间格式(yyyy-MM-dd HH:mm:ss)
|
||||
*/
|
||||
public final static String DATE_TIME_PATTERN = "yyyy-MM-dd HH:mm:ss";
|
||||
|
||||
public static String format(Date date) {
|
||||
return format(date, DATE_PATTERN);
|
||||
}
|
||||
|
||||
public static String format(Date date, String pattern) {
|
||||
if (date != null) {
|
||||
SimpleDateFormat df = new SimpleDateFormat(pattern);
|
||||
return df.format(date);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算距离现在多久,非精确
|
||||
*
|
||||
* @param date
|
||||
* @return
|
||||
*/
|
||||
public static String getTimeBefore(Date date) {
|
||||
Date now = new Date();
|
||||
long l = now.getTime() - date.getTime();
|
||||
long day = l / (24 * 60 * 60 * 1000);
|
||||
long hour = (l / (60 * 60 * 1000) - day * 24);
|
||||
long min = ((l / (60 * 1000)) - day * 24 * 60 - hour * 60);
|
||||
long s = (l / 1000 - day * 24 * 60 * 60 - hour * 60 * 60 - min * 60);
|
||||
String r = "";
|
||||
if (day > 0) {
|
||||
r += day + "天";
|
||||
} else if (hour > 0) {
|
||||
r += hour + "小时";
|
||||
} else if (min > 0) {
|
||||
r += min + "分";
|
||||
} else if (s > 0) {
|
||||
r += s + "秒";
|
||||
}
|
||||
r += "前";
|
||||
return r;
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算距离现在多久,精确
|
||||
*
|
||||
* @param date
|
||||
* @return
|
||||
*/
|
||||
public static String getTimeBeforeAccurate(Date date) {
|
||||
Date now = new Date();
|
||||
long l = now.getTime() - date.getTime();
|
||||
long day = l / (24 * 60 * 60 * 1000);
|
||||
long hour = (l / (60 * 60 * 1000) - day * 24);
|
||||
long min = ((l / (60 * 1000)) - day * 24 * 60 - hour * 60);
|
||||
long s = (l / 1000 - day * 24 * 60 * 60 - hour * 60 * 60 - min * 60);
|
||||
String r = "";
|
||||
if (day > 0) {
|
||||
r += day + "天";
|
||||
}
|
||||
if (hour > 0) {
|
||||
r += hour + "小时";
|
||||
}
|
||||
if (min > 0) {
|
||||
r += min + "分";
|
||||
}
|
||||
if (s > 0) {
|
||||
r += s + "秒";
|
||||
}
|
||||
r += "前";
|
||||
return r;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取过去第几天的日期
|
||||
*
|
||||
* @param past
|
||||
* @return
|
||||
*/
|
||||
@SneakyThrows
|
||||
public static String getPastDate(int past,Date date) {
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
calendar.setTime(date);
|
||||
calendar.set(Calendar.DATE, calendar.get(Calendar.DATE) - past);
|
||||
Date today = calendar.getTime();
|
||||
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
|
||||
return sdf.format(today);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取过去几天的日期集合
|
||||
*
|
||||
* @param past
|
||||
* @return
|
||||
*/
|
||||
public static List<String> getDateList(int past,Date date) {
|
||||
List<String> result = new ArrayList<>(past);
|
||||
for(int i = past - 1 ; i > 0 ; i--){
|
||||
result.add(getPastDate(i,date));
|
||||
}
|
||||
//今天的日期
|
||||
result.add(new SimpleDateFormat("yyyy-MM-dd").format(date));
|
||||
return result;
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
package com.java2nb.common.utils;
|
||||
|
||||
public class ExceptionUtils {
|
||||
public static String getExceptionAllinformation(Exception ex) {
|
||||
String sOut = "";
|
||||
StackTraceElement[] trace = ex.getStackTrace();
|
||||
for (StackTraceElement s : trace) {
|
||||
sOut += "\tat " + s + "\r\n";
|
||||
}
|
||||
return sOut;
|
||||
}
|
||||
}
|
@ -0,0 +1,55 @@
|
||||
package com.java2nb.common.utils;
|
||||
|
||||
/* author:zss
|
||||
* 日期:2017年3月31日
|
||||
* 功能:根据文件名称判断类型
|
||||
* 接受参数类型:String
|
||||
* 返回参数类型:String
|
||||
* 备注:文件类型不完善,有需要的自行添加
|
||||
*/
|
||||
public class FileType {
|
||||
public static int fileType(String fileName) {
|
||||
if (fileName == null) {
|
||||
fileName = "文件名为空!";
|
||||
return 500;
|
||||
|
||||
} else {
|
||||
// 获取文件后缀名并转化为写,用于后续比较
|
||||
String fileType = fileName.substring(fileName.lastIndexOf(".") + 1, fileName.length()).toLowerCase();
|
||||
// 创建图片类型数组0
|
||||
String[] img = { "bmp", "jpg", "jpeg", "png", "tiff", "gif", "pcx", "tga", "exif", "fpx", "svg", "psd",
|
||||
"cdr", "pcd", "dxf", "ufo", "eps", "ai", "raw", "wmf" };
|
||||
for (int i = 0; i < img.length; i++) {
|
||||
if (img[i].equals(fileType)) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// 创建文档类型数组1
|
||||
String[] document = { "txt", "doc", "docx", "xls", "htm", "html", "jsp", "rtf", "wpd", "pdf", "ppt" };
|
||||
for (int i = 0; i < document.length; i++) {
|
||||
if (document[i].equals(fileType)) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
// 创建视频类型数组2
|
||||
String[] video = { "mp4", "avi", "mov", "wmv", "asf", "navi", "3gp", "mkv", "f4v", "rmvb", "webm" };
|
||||
for (int i = 0; i < video.length; i++) {
|
||||
if (video[i].equals(fileType)) {
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
// 创建音乐类型数组3
|
||||
String[] music = { "mp3", "wma", "wav", "mod", "ra", "cd", "md", "asf", "aac", "vqf", "ape", "mid", "ogg",
|
||||
"m4a", "vqf" };
|
||||
for (int i = 0; i < music.length; i++) {
|
||||
if (music[i].equals(fileType)) {
|
||||
return 3;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
//4
|
||||
return 99;
|
||||
}
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
package com.java2nb.common.utils;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.util.UUID;
|
||||
|
||||
public class FileUtil {
|
||||
|
||||
public static void uploadFile(byte[] file, String filePath, String fileName) throws Exception {
|
||||
File targetFile = new File(filePath);
|
||||
if (!targetFile.exists()) {
|
||||
targetFile.mkdirs();
|
||||
}
|
||||
FileOutputStream out = new FileOutputStream(filePath + fileName);
|
||||
out.write(file);
|
||||
out.flush();
|
||||
out.close();
|
||||
}
|
||||
|
||||
public static boolean deleteFile(String fileName) {
|
||||
File file = new File(fileName);
|
||||
// 如果文件路径所对应的文件存在,并且是一个文件,则直接删除
|
||||
if (file.exists() && file.isFile()) {
|
||||
if (file.delete()) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static String renameToUUID(String fileName) {
|
||||
return UUID.randomUUID() + "." + fileName.substring(fileName.lastIndexOf(".") + 1);
|
||||
}
|
||||
}
|
376
novel-admin/src/main/java/com/java2nb/common/utils/GenUtils.java
Normal file
376
novel-admin/src/main/java/com/java2nb/common/utils/GenUtils.java
Normal file
@ -0,0 +1,376 @@
|
||||
package com.java2nb.common.utils;
|
||||
|
||||
|
||||
import com.java2nb.common.config.Constant;
|
||||
import com.java2nb.common.domain.ColumnDO;
|
||||
import com.java2nb.common.domain.GenColumnsDO;
|
||||
import com.java2nb.common.domain.TableDO;
|
||||
import org.apache.commons.configuration.Configuration;
|
||||
import org.apache.commons.configuration.ConfigurationException;
|
||||
import org.apache.commons.configuration.PropertiesConfiguration;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.commons.lang.WordUtils;
|
||||
import org.apache.velocity.Template;
|
||||
import org.apache.velocity.VelocityContext;
|
||||
import org.apache.velocity.app.Velocity;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipOutputStream;
|
||||
|
||||
/**
|
||||
* 代码生成器 工具类
|
||||
*/
|
||||
public class GenUtils {
|
||||
|
||||
|
||||
public static List<String> getTemplates() {
|
||||
List<String> templates = new ArrayList<String>();
|
||||
templates.add("templates/common/generator/domain.java.vm");
|
||||
templates.add("templates/common/generator/Dao.java.vm");
|
||||
//templates.add("templates/common/generator/Mapper.java.vm");
|
||||
templates.add("templates/common/generator/Mapper.xml.vm");
|
||||
templates.add("templates/common/generator/Service.java.vm");
|
||||
templates.add("templates/common/generator/ServiceImpl.java.vm");
|
||||
templates.add("templates/common/generator/Controller.java.vm");
|
||||
templates.add("templates/common/generator/list.html.vm");
|
||||
templates.add("templates/common/generator/add.html.vm");
|
||||
templates.add("templates/common/generator/edit.html.vm");
|
||||
templates.add("templates/common/generator/detail.html.vm");
|
||||
templates.add("templates/common/generator/list.js.vm");
|
||||
templates.add("templates/common/generator/add.js.vm");
|
||||
templates.add("templates/common/generator/edit.js.vm");
|
||||
templates.add("templates/common/generator/menu.sql.vm");
|
||||
|
||||
//templates.add("templates/common/generator/menu.sql.vm");
|
||||
return templates;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 生成代码
|
||||
*/
|
||||
|
||||
|
||||
public static void generatorCode(Map<String, String> table,
|
||||
List<Map<String, String>> columns, ZipOutputStream zip) {
|
||||
/*//封装模板数据
|
||||
Map<String, Object> map = new HashMap<>(16);
|
||||
|
||||
|
||||
//配置信息
|
||||
Configuration config = getConfig();
|
||||
//表信息
|
||||
TableDO tableDO = new TableDO();
|
||||
tableDO.setTableName(table.get("tableName"));
|
||||
tableDO.setComments(table.get("tableComment"));
|
||||
//表名转换成Java类名
|
||||
String className = tableToJava(tableDO.getTableName(), config.getString("tablePrefix"), config.getString("autoRemovePre"));
|
||||
tableDO.setClassName(className);
|
||||
tableDO.setClassname(StringUtils.uncapitalize(className));
|
||||
|
||||
//列信息
|
||||
List<ColumnDO> columsList = new ArrayList<>();
|
||||
for (Map<String, String> column : columns) {
|
||||
ColumnDO columnDO = new ColumnDO();
|
||||
columnDO.setColumnName(column.get("columnName"));
|
||||
columnDO.setDataType(column.get("dataType"));
|
||||
columnDO.setComments(column.get("columnComment"));
|
||||
columnDO.setExtra(column.get("extra"));
|
||||
|
||||
//列名转换成Java属性名
|
||||
String attrName = columnToJava(columnDO.getColumnName());
|
||||
columnDO.setAttrName(attrName);
|
||||
columnDO.setAttrname(StringUtils.uncapitalize(attrName));
|
||||
|
||||
//列的数据类型,转换成Java类型
|
||||
String attrType = config.getString(columnDO.getDataType(), "unknowType");
|
||||
switch (attrType) {
|
||||
case "BigDecimal": {
|
||||
map.put("hasBigDecimal", true);
|
||||
break;
|
||||
}
|
||||
case "Date": {
|
||||
map.put("hasDate", true);
|
||||
break;
|
||||
}
|
||||
case "Long": {
|
||||
map.put("hasLong", true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
columnDO.setAttrType(attrType);
|
||||
|
||||
//是否主键
|
||||
if ("PRI".equalsIgnoreCase(column.get("columnKey")) && tableDO.getPk() == null) {
|
||||
tableDO.setPk(columnDO);
|
||||
}
|
||||
|
||||
columsList.add(columnDO);
|
||||
}
|
||||
tableDO.setColumns(columsList);
|
||||
|
||||
//没主键,则第一个字段为主键
|
||||
if (tableDO.getPk() == null) {
|
||||
tableDO.setPk(tableDO.getColumns().get(0));
|
||||
}
|
||||
|
||||
//设置velocity资源加载器
|
||||
Properties prop = new Properties();
|
||||
prop.put("file.resource.loader.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
|
||||
Velocity.init(prop);
|
||||
|
||||
|
||||
map.put("tableName", tableDO.getTableName());
|
||||
map.put("comments", tableDO.getComments());
|
||||
map.put("pk", tableDO.getPk());
|
||||
map.put("className", tableDO.getClassName());
|
||||
map.put("classname", tableDO.getClassname());
|
||||
map.put("pathName", config.getString("package").substring(config.getString("package").lastIndexOf(".") + 1));
|
||||
map.put("columns", tableDO.getColumns());
|
||||
map.put("package", config.getString("package"));
|
||||
map.put("author", config.getString("author"));
|
||||
map.put("email", config.getString("email"));
|
||||
map.put("datetime", DateUtils.format(new Date(), DateUtils.DATE_TIME_PATTERN));
|
||||
VelocityContext context = new VelocityContext(map);
|
||||
|
||||
//获取模板列表
|
||||
List<String> templates = getTemplates();
|
||||
for (String template : templates) {
|
||||
//渲染模板
|
||||
StringWriter sw = new StringWriter();
|
||||
Template tpl = Velocity.getTemplate(template, "UTF-8");
|
||||
tpl.merge(context, sw);
|
||||
|
||||
try {
|
||||
String fileName = getFileName(template, tableDO.getClassname(), tableDO.getClassName(), config.getString("package"));
|
||||
if (zip != null) {
|
||||
//添加到zip
|
||||
zip.putNextEntry(new ZipEntry(fileName));
|
||||
IOUtils.write(sw.toString(), zip, "UTF-8");
|
||||
IOUtils.closeQuietly(sw);
|
||||
zip.closeEntry();
|
||||
} else {
|
||||
String srcPath = config.getString("srcPath");
|
||||
fileName = srcPath + File.separator + fileName;
|
||||
File file = new File(fileName);
|
||||
if (file.exists()) {
|
||||
file = new File(fileName + 1);
|
||||
}
|
||||
File parentCatelog = file.getParentFile();
|
||||
if (!parentCatelog.exists()) {
|
||||
parentCatelog.mkdirs();
|
||||
}
|
||||
OutputStream fos = new FileOutputStream(file);
|
||||
IOUtils.write(sw.toString(), fos, "UTF-8");
|
||||
fos.close();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("渲染模板失败,表名:" + tableDO.getTableName(), e);
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 列名转换成Java属性名
|
||||
*/
|
||||
public static String columnToJava(String columnName) {
|
||||
return WordUtils.capitalizeFully(columnName, new char[]{'_'}).replace("_", "");
|
||||
}
|
||||
|
||||
/**
|
||||
* 表名转换成Java类名
|
||||
*/
|
||||
public static String tableToJava(String tableName, String tablePrefix, String autoRemovePre) {
|
||||
if (Constant.AUTO_REOMVE_PRE.equals(autoRemovePre)) {
|
||||
tableName = tableName.substring(tableName.indexOf("_") + 1);
|
||||
}
|
||||
if (StringUtils.isNotBlank(tablePrefix)) {
|
||||
tableName = tableName.replace(tablePrefix, "");
|
||||
}
|
||||
|
||||
return columnToJava(tableName);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取配置信息
|
||||
*/
|
||||
public static Configuration getConfig() {
|
||||
try {
|
||||
return new PropertiesConfiguration("generator.properties");
|
||||
} catch (ConfigurationException e) {
|
||||
throw new RuntimeException("获取配置文件失败,", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取文件名
|
||||
*/
|
||||
public static String getFileName(String template, String classname, String className, String packageName) {
|
||||
String moduleName = packageName.substring(packageName.lastIndexOf(".") + 1);
|
||||
|
||||
String javaPackagePath = "main" + File.separator + "java" + File.separator;
|
||||
//String modulesname=config.getString("packageName");
|
||||
if (StringUtils.isNotBlank(packageName)) {
|
||||
javaPackagePath += packageName.replace(".", File.separator) + File.separator;
|
||||
}
|
||||
|
||||
if (template.contains("domain.java.vm")) {
|
||||
return javaPackagePath + "domain" + File.separator + className + "DO.java";
|
||||
}
|
||||
|
||||
if (template.contains("Dao.java.vm")) {
|
||||
return javaPackagePath + "dao" + File.separator + className + "Dao.java";
|
||||
}
|
||||
|
||||
// if(template.contains("Mapper.java.vm")){
|
||||
// return packagePath + "dao" + File.separator + className + "Mapper.java";
|
||||
// }
|
||||
|
||||
if (template.contains("Service.java.vm")) {
|
||||
return javaPackagePath + "service" + File.separator + className + "Service.java";
|
||||
}
|
||||
|
||||
if (template.contains("ServiceImpl.java.vm")) {
|
||||
return javaPackagePath + "service" + File.separator + "impl" + File.separator + className + "ServiceImpl.java";
|
||||
}
|
||||
|
||||
if (template.contains("Controller.java.vm")) {
|
||||
return javaPackagePath + "controller" + File.separator + className + "Controller.java";
|
||||
}
|
||||
|
||||
if (template.contains("Mapper.xml.vm")) {
|
||||
return "main" + File.separator + "resources" + File.separator + "mybatis" + File.separator + moduleName + File.separator + className + "Mapper.xml";
|
||||
}
|
||||
|
||||
if (template.contains("list.html.vm")) {
|
||||
return "main" + File.separator + "resources" + File.separator + "templates" + File.separator
|
||||
+ moduleName + File.separator + classname + File.separator + classname + ".html";
|
||||
// + "modules" + File.separator + "generator" + File.separator + className.toLowerCase() + ".html";
|
||||
}
|
||||
if (template.contains("add.html.vm")) {
|
||||
return "main" + File.separator + "resources" + File.separator + "templates" + File.separator
|
||||
+ moduleName + File.separator + classname + File.separator + "add.html";
|
||||
}
|
||||
if (template.contains("edit.html.vm")) {
|
||||
return "main" + File.separator + "resources" + File.separator + "templates" + File.separator
|
||||
+ moduleName + File.separator + classname + File.separator + "edit.html";
|
||||
}
|
||||
if (template.contains("detail.html.vm")) {
|
||||
return "main" + File.separator + "resources" + File.separator + "templates" + File.separator
|
||||
+ moduleName + File.separator + classname + File.separator + "detail.html";
|
||||
}
|
||||
|
||||
if (template.contains("list.js.vm")) {
|
||||
return "main" + File.separator + "resources" + File.separator + "static" + File.separator + "js" + File.separator
|
||||
+ "appjs" + File.separator + moduleName + File.separator + classname + File.separator + classname + ".js";
|
||||
// + "modules" + File.separator + "generator" + File.separator + className.toLowerCase() + ".js";
|
||||
}
|
||||
if (template.contains("add.js.vm")) {
|
||||
return "main" + File.separator + "resources" + File.separator + "static" + File.separator + "js" + File.separator
|
||||
+ "appjs" + File.separator + moduleName + File.separator + classname + File.separator + "add.js";
|
||||
}
|
||||
if (template.contains("edit.js.vm")) {
|
||||
return "main" + File.separator + "resources" + File.separator + "static" + File.separator + "js" + File.separator
|
||||
+ "appjs" + File.separator + moduleName + File.separator + classname + File.separator + "edit.js";
|
||||
}
|
||||
if (template.contains("menu.sql.vm")) {
|
||||
return "main" + File.separator + "resources" + File.separator + "static" + File.separator + "sql"
|
||||
+ File.separator + moduleName + File.separator + classname + File.separator + "menu.js";
|
||||
}
|
||||
|
||||
// if(template.contains("menu.sql.vm")){
|
||||
// return className.toLowerCase() + "_menu.sql";
|
||||
// }
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void generatorCode(Map<String, String> table, GenColumnsDO pkColumn, List<GenColumnsDO> list) {
|
||||
//封装模板数据
|
||||
Map<String, Object> map = new HashMap<>(16);
|
||||
|
||||
|
||||
//配置信息
|
||||
Configuration config = getConfig();
|
||||
//表信息
|
||||
TableDO tableDO = new TableDO();
|
||||
tableDO.setTableName(table.get("tableName"));
|
||||
tableDO.setComments(table.get("tableComment"));
|
||||
//表名转换成Java类名
|
||||
String className = tableToJava(tableDO.getTableName(), config.getString("tablePrefix"), config.getString("autoRemovePre"));
|
||||
tableDO.setClassName(className);
|
||||
tableDO.setClassname(StringUtils.uncapitalize(className));
|
||||
|
||||
|
||||
|
||||
Collections.sort(list, Comparator.comparingInt(GenColumnsDO::getColumnSort));
|
||||
|
||||
for(GenColumnsDO genColumnsDO : list){
|
||||
String attrName = columnToJava(genColumnsDO.getColumnName());
|
||||
genColumnsDO.setAttrName(attrName);
|
||||
genColumnsDO.setAttrname(StringUtils.uncapitalize(attrName));
|
||||
}
|
||||
|
||||
String attrName = columnToJava(pkColumn.getColumnName());
|
||||
pkColumn.setAttrName(attrName);
|
||||
pkColumn.setAttrname(StringUtils.uncapitalize(attrName));
|
||||
|
||||
tableDO.setPk(pkColumn);
|
||||
|
||||
list.add(0,pkColumn);
|
||||
tableDO.setColumns(list);
|
||||
|
||||
//设置velocity资源加载器
|
||||
Properties prop = new Properties();
|
||||
prop.put("file.resource.loader.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
|
||||
Velocity.init(prop);
|
||||
|
||||
|
||||
map.put("tableName", tableDO.getTableName());
|
||||
map.put("comments", tableDO.getComments());
|
||||
map.put("pk", tableDO.getPk());
|
||||
map.put("className", tableDO.getClassName());
|
||||
map.put("classname", tableDO.getClassname());
|
||||
map.put("pathName", config.getString("package").substring(config.getString("package").lastIndexOf(".") + 1));
|
||||
map.put("columns", tableDO.getColumns());
|
||||
map.put("package", config.getString("package"));
|
||||
map.put("author", config.getString("author"));
|
||||
map.put("email", config.getString("email"));
|
||||
map.put("datetime", DateUtils.format(new Date(), DateUtils.DATE_TIME_PATTERN));
|
||||
VelocityContext context = new VelocityContext(map);
|
||||
|
||||
//获取模板列表
|
||||
List<String> templates = getTemplates();
|
||||
for (String template : templates) {
|
||||
//渲染模板
|
||||
StringWriter sw = new StringWriter();
|
||||
Template tpl = Velocity.getTemplate(template, "UTF-8");
|
||||
tpl.merge(context, sw);
|
||||
|
||||
try {
|
||||
String fileName = getFileName(template, tableDO.getClassname(), tableDO.getClassName(), config.getString("package"));
|
||||
|
||||
String srcPath = config.getString("srcPath");
|
||||
fileName = srcPath + File.separator + fileName;
|
||||
File file = new File(fileName);
|
||||
if (file.exists()) {
|
||||
file = new File(fileName + 1);
|
||||
}
|
||||
File parentCatelog = file.getParentFile();
|
||||
if (!parentCatelog.exists()) {
|
||||
parentCatelog.mkdirs();
|
||||
}
|
||||
OutputStream fos = new FileOutputStream(file);
|
||||
IOUtils.write(sw.toString(), fos, "UTF-8");
|
||||
fos.close();
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("渲染模板失败,表名:" + tableDO.getTableName(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
package com.java2nb.common.utils;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.springframework.web.context.request.RequestContextHolder;
|
||||
import org.springframework.web.context.request.ServletRequestAttributes;
|
||||
|
||||
public class HttpContextUtils {
|
||||
public static HttpServletRequest getHttpServletRequest() {
|
||||
return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
|
||||
}
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
package com.java2nb.common.utils;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
public class HttpServletUtils {
|
||||
public static boolean jsAjax(HttpServletRequest req){
|
||||
//判断是否为ajax请求,默认不是
|
||||
boolean isAjaxRequest = false;
|
||||
if(!StringUtils.isBlank(req.getHeader("x-requested-with")) && req.getHeader("x-requested-with").equals("XMLHttpRequest")){
|
||||
isAjaxRequest = true;
|
||||
}
|
||||
return isAjaxRequest;
|
||||
}
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
package com.java2nb.common.utils;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
public class IPUtils {
|
||||
private static Logger logger = LoggerFactory.getLogger(IPUtils.class);
|
||||
|
||||
/**
|
||||
* 获取IP地址
|
||||
*
|
||||
* 使用Nginx等反向代理软件, 则不能通过request.getRemoteAddr()获取IP地址
|
||||
* 如果使用了多级反向代理的话,X-Forwarded-For的值并不止一个,而是一串IP地址,X-Forwarded-For中第一个非unknown的有效IP字符串,则为真实IP地址
|
||||
*/
|
||||
public static String getIpAddr(HttpServletRequest request) {
|
||||
|
||||
String ip = request.getHeader("x-forwarded-for");
|
||||
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
|
||||
ip = request.getHeader("Proxy-Client-IP");
|
||||
}
|
||||
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
|
||||
ip = request.getHeader("WL-Proxy-Client-IP");
|
||||
}
|
||||
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
|
||||
ip = request.getRemoteAddr();
|
||||
}
|
||||
return "0:0:0:0:0:0:0:1".equals(ip) ? "127.0.0.1" : ip;
|
||||
}
|
||||
|
||||
}
|
163
novel-admin/src/main/java/com/java2nb/common/utils/IdWorker.java
Normal file
163
novel-admin/src/main/java/com/java2nb/common/utils/IdWorker.java
Normal file
@ -0,0 +1,163 @@
|
||||
package com.java2nb.common.utils;
|
||||
|
||||
|
||||
import java.lang.management.ManagementFactory;
|
||||
import java.net.InetAddress;
|
||||
import java.net.NetworkInterface;
|
||||
|
||||
/**
|
||||
* <p>名称:IdWorker.java</p>
|
||||
* <p>描述:分布式自增长ID</p>
|
||||
* <pre>
|
||||
* Twitter的 Snowflake JAVA实现方案
|
||||
* </pre>
|
||||
* 核心代码为其IdWorker这个类实现,其原理结构如下,我分别用一个0表示一位,用—分割开部分的作用:
|
||||
* 1||0---0000000000 0000000000 0000000000 0000000000 0 --- 00000 ---00000 ---000000000000
|
||||
* 在上面的字符串中,第一位为未使用(实际上也可作为long的符号位),接下来的41位为毫秒级时间,
|
||||
* 然后5位datacenter标识位,5位机器ID(并不算标识符,实际是为线程标识),
|
||||
* 然后12位该毫秒内的当前毫秒内的计数,加起来刚好64位,为一个Long型。
|
||||
* 这样的好处是,整体上按照时间自增排序,并且整个分布式系统内不会产生ID碰撞(由datacenter和机器ID作区分),
|
||||
* 并且效率较高,经测试,snowflake每秒能够产生26万ID左右,完全满足需要。
|
||||
* <p>
|
||||
* 64位ID (42(毫秒)+5(机器ID)+5(业务编码)+12(重复累加))
|
||||
*
|
||||
*/
|
||||
public class IdWorker {
|
||||
// 时间起始标记点,作为基准,一般取系统的最近时间(一旦确定不能变动)
|
||||
private final static long twepoch = 1288834974657L;
|
||||
// 机器标识位数
|
||||
private final static long workerIdBits = 5L;
|
||||
// 数据中心标识位数
|
||||
private final static long datacenterIdBits = 5L;
|
||||
// 机器ID最大值
|
||||
private final static long maxWorkerId = -1L ^ (-1L << workerIdBits);
|
||||
// 数据中心ID最大值
|
||||
private final static long maxDatacenterId = -1L ^ (-1L << datacenterIdBits);
|
||||
// 毫秒内自增位
|
||||
private final static long sequenceBits = 12L;
|
||||
// 机器ID偏左移12位
|
||||
private final static long workerIdShift = sequenceBits;
|
||||
// 数据中心ID左移17位
|
||||
private final static long datacenterIdShift = sequenceBits + workerIdBits;
|
||||
// 时间毫秒左移22位
|
||||
private final static long timestampLeftShift = sequenceBits + workerIdBits + datacenterIdBits;
|
||||
|
||||
private final static long sequenceMask = -1L ^ (-1L << sequenceBits);
|
||||
/* 上次生产id时间戳 */
|
||||
private static long lastTimestamp = -1L;
|
||||
// 0,并发控制
|
||||
private long sequence = 0L;
|
||||
|
||||
private final long workerId;
|
||||
// 数据标识id部分
|
||||
private final long datacenterId;
|
||||
|
||||
public IdWorker(){
|
||||
this.datacenterId = getDatacenterId(maxDatacenterId);
|
||||
this.workerId = getMaxWorkerId(datacenterId, maxWorkerId);
|
||||
}
|
||||
/**
|
||||
* @param workerId
|
||||
* 工作机器ID
|
||||
* @param datacenterId
|
||||
* 序列号
|
||||
*/
|
||||
public IdWorker(long workerId, long datacenterId) {
|
||||
if (workerId > maxWorkerId || workerId < 0) {
|
||||
throw new IllegalArgumentException(String.format("worker Id can't be greater than %d or less than 0", maxWorkerId));
|
||||
}
|
||||
if (datacenterId > maxDatacenterId || datacenterId < 0) {
|
||||
throw new IllegalArgumentException(String.format("datacenter Id can't be greater than %d or less than 0", maxDatacenterId));
|
||||
}
|
||||
this.workerId = workerId;
|
||||
this.datacenterId = datacenterId;
|
||||
}
|
||||
/**
|
||||
* 获取下一个ID
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public synchronized long nextId() {
|
||||
long timestamp = timeGen();
|
||||
if (timestamp < lastTimestamp) {
|
||||
throw new RuntimeException(String.format("Clock moved backwards. Refusing to generate id for %d milliseconds", lastTimestamp - timestamp));
|
||||
}
|
||||
|
||||
if (lastTimestamp == timestamp) {
|
||||
// 当前毫秒内,则+1
|
||||
sequence = (sequence + 1) & sequenceMask;
|
||||
if (sequence == 0) {
|
||||
// 当前毫秒内计数满了,则等待下一秒
|
||||
timestamp = tilNextMillis(lastTimestamp);
|
||||
}
|
||||
} else {
|
||||
sequence = 0L;
|
||||
}
|
||||
lastTimestamp = timestamp;
|
||||
// ID偏移组合生成最终的ID,并返回ID
|
||||
long nextId = ((timestamp - twepoch) << timestampLeftShift)
|
||||
| (datacenterId << datacenterIdShift)
|
||||
| (workerId << workerIdShift) | sequence;
|
||||
|
||||
return nextId;
|
||||
}
|
||||
|
||||
private long tilNextMillis(final long lastTimestamp) {
|
||||
long timestamp = this.timeGen();
|
||||
while (timestamp <= lastTimestamp) {
|
||||
timestamp = this.timeGen();
|
||||
}
|
||||
return timestamp;
|
||||
}
|
||||
|
||||
private long timeGen() {
|
||||
return System.currentTimeMillis();
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 获取 maxWorkerId
|
||||
* </p>
|
||||
*/
|
||||
protected static long getMaxWorkerId(long datacenterId, long maxWorkerId) {
|
||||
StringBuffer mpid = new StringBuffer();
|
||||
mpid.append(datacenterId);
|
||||
String name = ManagementFactory.getRuntimeMXBean().getName();
|
||||
if (!name.isEmpty()) {
|
||||
/*
|
||||
* GET jvmPid
|
||||
*/
|
||||
mpid.append(name.split("@")[0]);
|
||||
}
|
||||
/*
|
||||
* MAC + PID 的 hashcode 获取16个低位
|
||||
*/
|
||||
return (mpid.toString().hashCode() & 0xffff) % (maxWorkerId + 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 数据标识id部分
|
||||
* </p>
|
||||
*/
|
||||
protected static long getDatacenterId(long maxDatacenterId) {
|
||||
long id = 0L;
|
||||
try {
|
||||
InetAddress ip = InetAddress.getLocalHost();
|
||||
NetworkInterface network = NetworkInterface.getByInetAddress(ip);
|
||||
if (network == null) {
|
||||
id = 1L;
|
||||
} else {
|
||||
byte[] mac = network.getHardwareAddress();
|
||||
id = ((0x000000FF & (long) mac[mac.length - 1])
|
||||
| (0x0000FF00 & (((long) mac[mac.length - 2]) << 8))) >> 6;
|
||||
id = id % (maxDatacenterId + 1);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
System.out.println(" getDatacenterId: " + e.getMessage());
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,77 @@
|
||||
package com.java2nb.common.utils;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.imageio.ImageReadParam;
|
||||
import javax.imageio.ImageReader;
|
||||
import javax.imageio.stream.ImageInputStream;
|
||||
import java.awt.*;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Iterator;
|
||||
|
||||
/**
|
||||
* @author xiongxy
|
||||
* @date 2019-09-25 15:09:21
|
||||
*/
|
||||
@Slf4j
|
||||
public class ImageUtils {
|
||||
/***
|
||||
* 剪裁图片
|
||||
* @param file 图片
|
||||
* @param x 起点横坐标
|
||||
* @param y 纵坐标
|
||||
* @param w 长
|
||||
* @param h 高
|
||||
* @throws IOException
|
||||
* @date 2019-09-25 15:09:21
|
||||
*/
|
||||
public static BufferedImage cutImage(MultipartFile file, int x, int y, int w, int h,String prefix) {
|
||||
|
||||
Iterator iterator = ImageIO.getImageReadersByFormatName(prefix);
|
||||
try {
|
||||
ImageReader reader = (ImageReader)iterator.next();
|
||||
//转换成输入流
|
||||
InputStream in = file.getInputStream();
|
||||
ImageInputStream iis = ImageIO.createImageInputStream(in);
|
||||
reader.setInput(iis, true);
|
||||
ImageReadParam param = reader.getDefaultReadParam();
|
||||
Rectangle rect = new Rectangle(x, y, w,h);
|
||||
param.setSourceRegion(rect);
|
||||
BufferedImage bi = reader.read(0,param);
|
||||
return bi;
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(),e);
|
||||
|
||||
}
|
||||
return null;
|
||||
}
|
||||
/***
|
||||
* 图片旋转指定角度
|
||||
* @param bufferedimage 图像
|
||||
* @param degree 角度
|
||||
* @return
|
||||
* @date 2019-09-25 15:09:21
|
||||
*/
|
||||
public static BufferedImage rotateImage(BufferedImage bufferedimage, int degree) {
|
||||
int w = bufferedimage.getWidth();
|
||||
int h = bufferedimage.getHeight();
|
||||
int type = bufferedimage.getColorModel().getTransparency();
|
||||
BufferedImage img;
|
||||
Graphics2D graphics2d;
|
||||
(graphics2d = (img = new BufferedImage(w, h, type))
|
||||
.createGraphics()).setRenderingHint(
|
||||
RenderingHints.KEY_INTERPOLATION,
|
||||
RenderingHints.VALUE_INTERPOLATION_BILINEAR);
|
||||
graphics2d.setPaint(Color.WHITE);
|
||||
graphics2d.fillRect(0, 0, w, h);
|
||||
graphics2d.rotate(Math.toRadians(degree), w / 2, h / 2);
|
||||
graphics2d.drawImage(bufferedimage, 0, 0,Color.WHITE, null);
|
||||
graphics2d.dispose();
|
||||
return img;
|
||||
}
|
||||
}
|
@ -0,0 +1,86 @@
|
||||
package com.java2nb.common.utils;
|
||||
|
||||
import com.alibaba.druid.util.StringUtils;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class JSONUtils {
|
||||
/**
|
||||
* Bean对象转JSON
|
||||
*
|
||||
* @param object
|
||||
* @param dataFormatString
|
||||
* @return
|
||||
*/
|
||||
public static String beanToJson(Object object, String dataFormatString) {
|
||||
if (object != null) {
|
||||
if (StringUtils.isEmpty(dataFormatString)) {
|
||||
return JSONObject.toJSONString(object);
|
||||
}
|
||||
return JSON.toJSONStringWithDateFormat(object, dataFormatString);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Bean对象转JSON
|
||||
*
|
||||
* @param object
|
||||
* @return
|
||||
*/
|
||||
public static String beanToJson(Object object) {
|
||||
if (object != null) {
|
||||
return JSON.toJSONString(object);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* String转JSON字符串
|
||||
*
|
||||
* @param key
|
||||
* @param value
|
||||
* @return
|
||||
*/
|
||||
public static String stringToJsonByFastjson(String key, String value) {
|
||||
if (StringUtils.isEmpty(key) || StringUtils.isEmpty(value)) {
|
||||
return null;
|
||||
}
|
||||
Map<String, String> map = new HashMap<String, String>(16);
|
||||
map.put(key, value);
|
||||
return beanToJson(map, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将json字符串转换成对象
|
||||
*
|
||||
* @param json
|
||||
* @param clazz
|
||||
* @return
|
||||
*/
|
||||
public static Object jsonToBean(String json, Object clazz) {
|
||||
if (StringUtils.isEmpty(json) || clazz == null) {
|
||||
return null;
|
||||
}
|
||||
return JSON.parseObject(json, clazz.getClass());
|
||||
}
|
||||
|
||||
/**
|
||||
* json字符串转map
|
||||
*
|
||||
* @param json
|
||||
* @return
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static Map<String, Object> jsonToMap(String json) {
|
||||
if (StringUtils.isEmpty(json)) {
|
||||
return null;
|
||||
}
|
||||
return JSON.parseObject(json, Map.class);
|
||||
}
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
package com.java2nb.common.utils;
|
||||
|
||||
import org.apache.shiro.crypto.hash.SimpleHash;
|
||||
import org.apache.shiro.util.ByteSource;
|
||||
|
||||
public class MD5Utils {
|
||||
private static final String SALT = "1qazxsw2";
|
||||
|
||||
private static final String ALGORITH_NAME = "md5";
|
||||
|
||||
private static final int HASH_ITERATIONS = 2;
|
||||
|
||||
public static String encrypt(String pswd) {
|
||||
String newPassword = new SimpleHash(ALGORITH_NAME, pswd, ByteSource.Util.bytes(SALT), HASH_ITERATIONS).toHex();
|
||||
return newPassword;
|
||||
}
|
||||
|
||||
public static String encrypt(String username, String pswd) {
|
||||
String newPassword = new SimpleHash(ALGORITH_NAME, pswd, ByteSource.Util.bytes(username + SALT),
|
||||
HASH_ITERATIONS).toHex();
|
||||
return newPassword;
|
||||
}
|
||||
public static void main(String[] args) {
|
||||
|
||||
//System.out.println(MD5Utils.encrypt("admin", "1"));
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
package com.java2nb.common.utils;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @Author xiongxy
|
||||
*/
|
||||
public class PageBean implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
private int total;
|
||||
private List<?> rows;
|
||||
|
||||
public PageBean(List<?> list, int total) {
|
||||
this.rows = list;
|
||||
this.total = total;
|
||||
}
|
||||
|
||||
public int getTotal() {
|
||||
return total;
|
||||
}
|
||||
|
||||
public void setTotal(int total) {
|
||||
this.total = total;
|
||||
}
|
||||
|
||||
public List<?> getRows() {
|
||||
return rows;
|
||||
}
|
||||
|
||||
public void setRows(List<?> rows) {
|
||||
this.rows = rows;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,41 @@
|
||||
package com.java2nb.common.utils;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 查询参数
|
||||
*/
|
||||
public class Query extends LinkedHashMap<String, Object> {
|
||||
private static final long serialVersionUID = 1L;
|
||||
//
|
||||
private int offset;
|
||||
// 每页条数
|
||||
private int limit;
|
||||
|
||||
public Query(Map<String, Object> params) {
|
||||
this.putAll(params);
|
||||
// 分页参数
|
||||
this.offset = Integer.parseInt(params.get("offset").toString());
|
||||
this.limit = Integer.parseInt(params.get("limit").toString());
|
||||
this.put("offset", offset);
|
||||
this.put("page", offset / limit + 1);
|
||||
this.put("limit", limit);
|
||||
}
|
||||
|
||||
public int getOffset() {
|
||||
return offset;
|
||||
}
|
||||
|
||||
public void setOffset(int offset) {
|
||||
this.put("offset", offset);
|
||||
}
|
||||
|
||||
public int getLimit() {
|
||||
return limit;
|
||||
}
|
||||
|
||||
public void setLimit(int limit) {
|
||||
this.limit = limit;
|
||||
}
|
||||
}
|
50
novel-admin/src/main/java/com/java2nb/common/utils/R.java
Normal file
50
novel-admin/src/main/java/com/java2nb/common/utils/R.java
Normal file
@ -0,0 +1,50 @@
|
||||
package com.java2nb.common.utils;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class R extends HashMap<String, Object> {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public R() {
|
||||
put("code", 0);
|
||||
put("msg", "操作成功");
|
||||
}
|
||||
|
||||
public static R error() {
|
||||
return error(1, "操作失败");
|
||||
}
|
||||
|
||||
public static R error(String msg) {
|
||||
return error(500, msg);
|
||||
}
|
||||
|
||||
public static R error(int code, String msg) {
|
||||
R r = new R();
|
||||
r.put("code", code);
|
||||
r.put("msg", msg);
|
||||
return r;
|
||||
}
|
||||
|
||||
public static R ok(String msg) {
|
||||
R r = new R();
|
||||
r.put("msg", msg);
|
||||
return r;
|
||||
}
|
||||
|
||||
public static R ok(Map<String, Object> map) {
|
||||
R r = new R();
|
||||
r.putAll(map);
|
||||
return r;
|
||||
}
|
||||
|
||||
public static R ok() {
|
||||
return new R();
|
||||
}
|
||||
|
||||
@Override
|
||||
public R put(String key, Object value) {
|
||||
super.put(key, value);
|
||||
return this;
|
||||
}
|
||||
}
|
@ -0,0 +1,122 @@
|
||||
package com.java2nb.common.utils;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.servlet.http.HttpSession;
|
||||
import java.awt.*;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.util.Random;
|
||||
|
||||
/**
|
||||
* @author xiongxy
|
||||
*/
|
||||
public class RandomValidateCodeUtil {
|
||||
|
||||
|
||||
public static final String RANDOMCODEKEY = "RANDOMVALIDATECODEKEY";//放到session中的key
|
||||
private String randString = "0123456789";//随机产生只有数字的字符串 private String
|
||||
//private String randString = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";//随机产生只有字母的字符串
|
||||
//private String randString = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";//随机产生数字与字母组合的字符串
|
||||
private int width = 95;// 图片宽
|
||||
private int height = 25;// 图片高
|
||||
private int lineSize = 40;// 干扰线数量
|
||||
private int stringNum = 4;// 随机产生字符数量
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(RandomValidateCodeUtil.class);
|
||||
|
||||
private Random random = new Random();
|
||||
|
||||
/**
|
||||
* 获得字体
|
||||
*/
|
||||
private Font getFont() {
|
||||
return new Font("Fixedsys", Font.CENTER_BASELINE, 18);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得颜色
|
||||
*/
|
||||
private Color getRandColor(int fc, int bc) {
|
||||
if (fc > 255) {
|
||||
fc = 255;
|
||||
}
|
||||
if (bc > 255) {
|
||||
bc = 255;
|
||||
}
|
||||
int r = fc + random.nextInt(bc - fc - 16);
|
||||
int g = fc + random.nextInt(bc - fc - 14);
|
||||
int b = fc + random.nextInt(bc - fc - 18);
|
||||
return new Color(r, g, b);
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成随机图片
|
||||
*/
|
||||
public void getRandcode(HttpServletRequest request, HttpServletResponse response) {
|
||||
HttpSession session = request.getSession();
|
||||
// BufferedImage类是具有缓冲区的Image类,Image类是用于描述图像信息的类
|
||||
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_BGR);
|
||||
Graphics g = image.getGraphics();// 产生Image对象的Graphics对象,改对象可以在图像上进行各种绘制操作
|
||||
g.fillRect(0, 0, width, height);//图片大小
|
||||
g.setFont(new Font("Default", Font.ROMAN_BASELINE, 18));//字体大小
|
||||
g.setColor(getRandColor(110, 133));//字体颜色
|
||||
// 绘制干扰线
|
||||
for (int i = 0; i <= lineSize; i++) {
|
||||
drowLine(g);
|
||||
}
|
||||
// 绘制随机字符
|
||||
String randomString = "";
|
||||
for (int i = 1; i <= stringNum; i++) {
|
||||
randomString = drowString(g, randomString, i);
|
||||
}
|
||||
logger.info(randomString);
|
||||
//将生成的随机字符串保存到session中
|
||||
session.removeAttribute(RANDOMCODEKEY);
|
||||
session.setAttribute(RANDOMCODEKEY, randomString);
|
||||
g.dispose();
|
||||
try {
|
||||
// 将内存中的图片通过流动形式输出到客户端
|
||||
ImageIO.write(image, "JPEG", response.getOutputStream());
|
||||
} catch (Exception e) {
|
||||
logger.error("将内存中的图片通过流动形式输出到客户端失败>>>> ", e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 绘制字符串
|
||||
*/
|
||||
private String drowString(Graphics g, String randomString, int i) {
|
||||
g.setFont(getFont());
|
||||
g.setColor(new Color(random.nextInt(101), random.nextInt(111), random
|
||||
.nextInt(121)));
|
||||
String rand = String.valueOf(getRandomString(random.nextInt(randString
|
||||
.length())));
|
||||
randomString += rand;
|
||||
g.translate(random.nextInt(3), random.nextInt(3));
|
||||
g.drawString(rand, 13 * i, 16);
|
||||
return randomString;
|
||||
}
|
||||
|
||||
/**
|
||||
* 绘制干扰线
|
||||
*/
|
||||
private void drowLine(Graphics g) {
|
||||
int x = random.nextInt(width);
|
||||
int y = random.nextInt(height);
|
||||
int xl = random.nextInt(13);
|
||||
int yl = random.nextInt(15);
|
||||
g.drawLine(x, y, x + xl, y + yl);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取随机的字符
|
||||
*/
|
||||
public String getRandomString(int num) {
|
||||
return String.valueOf(randString.charAt(num));
|
||||
}
|
||||
}
|
@ -0,0 +1,601 @@
|
||||
package com.java2nb.common.utils;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public final class RedisUtil {
|
||||
|
||||
|
||||
@Autowired
|
||||
private RedisTemplate<String, Object> redisTemplate;
|
||||
|
||||
/**
|
||||
* 指定缓存失效时间
|
||||
*
|
||||
* @param key 键
|
||||
* @param time 时间(秒)
|
||||
* @return
|
||||
*/
|
||||
|
||||
|
||||
public boolean expire(String key, long time) {
|
||||
try {
|
||||
if (time > 0) {
|
||||
redisTemplate.expire(key, time, TimeUnit.SECONDS);
|
||||
}
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(),e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 根据key 获取过期时间
|
||||
*
|
||||
* @param key 键 不能为null
|
||||
* @return 时间(秒) 返回0代表为永久有效
|
||||
*/
|
||||
|
||||
|
||||
public long getExpire(String key) {
|
||||
return redisTemplate.getExpire(key, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 判断key是否存在
|
||||
*
|
||||
* @param key 键
|
||||
* @return true 存在 false不存在
|
||||
*/
|
||||
|
||||
|
||||
public boolean hasKey(String key) {
|
||||
try {
|
||||
return redisTemplate.hasKey(key);
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(),e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 删除缓存
|
||||
*
|
||||
* @param key 可以传一个值 或多个
|
||||
*/
|
||||
public void del(String... key) {
|
||||
if (key != null && key.length > 0) {
|
||||
if (key.length == 1) {
|
||||
redisTemplate.delete(key[0]);
|
||||
} else {
|
||||
redisTemplate.delete(CollectionUtils.arrayToList(key));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 普通缓存获取
|
||||
*
|
||||
* @param key 键
|
||||
* @return 值
|
||||
*/
|
||||
public Object get(String key) {
|
||||
return key == null ? null : redisTemplate.opsForValue().get(key);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 普通缓存放入
|
||||
*
|
||||
* @param key 键
|
||||
* @param value 值
|
||||
* @return true成功 false失败
|
||||
*/
|
||||
public boolean set(String key, Object value) {
|
||||
try {
|
||||
redisTemplate.opsForValue().set(key, value);
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(),e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 普通缓存放入并设置时间
|
||||
*
|
||||
* @param key 键
|
||||
* @param value 值
|
||||
* @param time 时间(秒) time要大于0 如果time小于等于0 将设置无限期
|
||||
* @return true成功 false 失败
|
||||
*/
|
||||
public boolean set(String key, Object value, long time) {
|
||||
try {
|
||||
if (time > 0) {
|
||||
redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
|
||||
} else {
|
||||
set(key, value);
|
||||
}
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(),e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 递增
|
||||
*
|
||||
* @param key 键
|
||||
* @param delta 要增加几(大于0)
|
||||
* @return
|
||||
*/
|
||||
public long incr(String key, long delta) {
|
||||
if (delta < 0) {
|
||||
throw new RuntimeException("递增因子必须大于0");
|
||||
}
|
||||
return redisTemplate.opsForValue().increment(key, delta);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 递减
|
||||
*
|
||||
* @param key 键
|
||||
* @param delta 要减少几(小于0)
|
||||
* @return
|
||||
*/
|
||||
public long decr(String key, long delta) {
|
||||
if (delta < 0) {
|
||||
throw new RuntimeException("递减因子必须大于0");
|
||||
}
|
||||
return redisTemplate.opsForValue().increment(key, -delta);
|
||||
}
|
||||
|
||||
|
||||
// ================================Map=================================
|
||||
|
||||
|
||||
/**
|
||||
* HashGet
|
||||
*
|
||||
* @param key 键 不能为null
|
||||
* @param item 项 不能为null
|
||||
* @return 值
|
||||
*/
|
||||
public Object hget(String key, String item) {
|
||||
return redisTemplate.opsForHash().get(key, item);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取hashKey对应的所有键值
|
||||
*
|
||||
* @param key 键
|
||||
* @return 对应的多个键值
|
||||
*/
|
||||
public Map<Object, Object> hmget(String key) {
|
||||
return redisTemplate.opsForHash().entries(key);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* HashSet
|
||||
*
|
||||
* @param key 键
|
||||
* @param map 对应多个键值
|
||||
* @return true 成功 false 失败
|
||||
*/
|
||||
public boolean hmset(String key, Map<String, Object> map) {
|
||||
try {
|
||||
redisTemplate.opsForHash().putAll(key, map);
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(),e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* HashSet 并设置时间
|
||||
*
|
||||
* @param key 键
|
||||
* @param map 对应多个键值
|
||||
* @param time 时间(秒)
|
||||
* @return true成功 false失败
|
||||
*/
|
||||
public boolean hmset(String key, Map<String, Object> map, long time) {
|
||||
try {
|
||||
redisTemplate.opsForHash().putAll(key, map);
|
||||
if (time > 0) {
|
||||
expire(key, time);
|
||||
}
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(),e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 向一张hash表中放入数据,如果不存在将创建
|
||||
*
|
||||
* @param key 键
|
||||
* @param item 项
|
||||
* @param value 值
|
||||
* @return true 成功 false失败
|
||||
*/
|
||||
public boolean hset(String key, String item, Object value) {
|
||||
try {
|
||||
redisTemplate.opsForHash().put(key, item, value);
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(),e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 向一张hash表中放入数据,如果不存在将创建
|
||||
*
|
||||
* @param key 键
|
||||
* @param item 项
|
||||
* @param value 值
|
||||
* @param time 时间(秒) 注意:如果已存在的hash表有时间,这里将会替换原有的时间
|
||||
* @return true 成功 false失败
|
||||
*/
|
||||
public boolean hset(String key, String item, Object value, long time) {
|
||||
try {
|
||||
redisTemplate.opsForHash().put(key, item, value);
|
||||
if (time > 0) {
|
||||
expire(key, time);
|
||||
}
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(),e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 删除hash表中的值
|
||||
*
|
||||
* @param key 键 不能为null
|
||||
* @param item 项 可以使多个 不能为null
|
||||
*/
|
||||
|
||||
|
||||
public void hdel(String key, Object... item) {
|
||||
redisTemplate.opsForHash().delete(key, item);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 判断hash表中是否有该项的值
|
||||
*
|
||||
* @param key 键 不能为null
|
||||
* @param item 项 不能为null
|
||||
* @return true 存在 false不存在
|
||||
*/
|
||||
public boolean hHasKey(String key, String item) {
|
||||
return redisTemplate.opsForHash().hasKey(key, item);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* hash递增 如果不存在,就会创建一个 并把新增后的值返回
|
||||
*
|
||||
* @param key 键
|
||||
* @param item 项
|
||||
* @param by 要增加几(大于0)
|
||||
* @return
|
||||
*/
|
||||
public double hincr(String key, String item, double by) {
|
||||
return redisTemplate.opsForHash().increment(key, item, by);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* hash递减
|
||||
*
|
||||
* @param key 键
|
||||
* @param item 项
|
||||
* @param by 要减少记(小于0)
|
||||
* @return
|
||||
*/
|
||||
public double hdecr(String key, String item, double by) {
|
||||
return redisTemplate.opsForHash().increment(key, item, -by);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 根据key获取Set中的所有值
|
||||
*
|
||||
* @param key 键
|
||||
* @return
|
||||
*/
|
||||
public Set<Object> sGet(String key) {
|
||||
try {
|
||||
return redisTemplate.opsForSet().members(key);
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(),e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 根据value从一个set中查询,是否存在
|
||||
*
|
||||
* @param key 键
|
||||
* @param value 值
|
||||
* @return true 存在 false不存在
|
||||
*/
|
||||
public boolean sHasKey(String key, Object value) {
|
||||
try {
|
||||
return redisTemplate.opsForSet().isMember(key, value);
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(),e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 将数据放入set缓存
|
||||
*
|
||||
* @param key 键
|
||||
* @param values 值 可以是多个
|
||||
* @return 成功个数
|
||||
*/
|
||||
public long sSet(String key, Object... values) {
|
||||
try {
|
||||
return redisTemplate.opsForSet().add(key, values);
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(),e);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 将set数据放入缓存
|
||||
*
|
||||
* @param key 键
|
||||
* @param time 时间(秒)
|
||||
* @param values 值 可以是多个
|
||||
* @return 成功个数
|
||||
*/
|
||||
public long sSetAndTime(String key, long time, Object... values) {
|
||||
try {
|
||||
Long count = redisTemplate.opsForSet().add(key, values);
|
||||
if (time > 0)
|
||||
expire(key, time);
|
||||
return count;
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(),e);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取set缓存的长度
|
||||
*
|
||||
* @param key 键
|
||||
* @return
|
||||
*/
|
||||
public long sGetSetSize(String key) {
|
||||
try {
|
||||
return redisTemplate.opsForSet().size(key);
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(),e);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 移除值为value的
|
||||
*
|
||||
* @param key 键
|
||||
* @param values 值 可以是多个
|
||||
* @return 移除的个数
|
||||
*/
|
||||
public long setRemove(String key, Object... values) {
|
||||
try {
|
||||
Long count = redisTemplate.opsForSet().remove(key, values);
|
||||
return count;
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(),e);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取list缓存的内容
|
||||
*
|
||||
* @param key 键
|
||||
* @param start 开始
|
||||
* @param end 结束 0 到 -代表所有值
|
||||
* @return
|
||||
*/
|
||||
public List<Object> lGet(String key, long start, long end) {
|
||||
try {
|
||||
return redisTemplate.opsForList().range(key, start, end);
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(),e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取list缓存的长度
|
||||
*
|
||||
* @param key 键
|
||||
* @return
|
||||
*/
|
||||
public long lGetListSize(String key) {
|
||||
try {
|
||||
return redisTemplate.opsForList().size(key);
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(),e);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 通过索引 获取list中的值
|
||||
*
|
||||
* @param key 键
|
||||
* @param index 索引 index>=0时, 0 表头, 第二个元素,依次类推;index<0时,-,表尾,-倒数第二个元素,依次类推
|
||||
* @return
|
||||
*/
|
||||
public Object lGetIndex(String key, long index) {
|
||||
try {
|
||||
return redisTemplate.opsForList().index(key, index);
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(),e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 将list放入缓存
|
||||
*
|
||||
* @param key 键
|
||||
* @param value 值
|
||||
* @return
|
||||
*/
|
||||
public boolean lSet(String key, Object value) {
|
||||
try {
|
||||
redisTemplate.opsForList().rightPush(key, value);
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(),e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 将list放入缓存
|
||||
*
|
||||
* @param key 键
|
||||
* @param value 值
|
||||
* @param time 时间(秒)
|
||||
* @return
|
||||
*/
|
||||
public boolean lSet(String key, Object value, long time) {
|
||||
try {
|
||||
redisTemplate.opsForList().rightPush(key, value);
|
||||
if (time > 0)
|
||||
expire(key, time);
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(),e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 将list放入缓存
|
||||
*
|
||||
* @param key 键
|
||||
* @param value 值
|
||||
* @return
|
||||
*/
|
||||
public boolean lSet(String key, List<Object> value) {
|
||||
try {
|
||||
redisTemplate.opsForList().rightPushAll(key, value);
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(),e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 将list放入缓存
|
||||
*
|
||||
* @param key 键
|
||||
* @param value 值
|
||||
* @param time 时间(秒)
|
||||
* @return
|
||||
*/
|
||||
public boolean lSet(String key, List<Object> value, long time) {
|
||||
try {
|
||||
redisTemplate.opsForList().rightPushAll(key, value);
|
||||
if (time > 0)
|
||||
expire(key, time);
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(),e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 根据索引修改list中的某条数据
|
||||
*
|
||||
* @param key 键
|
||||
* @param index 索引
|
||||
* @param value 值
|
||||
* @return
|
||||
*/
|
||||
public boolean lUpdateIndex(String key, long index, Object value) {
|
||||
try {
|
||||
redisTemplate.opsForList().set(key, index, value);
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(),e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 移除N个值为value
|
||||
*
|
||||
* @param key 键
|
||||
* @param count 移除多少个
|
||||
* @param value 值
|
||||
* @return 移除的个数
|
||||
*/
|
||||
public long lRemove(String key, long count, Object value) {
|
||||
try {
|
||||
Long remove = redisTemplate.opsForList().remove(key, count, value);
|
||||
return remove;
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(),e);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,41 @@
|
||||
package com.java2nb.common.utils;
|
||||
|
||||
import com.java2nb.system.domain.UserToken;
|
||||
import org.apache.commons.beanutils.BeanUtils;
|
||||
import org.apache.shiro.SecurityUtils;
|
||||
import org.apache.shiro.session.Session;
|
||||
import org.apache.shiro.session.mgt.eis.SessionDAO;
|
||||
import org.apache.shiro.subject.Subject;
|
||||
|
||||
import com.java2nb.system.domain.UserDO;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.security.Principal;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
public class ShiroUtils {
|
||||
@Autowired
|
||||
private static SessionDAO sessionDAO;
|
||||
|
||||
public static Subject getSubjct() {
|
||||
return SecurityUtils.getSubject();
|
||||
}
|
||||
public static UserDO getUser() {
|
||||
Object object = getSubjct().getPrincipal();
|
||||
return (UserDO)object;
|
||||
}
|
||||
public static Long getUserId() {
|
||||
return getUser().getUserId();
|
||||
}
|
||||
public static void logout() {
|
||||
getSubjct().logout();
|
||||
}
|
||||
|
||||
public static List<Principal> getPrinciples() {
|
||||
List<Principal> principals = null;
|
||||
Collection<Session> sessions = sessionDAO.getActiveSessions();
|
||||
return principals;
|
||||
}
|
||||
}
|
@ -0,0 +1,82 @@
|
||||
//package com.java2nb.common.utils;
|
||||
//
|
||||
//import org.apache.commons.lang3.Validate;
|
||||
//import org.slf4j.Logger;
|
||||
//import org.slf4j.LoggerFactory;
|
||||
//import org.springframework.beans.factory.DisposableBean;
|
||||
//import org.springframework.context.ApplicationContext;
|
||||
//import org.springframework.context.ApplicationContextAware;
|
||||
//import org.springframework.context.annotation.Lazy;
|
||||
//import org.springframework.stereotype.Service;
|
||||
//
|
||||
///**
|
||||
// * 以静态变量保存Spring ApplicationContext, 可在任何代码任何地方任何时候取出ApplicaitonContext.
|
||||
// *
|
||||
// */
|
||||
//@Service
|
||||
//@Lazy(false)
|
||||
//public class SpringContextHolder implements ApplicationContextAware, DisposableBean {
|
||||
//
|
||||
// private static ApplicationContext applicationContext = null;
|
||||
//
|
||||
// private static Logger logger = LoggerFactory.getLogger(SpringContextHolder.class);
|
||||
//
|
||||
// /**
|
||||
// * 取得存储在静态变量中的ApplicationContext.
|
||||
// */
|
||||
// public static ApplicationContext getApplicationContext() {
|
||||
// assertContextInjected();
|
||||
// return applicationContext;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 从静态变量applicationContext中取得Bean, 自动转型为所赋值对象的类型.
|
||||
// */
|
||||
// @SuppressWarnings("unchecked")
|
||||
// public static <T> T getBean(String name) {
|
||||
// assertContextInjected();
|
||||
// return (T) applicationContext.getBean(name);
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 从静态变量applicationContext中取得Bean, 自动转型为所赋值对象的类型.
|
||||
// */
|
||||
// public static <T> T getBean(Class<T> requiredType) {
|
||||
// assertContextInjected();
|
||||
// return applicationContext.getBean(requiredType);
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 清除SpringContextHolder中的ApplicationContext为Null.
|
||||
// */
|
||||
// public static void clearHolder() {
|
||||
// if (logger.isDebugEnabled()) {
|
||||
// logger.debug("清除SpringContextHolder中的ApplicationContext:" + applicationContext);
|
||||
// }
|
||||
// applicationContext = null;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 实现ApplicationContextAware接口, 注入Context到静态变量中.
|
||||
// */
|
||||
// @Override
|
||||
// public void setApplicationContext(ApplicationContext applicationContext) {
|
||||
// SpringContextHolder.applicationContext = applicationContext;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 实现DisposableBean接口, 在Context关闭时清理静态变量.
|
||||
// */
|
||||
// @Override
|
||||
// public void destroy() throws Exception {
|
||||
// SpringContextHolder.clearHolder();
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 检查ApplicationContext不为空.
|
||||
// */
|
||||
// private static void assertContextInjected() {
|
||||
// Validate.validState(applicationContext != null,
|
||||
// "applicaitonContext属性未注入, 请在applicationContext.xml中定义SpringContextHolder.");
|
||||
// }
|
||||
//}
|
@ -0,0 +1,7 @@
|
||||
package com.java2nb.common.utils;
|
||||
|
||||
/**
|
||||
* @author xiongxy
|
||||
*/
|
||||
public class StringUtils extends org.apache.commons.lang3.StringUtils{
|
||||
}
|
@ -0,0 +1,323 @@
|
||||
/**
|
||||
* Copyright © 2012-2016 <a href="https://github.com/thinkgem/jeesite">JeeSite</a> All rights reserved.
|
||||
*/
|
||||
package com.java2nb.common.utils;
|
||||
|
||||
import org.apache.commons.lang3.time.DateFormatUtils;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 时间计算工具类
|
||||
|
||||
*/
|
||||
public class TimeUtils {
|
||||
|
||||
public static String toTimeString(long time) {
|
||||
TimeUtils t = new TimeUtils(time);
|
||||
int day = t.get(TimeUtils.DAY);
|
||||
int hour = t.get(TimeUtils.HOUR);
|
||||
int minute = t.get(TimeUtils.MINUTE);
|
||||
int second = t.get(TimeUtils.SECOND);
|
||||
StringBuilder sb = new StringBuilder();
|
||||
if (day > 0){
|
||||
sb.append(day).append("天");
|
||||
}
|
||||
if (hour > 0){
|
||||
sb.append(hour).append("时");
|
||||
}
|
||||
if (minute > 0){
|
||||
sb.append(minute).append("分");
|
||||
}
|
||||
if (second > 0){
|
||||
sb.append(second).append("秒");
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 时间字段常量,表示“秒”
|
||||
*/
|
||||
public final static int SECOND = 0;
|
||||
|
||||
/**
|
||||
* 时间字段常量,表示“分”
|
||||
*/
|
||||
public final static int MINUTE = 1;
|
||||
|
||||
/**
|
||||
* 时间字段常量,表示“时”
|
||||
*/
|
||||
public final static int HOUR = 2;
|
||||
|
||||
/**
|
||||
* 时间字段常量,表示“天”
|
||||
*/
|
||||
public final static int DAY = 3;
|
||||
|
||||
/**
|
||||
* 各常量允许的最大值
|
||||
*/
|
||||
private final int[] maxFields = { 59, 59, 23, Integer.MAX_VALUE - 1 };
|
||||
|
||||
/**
|
||||
* 各常量允许的最小值
|
||||
*/
|
||||
private final int[] minFields = { 0, 0, 0, Integer.MIN_VALUE };
|
||||
|
||||
/**
|
||||
* 默认的字符串格式时间分隔符
|
||||
*/
|
||||
private String timeSeparator = ":";
|
||||
|
||||
/**
|
||||
* 时间数据容器
|
||||
*/
|
||||
private int[] fields = new int[4];
|
||||
|
||||
/**
|
||||
* 无参构造,将各字段置为 0
|
||||
*/
|
||||
public TimeUtils() {
|
||||
this(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用时、分构造一个时间
|
||||
* @param hour 小时
|
||||
* @param minute 分钟
|
||||
*/
|
||||
public TimeUtils(int hour, int minute) {
|
||||
this(0, hour, minute, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用时、分、秒构造一个时间
|
||||
* @param hour 小时
|
||||
* @param minute 分钟
|
||||
* @param second 秒
|
||||
*/
|
||||
public TimeUtils(int hour, int minute, int second) {
|
||||
this(0, hour, minute, second);
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用一个字符串构造时间<br/>
|
||||
* Time time = new Time("14:22:23");
|
||||
* @param time 字符串格式的时间,默认采用“:”作为分隔符
|
||||
*/
|
||||
public TimeUtils(String time) {
|
||||
this(time, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用时间毫秒构建时间
|
||||
* @param time
|
||||
*/
|
||||
public TimeUtils(long time){
|
||||
this(new Date(time));
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用日期对象构造时间
|
||||
* @param date
|
||||
*/
|
||||
public TimeUtils(Date date){
|
||||
this(DateFormatUtils.formatUTC(date, "HH:mm:ss"));
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用天、时、分、秒构造时间,进行全字符的构造
|
||||
* @param day 天
|
||||
* @param hour 时
|
||||
* @param minute 分
|
||||
* @param second 秒
|
||||
*/
|
||||
public TimeUtils(int day, int hour, int minute, int second) {
|
||||
initialize(day, hour, minute, second);
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用一个字符串构造时间,指定分隔符<br/>
|
||||
* Time time = new Time("14-22-23", "-");
|
||||
* @param time 字符串格式的时间
|
||||
*/
|
||||
public TimeUtils(String time, String timeSeparator) {
|
||||
if(timeSeparator != null) {
|
||||
setTimeSeparator(timeSeparator);
|
||||
}
|
||||
parseTime(time);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置时间字段的值
|
||||
* @param field 时间字段常量
|
||||
* @param value 时间字段的值
|
||||
*/
|
||||
public void set(int field, int value) {
|
||||
if(value < minFields[field]) {
|
||||
throw new IllegalArgumentException(value + ", time value must be positive.");
|
||||
}
|
||||
fields[field] = value % (maxFields[field] + 1);
|
||||
// 进行进位计算
|
||||
int carry = value / (maxFields[field] + 1);
|
||||
if(carry > 0) {
|
||||
int upFieldValue = get(field + 1);
|
||||
set(field + 1, upFieldValue + carry);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得时间字段的值
|
||||
* @param field 时间字段常量
|
||||
* @return 该时间字段的值
|
||||
*/
|
||||
public int get(int field) {
|
||||
if(field < 0 || field > fields.length - 1) {
|
||||
throw new IllegalArgumentException(field + ", field value is error.");
|
||||
}
|
||||
return fields[field];
|
||||
}
|
||||
|
||||
/**
|
||||
* 将时间进行“加”运算,即加上一个时间
|
||||
* @param time 需要加的时间
|
||||
* @return 运算后的时间
|
||||
*/
|
||||
public TimeUtils addTime(TimeUtils time) {
|
||||
TimeUtils result = new TimeUtils();
|
||||
int up = 0; // 进位标志
|
||||
for (int i = 0; i < fields.length; i++) {
|
||||
int sum = fields[i] + time.fields[i] + up;
|
||||
up = sum / (maxFields[i] + 1);
|
||||
result.fields[i] = sum % (maxFields[i] + 1);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将时间进行“减”运算,即减去一个时间
|
||||
* @param time 需要减的时间
|
||||
* @return 运算后的时间
|
||||
*/
|
||||
public TimeUtils subtractTime(TimeUtils time) {
|
||||
TimeUtils result = new TimeUtils();
|
||||
int down = 0; // 退位标志
|
||||
for (int i = 0, k = fields.length - 1; i < k; i++) {
|
||||
int difference = fields[i] + down;
|
||||
if (difference >= time.fields[i]) {
|
||||
difference -= time.fields[i];
|
||||
down = 0;
|
||||
} else {
|
||||
difference += maxFields[i] + 1 - time.fields[i];
|
||||
down = -1;
|
||||
}
|
||||
result.fields[i] = difference;
|
||||
}
|
||||
result.fields[DAY] = fields[DAY] - time.fields[DAY] + down;
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得时间字段的分隔符
|
||||
* @return
|
||||
*/
|
||||
public String getTimeSeparator() {
|
||||
return timeSeparator;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置时间字段的分隔符(用于字符串格式的时间)
|
||||
* @param timeSeparator 分隔符字符串
|
||||
*/
|
||||
public void setTimeSeparator(String timeSeparator) {
|
||||
this.timeSeparator = timeSeparator;
|
||||
}
|
||||
|
||||
private void initialize(int day, int hour, int minute, int second) {
|
||||
set(DAY, day);
|
||||
set(HOUR, hour);
|
||||
set(MINUTE, minute);
|
||||
set(SECOND, second);
|
||||
}
|
||||
|
||||
private void parseTime(String time) {
|
||||
if(time == null) {
|
||||
initialize(0, 0, 0, 0);
|
||||
return;
|
||||
}
|
||||
String t = time;
|
||||
int field = DAY;
|
||||
set(field--, 0);
|
||||
int p = -1;
|
||||
while((p = t.indexOf(timeSeparator)) > -1) {
|
||||
parseTimeField(time, t.substring(0, p), field--);
|
||||
t = t.substring(p + timeSeparator.length());
|
||||
}
|
||||
parseTimeField(time, t, field--);
|
||||
}
|
||||
|
||||
private void parseTimeField(String time, String t, int field) {
|
||||
if(field < SECOND || t.length() < 1) {
|
||||
parseTimeException(time);
|
||||
}
|
||||
char[] chs = t.toCharArray();
|
||||
int n = 0;
|
||||
for(int i = 0; i < chs.length; i++) {
|
||||
if(chs[i] <= ' ') {
|
||||
continue;
|
||||
}
|
||||
if(chs[i] >= '0' && chs[i] <= '9') {
|
||||
n = n * 10 + chs[i] - '0';
|
||||
continue;
|
||||
}
|
||||
parseTimeException(time);
|
||||
}
|
||||
set(field, n);
|
||||
}
|
||||
|
||||
private void parseTimeException(String time) {
|
||||
throw new IllegalArgumentException(time + ", time format error, HH"
|
||||
+ this.timeSeparator + "mm" + this.timeSeparator + "ss");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder(16);
|
||||
sb.append(fields[DAY]).append(',').append(' ');
|
||||
buildString(sb, HOUR).append(timeSeparator);
|
||||
buildString(sb, MINUTE).append(timeSeparator);
|
||||
buildString(sb, SECOND);
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private StringBuilder buildString(StringBuilder sb, int field) {
|
||||
if(fields[field] < 10) {
|
||||
sb.append('0');
|
||||
}
|
||||
return sb.append(fields[field]);
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
final int PRIME = 31;
|
||||
int result = 1;
|
||||
result = PRIME * result + Arrays.hashCode(fields);
|
||||
return result;
|
||||
}
|
||||
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
final TimeUtils other = (TimeUtils) obj;
|
||||
if (!Arrays.equals(fields, other.fields)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
package com.java2nb.common.utils;
|
||||
|
||||
public class UploadUtils {
|
||||
|
||||
}
|
@ -0,0 +1,61 @@
|
||||
package com.java2nb.common.xss;
|
||||
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletRequestWrapper;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public class XssAndSqlHttpServletRequestWrapper extends HttpServletRequestWrapper {
|
||||
private HttpServletRequest request;
|
||||
|
||||
/**
|
||||
* 假如有有html 代码是自己传来的 需要设定对应的name 不过滤
|
||||
*/
|
||||
private static final List<String> noFilterNames = Arrays.asList("attach","push_ip","content");
|
||||
|
||||
public XssAndSqlHttpServletRequestWrapper(HttpServletRequest request) {
|
||||
super(request);
|
||||
this.request = request;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getParameter(String name) {
|
||||
String value = request.getParameter(name);
|
||||
if (!StringUtils.isEmpty(value) && !noFilterNames.contains(name)) {
|
||||
value = htmlEncodeByRegExp(value);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getParameterValues(String name) {
|
||||
String[] parameterValues = super.getParameterValues(name);
|
||||
if (parameterValues == null || noFilterNames.contains(name)) {
|
||||
return parameterValues;
|
||||
}
|
||||
for (int i = 0; i < parameterValues.length; i++) {
|
||||
String value = parameterValues[i];
|
||||
if (!StringUtils.isEmpty(value)){
|
||||
parameterValues[i] = htmlEncodeByRegExp(value);
|
||||
}
|
||||
}
|
||||
return parameterValues;
|
||||
}
|
||||
|
||||
|
||||
private String htmlEncodeByRegExp(String str) {
|
||||
String temp = "" ;
|
||||
temp = str
|
||||
//.replaceAll("&", "&")
|
||||
.replaceAll("<", "<")
|
||||
.replaceAll(">", ">");
|
||||
//.replaceAll("\\s", " ")
|
||||
//.replaceAll("\'", "'")
|
||||
//.replaceAll("\"", """);
|
||||
return temp;
|
||||
}
|
||||
}
|
@ -0,0 +1,45 @@
|
||||
package com.java2nb.common.xss;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.servlet.*;
|
||||
import javax.servlet.annotation.WebFilter;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
@WebFilter(filterName = "xssFilter", urlPatterns = "/*", asyncSupported = true)
|
||||
@Component
|
||||
public class XssFilter implements Filter {
|
||||
|
||||
private static final List<String> NO_XSS_PATH = Arrays.asList("/common/generator/batchCode","/common/generator/batchDownload");
|
||||
|
||||
@Override
|
||||
public void destroy() {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
|
||||
throws IOException, ServletException {
|
||||
// TODO Auto-generated method stub
|
||||
HttpServletRequest req = (HttpServletRequest) request;
|
||||
String reqURI = req.getRequestURI();
|
||||
if(NO_XSS_PATH.contains(reqURI)){
|
||||
chain.doFilter(request,response);
|
||||
}else {
|
||||
XssAndSqlHttpServletRequestWrapper xssRequestWrapper = new XssAndSqlHttpServletRequestWrapper(req);
|
||||
chain.doFilter(xssRequestWrapper, response);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(FilterConfig arg0) {
|
||||
// TODO Auto-generated method stub
|
||||
}
|
||||
|
||||
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user