Compare commits

..

340 Commits

Author SHA1 Message Date
e4e511aed8 feat: 移出书架 2025-03-20 22:03:10 +08:00
ec9674f2aa feat: 移出书架 2025-03-20 21:51:51 +08:00
06074faf9a feat(pc): 移除书架 2025-03-20 17:30:18 +08:00
73654dda2b ci: GitHub Actions 设置上传 token 2025-03-20 14:58:26 +08:00
c0634a335e ci: GitHub Actions 上传ZIP包 2025-03-20 14:48:42 +08:00
5dcc2b0b46 v5.0.1 发布 2025-03-20 13:27:46 +08:00
6cdb68899b ci: GitHub Actions 指定中央仓库下载 maven 依赖 2025-03-20 13:26:10 +08:00
d955b11165 ci: 创建 GitHub Actions 工作流自动发布版本 2025-03-20 13:19:51 +08:00
1081b8e10a chore: 修改日志 2025-03-19 10:12:22 +08:00
4b1507b2d1 perf: 连接池统一创建 2025-03-19 10:04:54 +08:00
82658f3b5f perf: 兼容其它数据源 2025-03-19 08:03:45 +08:00
acf9c76757 perf: 提前创建数据库连接池
Spring Boot 新版本默认会在第一次请求数据库时创建连接池
2025-03-19 07:50:50 +08:00
4b00ea68a9 perf: 提高第一次登录速度 2025-03-19 00:09:10 +08:00
d9f9fd8bd2 build: 优化打包配置 2025-03-18 21:39:01 +08:00
c1583f83bb fix: 网站icon显示 2025-03-18 21:19:18 +08:00
eecbb2dd9c fix: 通用异常处理 2025-03-18 21:18:51 +08:00
0afc7b1bbf fix: 通用异常处理 2025-03-18 21:03:21 +08:00
f5a9a7423f fix: 生产环境web静态资源目录配置 2025-03-18 20:22:54 +08:00
3858cd4e49 build: 修改版本号 2025-03-18 19:10:10 +08:00
c4a6acf2b3 fix: 网站ico图标显示 2025-03-18 14:24:19 +08:00
8781cc54d4 chore: 模版/配置/SQL/文档更新 2025-03-17 18:47:05 +08:00
84a06a7037 fix: 通用异常处理 2025-03-17 10:18:18 +08:00
a046899dd6 fix:通用异常处理 2025-03-17 10:12:53 +08:00
14a1ff69bf build: 升级配置 2025-03-16 14:27:47 +08:00
467290b908 feat: 集成 Spring AI 实现基础的 AI 写作功能 2025-03-16 13:03:37 +08:00
d77ce5b446 build: Spring Boot 升级到 3.4.0 2025-03-15 23:35:47 +08:00
8d35aa80ab build: 修改打包配置 2025-03-15 19:51:43 +08:00
11978c2c9e build: v5.0.0发布 2025-03-15 19:29:37 +08:00
81c1514a21 build: 构建生产环境配置 2025-03-15 17:25:10 +08:00
af1237e2d7 build: Java版本升级到21 2025-03-15 15:13:36 +08:00
9033ca6331 build: Java版本升级到21 & SpringBoot版本升级到2.7.18 2025-03-15 15:06:59 +08:00
fd200772c9 build: 修改版本号 2025-03-15 09:15:26 +08:00
73502a279b feat: 支持非utf-8编码的网站采集 2025-03-14 20:39:57 +08:00
85b64bbc10 perf: 爬虫采集流程优化 2025-03-14 19:27:46 +08:00
6d0ab33757 perf: 爬虫分类规则优化 2025-03-14 19:03:30 +08:00
74d7ea7000 feat: 代理IP增加用户名密码设置 2025-03-14 18:36:14 +08:00
cdfe481d60 Update README.md 2025-03-14 17:48:35 +08:00
0ff87614ea fix: 修复失效的爬虫规则 2025-02-28 22:02:11 +08:00
2cb9f85081 优化提示 2025-01-18 00:46:39 +08:00
d8e559ab50 修复规则 2024-11-02 21:19:27 +08:00
3849a9b86f build: 修改版本号 2024-11-02 18:32:01 +08:00
71b9d1d916 模版更新 2024-11-02 18:31:47 +08:00
4b9dbe969c 修复i笔趣阁爬虫规则 2024-11-02 18:26:40 +08:00
2136f7490f 增加爬虫规则 2024-11-02 13:24:28 +08:00
3586ffbc0a 优化 2024-09-21 11:14:07 +08:00
f78a2a36cf 优化 2024-09-21 11:10:44 +08:00
a8219253e9 优化 2024-09-21 10:15:45 +08:00
5c35f7af0a 更换默认logo图片 2024-09-16 21:08:32 +08:00
d55e1a3e22 revert: sql格式化还原 2024-08-06 22:42:43 +08:00
21a6a49ce9 fix: 作家稿费统计 2024-08-06 21:14:22 +08:00
3735023cef perf(novel-front): UI优化 2024-07-20 21:48:29 +08:00
89992dc781 perf(novel-crawl): 增加小说内容过滤 2024-06-01 09:56:07 +08:00
976db9420e build: 修改版本号 2024-05-31 20:59:34 +08:00
e33db86081 Update README.md 2024-05-28 12:34:00 +08:00
48a70c2aca build: 修改版本号 2024-05-28 09:45:23 +08:00
ea5c0e8bd1 模版更新 2024-05-28 09:42:27 +08:00
b0c249cdca fix: 默认logo图片失效 2024-05-26 22:50:57 +08:00
730fcb4c76 fix: 默认logo图片失效 2024-05-26 22:46:46 +08:00
b976a00389 perf: UI优化 2024-05-26 22:31:26 +08:00
6d9b563583 fix: 文件上传大小限制 2024-05-25 22:05:03 +08:00
bfb7d6cc5c fix: i笔趣阁域名更换 2024-05-12 17:26:59 +08:00
9d4dc409c6 fix: URI编码 2024-03-03 11:10:46 +08:00
34d211afbf fix: 只推荐有内容的小说 2024-02-21 19:27:48 +08:00
2d218076c4 chore: 修改打包默认模版 2024-02-18 10:28:29 +08:00
674e4df84c chore: 模版更新 2024-02-07 14:59:31 +08:00
331f56d112 fix: 移动端首页在数据量小于10时报错 2024-02-07 14:58:36 +08:00
f494aae2c7 chore: 模版更新 2024-02-07 14:23:32 +08:00
2fc533f8ae fix(novel-crawl): 登录页样式问题 2024-02-05 21:12:41 +08:00
82758271e3 feat: 增加语音播放小说内容 2024-02-05 12:05:26 +08:00
4c82c2d720 perf: 优化支付宝支付流程 2024-02-04 12:25:26 +08:00
4665b5c4b9 fix: bug 2024-02-03 16:14:36 +08:00
7bbabb3492 fix: 修复充值页面的未登录跳转路径 2024-02-03 14:03:23 +08:00
d6093d8182 fix(novel-admin): 友情链接URL格式校验 2023-12-29 18:54:53 +08:00
f77792aa3c perf: 限制昵称长度并优化显示 2023-12-29 00:34:04 +08:00
c62da9bb3a fix: nickName、userPhoto 更新校验 2023-12-29 00:11:01 +08:00
8a63cff0b5 Update README.md 2023-10-31 08:24:54 +08:00
07bed12fa5 fix(mobile): 充值页标题 2023-10-30 14:17:03 +08:00
0d6e0ffb06 perf(mobile): 内容页优化
去掉小说内容前面的多余空格
2023-10-30 14:07:31 +08:00
e7005004bb perf(mobile): 登录/注册页优化 2023-10-30 14:01:39 +08:00
ff68cdd829 perf(mobile): 首页优化 2023-10-30 14:01:24 +08:00
b61dc4d0d5 build(Docker): 管理 Dockerfile 文件 2023-10-22 19:20:52 +08:00
98f1f804c3 chore(sql): 自动创建 novel_plus 数据库 2023-10-22 19:07:32 +08:00
5978d6cbcc build: 修改版本号 2023-10-21 21:21:54 +08:00
ef290bed9c fix: 书架列表时间格式化 2023-10-21 21:02:00 +08:00
5543e5aa57 perf: 设置网站 ico 图标 2023-10-15 20:30:11 +08:00
0332802fe5 feat(crawl): 账号退出 2023-10-15 19:13:07 +08:00
a55f456b3d perf: 更新爬虫管理系统主题颜色 2023-10-15 17:54:44 +08:00
f6d66e69fb Update README.md 2023-10-14 18:19:00 +08:00
96960789e1 fix(alipay): 修改默认支付宝支付成功跳转地址 2023-10-14 17:50:14 +08:00
1998dcd460 fix(alipay): 修复支付宝支付页面报错
沙箱环境自动升级到新版后,没有在代码中更换新版本的应用/网关/账号信息,也没有从左边栏沙箱工具中下载最新版本的沙箱支付宝APP安装使用。
2023-10-14 17:42:42 +08:00
a33d8f68a2 删除垃圾文件 2023-10-14 13:42:37 +08:00
30959da038 删除垃圾文件 2023-10-14 13:39:11 +08:00
5406783344 删除垃圾文件 2023-10-14 12:54:33 +08:00
d84345918b Update README.md 2023-10-14 10:32:46 +08:00
a5394cb426 Update README.md 2023-10-14 10:20:16 +08:00
2275b85752 chore: 模版更新 2023-10-14 10:16:41 +08:00
2062123edd perf(mobile): 去除手机网站底部空白间隙 2023-10-14 10:06:16 +08:00
255b3f8c4b feat(templates): 新增绿色主题模版,并设置为默认模版
和文档站点 docs.xxyopen.com 风格保持一致
2023-10-13 21:21:21 +08:00
00179359bd chore: 更新 Dockerfile 文件 2023-10-12 16:33:57 +08:00
6019ce11c7 build: 修改版本号 2023-10-12 10:02:50 +08:00
3e1c1f02e9 chore: 模版更新 2023-10-12 09:59:08 +08:00
98a5157623 feat: 支付宝手机网站支付 2023-10-12 09:49:03 +08:00
05d65c19a7 perf: 手机端页面优化 2023-10-12 09:42:28 +08:00
4c9f39ab19 feat: 手机端阅读历史页面适配 2023-10-12 09:28:29 +08:00
8bc05a1606 Merge remote-tracking branch 'Gitee/4.1.x' into develop_xxy 2023-10-12 09:03:32 +08:00
f9aad61b10 chore: 模版更新 2023-10-10 19:31:26 +08:00
8311681b23 perf(mobile): 加入书架按钮样式优化 2023-10-10 19:29:26 +08:00
4497dd1974 chore: 模版更新 2023-09-29 19:25:06 +08:00
44bf0cd693 fix: 修复作家专区小说封面更新问题 2023-09-29 19:23:12 +08:00
f333a2c084 perf: 优化小说推荐管理 2023-09-29 19:18:42 +08:00
bff5b0827e perf: 爬虫配置自定义登录页面 2023-06-09 19:25:42 +08:00
14f9205d76 docs: 修正小说内容保存配置的注释 2023-06-05 13:17:43 +08:00
cb2ff39b1e build: 移除 Elasticsearch 依赖 2023-05-28 21:51:07 +08:00
3eaa526093 fix: 修复CVE漏洞 2023-05-28 21:44:44 +08:00
04d7b45334 feat: 移除 FastDFS 模块 2023-05-28 19:14:21 +08:00
24c80e381c fix: 修改依赖组件漏洞 2023-05-28 18:43:05 +08:00
9fe51eab74 fix: 页面请求异常处理 2023-05-17 23:43:27 +08:00
e1c800d78f feat: 手机端用户中心优化 2023-05-14 07:05:36 +08:00
eb982b51f7 feat: 手机端充值页面适配 2023-05-14 06:58:42 +08:00
18f5fbf508 feat: 手机端我的书架页面适配 2023-05-13 23:40:54 +08:00
c63b4d617e feat: 手机端用户中心页面适配 2023-05-13 23:02:53 +08:00
4fb0d478f3 feat: 手机端注册页面适配 2023-05-13 19:57:19 +08:00
dabfb9d1e8 feat: 手机端登录页面适配 2023-05-13 15:15:42 +08:00
dce8a21c0d feat: 首页是否登录识别 2023-05-13 13:11:10 +08:00
d9ad02e3f5 fix(sql): 网站信息修改提示未授权
超级管理员增加网站信息修改权限
2023-05-08 15:52:02 +08:00
b02a2b3b2c build: 4.1.0 发布 2023-04-18 12:00:50 +08:00
f28c8a9c16 revert: 恢复误删文件
作家专区稿费收入报错
2023-04-18 11:34:26 +08:00
e44978617f feat: 后台会员反馈管理 2023-04-18 11:23:45 +08:00
aa2929a3cd feat: 后台小说推荐管理 2023-04-18 10:58:33 +08:00
281561c85b fix: 会员注册验证码 2023-04-18 09:17:30 +08:00
cab350dbb2 fix: 刷新首页新闻缓存 2023-04-18 08:58:30 +08:00
9ed465784a fix: 网站信息管理的权限问题 2023-04-17 10:55:20 +08:00
e2cfa5a788 Update README.md 2023-04-16 08:32:19 +08:00
6fb1e5cc99 chore: 模版更新 2023-04-15 08:37:17 +08:00
749fd1aeaa docs: 项目演示 2023-04-15 08:08:57 +08:00
8c3fb7f1ca build: 4.0.0 发布 2023-04-15 06:50:55 +08:00
c71eadef82 perf: 后台订单管理 2023-04-14 23:22:23 +08:00
3ffa75dc10 perf: 后台评论管理 2023-04-14 23:16:55 +08:00
8ddc6cc434 feat: 后台评论管理 2023-04-14 22:34:36 +08:00
5854536c70 fix: 代码生成数据表查询 2023-04-14 22:06:39 +08:00
a7d825cc54 fix: 后台模块查询过滤相同的行 2023-04-14 21:33:31 +08:00
687eb61846 feat: 后台小说删除 2023-04-14 21:09:37 +08:00
9f23f817b1 feat: 后台小说管理 2023-04-14 18:07:05 +08:00
0c59adf23b feat: 后台订单管理 2023-04-14 17:29:41 +08:00
57eca58b24 feat: 后台会员管理 2023-04-14 16:58:04 +08:00
c76df15a7f feat: 后台友情链接管理 2023-04-14 16:32:05 +08:00
3b0edd8e1f fix: sql 2023-04-14 14:58:38 +08:00
2c3b735d49 feat: 后台网站信息管理 2023-04-14 14:56:11 +08:00
b45b83fdb0 Update README.md 2023-04-14 10:51:42 +08:00
29d074ec18 refactor: 移除 Ehcache,默认缓存设置为 Redis 2023-04-14 10:40:54 +08:00
282bc7b707 refactor: 移除 RabbitMQ 和 Elasticsearch 相关功能 2023-04-14 10:10:09 +08:00
68b3458c30 Add favicon.ico 2023-01-11 19:19:05 +08:00
2f5002f673 Update README.md 2022-08-29 08:12:32 +08:00
d293d7bf91 Merge branch 'develop_xxy' of https://gitee.com/novel_dev_team/novel-plus into develop_xxy 2022-07-31 08:12:41 +08:00
a9080310a4 update template & sql 2022-07-31 08:04:43 +08:00
xxy
1f571f9b64 Update README.md 2022-07-26 17:22:25 +08:00
xxy
7be529fe4a Update README.md 2022-07-26 17:11:15 +08:00
xxy
2f62641b63 Update README.md 2022-07-24 14:53:27 +08:00
xxy
d962620814 Update README.md 2022-07-24 14:51:09 +08:00
xxy
7640d153ac Update README.md 2022-07-21 21:28:26 +08:00
xxy
3d9f52ffee Update README.md 2022-07-20 06:28:17 +08:00
xxy
0112af202b Update README.md 2022-07-20 06:24:29 +08:00
xxy
e3010ea81e Update README.md 2022-07-20 06:21:54 +08:00
xxy
05608d0316 Update README.md 2022-07-20 06:18:52 +08:00
xxy
4f6ec5aa0f Update README.md 2022-07-20 06:17:48 +08:00
xxy
01984f7137 Update README.md 2022-07-18 18:20:06 +08:00
xxy
617f6f50b0 Update README.md 2022-07-18 13:14:27 +08:00
xxy
e0686f079c Update README.md 2022-07-16 07:08:50 +08:00
xxy
5fb1717770 Update README.md 2022-07-15 22:49:11 +08:00
xxy
4bf495b6c0 Update README.md 2022-07-15 22:47:40 +08:00
028c200764 fix: 新笔趣阁规则移动到全量sql文件 2022-07-15 22:36:48 +08:00
xxy
472440ef7c Update README.md 2022-07-15 19:26:12 +08:00
xxy
5278b5fc39 Update README.md 2022-07-15 19:24:04 +08:00
xxy
9a0a79957b Update README.md 2022-07-15 19:19:49 +08:00
xxy
d93bf3dd4e Update README.md 2022-07-15 19:15:42 +08:00
xxy
09a4f39172 Update README.md 2022-07-15 19:15:11 +08:00
xxy
3abe7e22c9 Update README.md 2022-07-15 19:14:05 +08:00
xxy
5e1135268a Update README.md 2022-07-15 19:12:58 +08:00
xxy
54aeef7c80 Update README.md 2022-07-15 07:18:04 +08:00
xxy
027fbffb7f Update README.md 2022-07-15 06:20:04 +08:00
xxy
5d70e44021 Update README.md 2022-07-15 00:49:35 +08:00
607deaa82f build: v3.6.2 发布 2022-07-15 00:44:10 +08:00
b997367f1a Merge github.com:201206030/novel-plus into develop_xxy 2022-07-15 00:32:30 +08:00
3d3cbc22b6 feat: 增加 HTTP 代理配置,助力爬虫采集 2022-07-14 23:41:47 +08:00
ba272bd89a feat: 增加 HTTP 代理配置,助力爬虫采集 2022-07-14 22:14:11 +08:00
xxy
7d1b024c4d Update README.md 2022-07-14 17:48:10 +08:00
xxy
e732c0fdee Update README.md 2022-07-14 17:47:29 +08:00
xxy
78de1de846 Update README.md 2022-07-14 17:45:36 +08:00
0b728b9fe5 docs: 修改 sql 文件说明 2022-07-14 14:19:05 +08:00
ec3428c358 docs: 增加 sql 说明 2022-07-14 14:09:43 +08:00
xxy
3c322a9d0e Update README.md 2022-07-14 13:44:54 +08:00
xxy
cdceb3818d Update README.md 2022-07-14 13:40:23 +08:00
6fc2df9b5a docs: 更新源码安装教程 2022-07-14 11:34:25 +08:00
c45b81fbbf build: 优化打包 2022-07-14 09:49:36 +08:00
40a999f353 perf: 模版更新 2022-07-14 09:48:22 +08:00
547bf00f46 docs: update README.md 2022-05-22 21:43:47 +08:00
xxy
d6849bc5a2 update README.md. 2022-05-17 23:00:29 +00:00
xxy
dc654086f3 update README.md. 2022-05-17 03:22:26 +00:00
xxy
303cc2051f update README.md 2022-05-17 03:19:22 +00:00
fe90345f0b fix: 首页小说推荐数据渲染
顶部推荐栏重复渲染同一本小说
2022-05-01 10:29:09 +08:00
7ac4b62840 update 2022-04-27 19:48:47 +08:00
029cce959b update 2022-04-27 19:41:23 +08:00
7395cf63e5 add: 启动日志 2022-04-26 09:15:24 +08:00
906e7762c9 Merge github.com:201206030/novel-plus into develop_xxy 2022-01-17 21:03:39 +08:00
465e03a17b perf: 缓存预编译的Pattern对象 2022-01-17 20:58:57 +08:00
2a69a28a0c perf: 预加载IdWorker 2022-01-08 11:59:28 +08:00
c1eb7b8954 docs: 增加说明 2022-01-07 18:02:46 +08:00
16e381f384 chore(sh): 修改JVM启动参数
兼容低配置机器
2022-01-07 17:24:20 +08:00
094ac95428 build(pom): 打包时复制common模块配置文件到外部 2021-12-28 14:40:16 +08:00
96662fcb17 feat(crawl): 新增编辑规则和测试规则
合并mstaer分支的pull request #71
2021-12-24 17:38:23 +08:00
fecf03b3f5 fix: 升级mybatis版本,增加Optional支持 2021-12-24 11:35:59 +08:00
e7f702ece0 docs: 微信群说明 2021-12-23 10:27:05 +08:00
b2c67c4f15 build: 修改打包配置 2021-12-17 19:53:21 +08:00
6a385877ac Merge pull request #69 from a100488/feature/saw_fenbao
feat(打包改为分包): 打包改为分包
2021-12-17 16:45:13 +08:00
7cde6ebf61 feat(打包改为分包): 打包改为分包 2021-12-17 16:33:45 +08:00
78969f9fd1 fix: 修复单本小说采集即使没有采集到内容仍然标记状态为采集成功的问题 2021-12-17 10:20:59 +08:00
b2eb6686e9 build: 更新xxyopen依赖版本 2021-12-12 20:44:09 +08:00
c537f6fb20 docs: maven仓库配置说明 2021-12-11 20:56:11 +08:00
16e4c98a45 refactor: 引入xxy-common相关依赖 2021-12-11 18:30:22 +08:00
776083076c update 2021-11-11 14:28:05 +08:00
2bf945fe0e 样式调整 2021-11-08 19:55:03 +08:00
ede7aca66d 作家作品列表分页修复 2021-09-27 22:35:48 +08:00
396452b46e 3.6.1发布 2021-09-13 22:24:08 +08:00
fc2ea40c6a 实现小说内容多种存储方式(txt、db..)并存 2021-09-13 22:21:50 +08:00
bfe4d938fd 去除重复依赖 2021-09-11 22:07:14 +08:00
7f4728191a 修改配置项命名 2021-09-04 16:27:02 +08:00
80b393fdda v3.6.0发布 2021-08-17 21:14:15 +08:00
e7897c988a 更新文档 2021-08-17 20:00:53 +08:00
750c8dee02 增加小说内容TXT文本存储方案(一行配置切换) 2021-08-17 19:55:24 +08:00
cbfd0b049f 爬虫部分代码重构,准备适配TXT文本存储方案 2021-08-17 11:08:51 +08:00
7f0331e095 解决爬虫运行时的UnrecognizedPropertyException 2021-08-16 15:58:32 +08:00
3520200a87 部分代码重构 2021-08-16 15:42:56 +08:00
4939bcf418 模版更新 2021-08-09 19:46:32 +08:00
1cffbae495 增加新闻阅读数 2021-07-26 19:06:57 +08:00
b99b6ae4f2 新闻详情时间显示 2021-07-24 17:52:25 +08:00
2e2a58c84b Merge pull request #41 from 201206030/dependabot/maven/novel-admin/org.apache.shiro-shiro-spring-1.7.0
Bump shiro-spring from 1.3.2 to 1.7.0 in /novel-admin
2021-07-24 16:54:19 +08:00
4fe36a8f4f 部分爬虫代码优化 2021-07-24 15:51:54 +08:00
b5df86d5c7 perf(index.html): orange模版更新 2021-07-03 12:00:17 +08:00
9b3ba1d8c1 perf(index): 首页优化 2021-07-03 11:51:47 +08:00
c4db754d23 docs(readme): 更新官网地址 2021-06-10 09:42:07 +08:00
8d3ce53dba build(pom): v3.5.4发布 2021-06-01 23:14:35 +08:00
d32d9d8410 perf(html): 模版更新 2021-06-01 23:13:18 +08:00
05ae012e05 fix(yml): Public Key Retrieval is not allowed 2021-06-01 23:03:15 +08:00
b60a0c9b40 perf(监控): 设置druid监控信息登陆后查看 2021-06-01 22:49:23 +08:00
3efaf8ce5f perf(评论): 优化评论显示 2021-06-01 22:01:05 +08:00
ebc4210774 fix(章节更新): xss 2021-06-01 21:44:18 +08:00
655ec90906 fix(data submit): Xss攻击 2021-06-01 20:58:06 +08:00
f28dd867ef v3.5.3发布 2021-05-28 20:32:08 +08:00
8e6842a495 模版更新 2021-05-28 20:08:45 +08:00
928cb2417f 小说详情页优化 2021-05-28 20:04:52 +08:00
625694ba1e Merge branch 'release_3.5.3' into develop_xxy 2021-05-28 11:54:24 +08:00
d6c0337c09 首页SEO优化 2021-05-28 11:51:11 +08:00
689efc0807 style(novel-common/bean): ResultBean更新
代码格式化,去除多余分号
2021-05-16 10:54:25 +08:00
4540c3781e 模版更新 2021-05-16 09:49:35 +08:00
9d2c453bb0 图片上传流程优化 2021-05-16 09:47:23 +08:00
xxy
9de47ce697 update README.md. 2021-04-25 07:39:56 +08:00
c79974ff77 3.5.2发布 2021-04-24 10:46:59 +08:00
fb0098aef8 作家后台新增作品封片图片修改功能 2021-04-24 10:38:55 +08:00
e83494cb17 Bump shiro-spring from 1.3.2 to 1.7.0 in /novel-admin
Bumps shiro-spring from 1.3.2 to 1.7.0.

Signed-off-by: dependabot[bot] <support@github.com>
2021-04-22 17:07:42 +00:00
419d7a971b 优化首页显示(修改周推小说数量) 2021-02-11 18:03:27 +08:00
83eda2a44d 模版更新 2021-02-11 12:25:04 +08:00
3182029bdd 文件压缩 2021-02-11 10:26:48 +08:00
19d4a9960d 使用图片懒加载优化首页加载速度 2021-02-11 09:36:03 +08:00
2603150b33 作家专区的跳转方式改为新标签页跳转 2021-02-11 08:31:27 +08:00
f5e440390b 修改404页面自动跳转首页的时间 2021-02-11 08:27:11 +08:00
91e525ec8e v3.5.1发布 2021-02-05 00:39:25 +08:00
83afb9e6e2 新增内置爬虫源i笔趣阁 2021-02-05 00:17:19 +08:00
19d4c6b778 修复部分分页接口的查询bug 2021-02-04 23:59:26 +08:00
d22200b8c7 文档update 2021-01-28 09:00:36 +08:00
43fe1150fd 文档update 2021-01-28 08:58:20 +08:00
65b65f874f 文档update 2021-01-28 08:46:56 +08:00
3b6bc859a5 文档update 2021-01-28 08:35:08 +08:00
cfc55a6c92 update 2021-01-28 08:33:05 +08:00
0a80c5662d update 2021-01-28 08:28:03 +08:00
02fd0d7e25 模版更新 2021-01-25 18:10:47 +08:00
521142a792 v3.5.1发布 2021-01-25 16:56:41 +08:00
c567e37423 v3.5.1发布 2021-01-25 14:56:05 +08:00
b5e0814eb4 小说内容页性能优化 2021-01-25 14:14:54 +08:00
ca6c2aec96 update 2021-01-24 14:07:14 +08:00
34859c839b update 2021-01-22 10:18:25 +08:00
039f9d9cf8 update 2021-01-21 21:03:08 +08:00
224829dd1f v3.5.0发布 2021-01-19 19:39:33 +08:00
1a5122209a 个人中心新增头像设置 2021-01-19 19:34:14 +08:00
48aff7cf37 个人中心新增头像设置 2021-01-19 19:32:32 +08:00
e673f9be9d 新增启动banner 2021-01-19 19:00:54 +08:00
20469bd669 增加生产环境配置 2021-01-19 18:53:47 +08:00
755300db3c update 2021-01-14 23:26:38 +08:00
a790f8042d update 2021-01-14 23:22:03 +08:00
d0db2021a6 v3.4.1发布 2021-01-10 17:55:48 +08:00
c403fc7496 更新orange主题手机端首尾章节跳转逻辑 2021-01-07 20:59:19 +08:00
e4927d7ac6 爬虫管理系统设置session默认超时时间为1天,解决由于编写爬虫规则时间过长导致的提交失败问题 2021-01-05 21:46:01 +08:00
a00a2141f2 爬虫管理系统设置session默认超时时间为1天,解决由于编写爬虫规则时间过长导致的提交失败问题 2021-01-05 21:45:04 +08:00
7cc7d8b541 v3.4.0发布 2021-01-04 10:28:01 +08:00
e4822979e2 elasticsearch升级到7.x,集成RestHighLevelClient客户端 2021-01-03 13:42:40 +08:00
ab741ec6bf v3.3.0发布 2020-12-28 12:06:19 +08:00
057c0646cd v3.3.0发布 2020-12-28 12:02:34 +08:00
57a9cd09ef v3.3.0发布 2020-12-28 11:06:27 +08:00
1a49e2a340 增加外部配置文件来配置网站信息 2020-12-28 10:58:38 +08:00
f8411c2337 v3.3.0发布 2020-12-28 09:34:22 +08:00
343a741c21 更新展示图片 2020-12-27 15:54:50 +08:00
f1a5fb4813 更新展示图片 2020-12-27 15:34:23 +08:00
0428356bd4 新增蓝色主题模版 2020-12-27 09:43:45 +08:00
c01097cd5f 更新v3.3.0的安装文档 2020-12-26 23:53:05 +08:00
7e650a0a04 修改版本号 2020-12-26 22:27:51 +08:00
45c59ecc37 前端新增深色主题模版 2020-12-26 22:16:58 +08:00
5e3962fef4 update 2020-12-26 20:10:11 +08:00
7f5035e369 update 2020-12-26 20:08:07 +08:00
44aad39847 update 2020-12-26 20:00:21 +08:00
6ad51908d5 文件夹结构调整,新增模版自定义功能 2020-12-26 19:13:07 +08:00
f03ab953d0 v3.2.0发布 2020-12-26 11:45:19 +08:00
5cc9dfa1bc v3.2.0发布 2020-12-26 11:42:09 +08:00
2fbda60617 修复jwt校验失败后的bug 2020-12-24 17:13:36 +08:00
39c19ac004 页面不存在则跳转到404页面 2020-12-24 16:54:37 +08:00
7494fe431a 页面不存在则跳转到404页面 2020-12-24 16:45:48 +08:00
c9f1500976 新增404页面,访问已删除的书页/目录页/内容页自动跳转到404页面 2020-12-24 16:26:21 +08:00
f61c252e71 爬虫代码优化 2020-12-24 01:30:00 +08:00
6fd183c2ae 爬虫代码优化 2020-12-24 01:22:19 +08:00
c3daaecaaa 爬虫代码优化 2020-12-24 01:17:52 +08:00
1b6cc8ccd5 爬虫代码优化 2020-12-24 00:10:19 +08:00
0a10504461 优化章节字数算法,优化爬虫代码 2020-12-23 23:48:34 +08:00
1046a7ffc1 后台数据校验优化 2020-12-22 23:12:22 +08:00
612555dbe6 更新QQ群 2020-12-22 09:35:24 +08:00
d5768e4011 后台首页gitee仓库地址更新 2020-12-21 17:51:54 +08:00
5982eb623f 更新文档 2020-12-16 09:53:39 +08:00
85ad5fa3b2 增加官网地址 2020-12-15 10:23:12 +08:00
bdc81f7676 更新安卓客户端 2020-12-13 10:09:42 +08:00
f31c86f362 修复手机端导航栏书架的点击问题 2020-12-13 09:33:59 +08:00
45d8902429 更新接口文档示例 2020-12-12 12:16:13 +08:00
ff9696bb7e 添加接口文档示例 2020-12-12 12:03:40 +08:00
cacebcaa33 小说章节列表接口排序字段新增默认值 2020-12-12 11:16:24 +08:00
355cb80458 restful api改造 2020-12-12 10:03:15 +08:00
a8c74d061c 修改gitee仓库地址 2020-12-11 13:40:35 +08:00
a713b66c1b 爬虫优化,兼容更多源站 2020-12-10 19:04:44 +08:00
e9d915c1fe 修改版本号 2020-12-10 13:39:57 +08:00
cd3520971d 修改版本号 2020-12-10 08:40:15 +08:00
dc4c9138ee novel-admin加入父工程管理 2020-12-09 18:24:23 +08:00
f830600c3e 爬虫优化,提升兼容性 2020-12-09 16:39:15 +08:00
154210719f 简化.gitignore 2020-12-09 08:48:27 +08:00
11e744e6a8 删掉不知道是啥文件 2020-12-07 16:11:20 +08:00
944ef912e2 修复后台管理首页因为数据库大小写敏感导致的报错 2020-12-07 16:06:46 +08:00
2002 changed files with 175495 additions and 25518 deletions

79
.github/workflows/release.yml vendored Normal file
View File

@ -0,0 +1,79 @@
name: Create novel-plus Maven Release with ZIPs
on:
push:
# 匹配所有以'v'开头的标签
tags:
- 'v*'
jobs:
build-and-release:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Set up JDK 21
uses: actions/setup-java@v3
with:
java-version: '21'
# 可选默认是 temurin也可以选择其他发行版
distribution: 'temurin'
- name: Build project with Maven
run: mvn clean install -DskipTests=true -Pcentral-repo
- name: Create Release
id: create_release
uses: actions/create-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
# 使用 tag_name 而不是 github.ref
tag_name: ${{ github.ref_name }}
release_name: novel-plus ${{ github.ref_name }}
draft: false
prerelease: false
# 使用 action 来替代直接 curl 进行上传
- name: Upload sql.zip
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: ${{ github.workspace }}/novel-common/target/build/sql.zip
asset_name: sql.zip
asset_content_type: application/zip
- name: Upload novel-crawl.zip
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: ${{ github.workspace }}/novel-crawl/target/build/novel-crawl.zip
asset_name: novel-crawl.zip
asset_content_type: application/zip
- name: Upload novel-front.zip
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: ${{ github.workspace }}/novel-front/target/build/novel-front.zip
asset_name: novel-front.zip
asset_content_type: application/zip
- name: Upload novel-admin.zip
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: ${{ github.workspace }}/novel-admin/target/build/novel-admin.zip
asset_name: novel-admin.zip
asset_content_type: application/zip

25
.gitignore vendored
View File

@ -1,18 +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
/novel-admin/target
/*.iml
/novel-admin/*.iml
.DS_Store
/novel-admin/cachedata
/novel-admin/logs
**/logs
**/.idea
**/cachedata
**/target
**/*.iml
**/.DS_Store

View File

@ -1,32 +0,0 @@
package com.java2nb.system.dao;
import com.java2nb.system.domain.UserDO;
import java.util.List;
import java.util.Map;
import org.apache.ibatis.annotations.Mapper;
/**
*
* @author xiongxy
* @email 1179705413@qq.com
* @date 2020-12-01 03:46:33
*/
@Mapper
public interface UserDao {
UserDO get(Long id);
List<UserDO> list(Map<String,Object> map);
int count(Map<String,Object> map);
int save(UserDO user);
int update(UserDO user);
int remove(Long id);
int batchRemove(Long[] ids);
}

View File

@ -1,177 +0,0 @@
package com.java2nb.system.domain;
import java.io.Serializable;
import java.math.BigDecimal;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.java2nb.common.jsonserializer.LongToStringSerializer;
import org.springframework.format.annotation.DateTimeFormat;
import java.util.Date;
/**
*
*
* @author xiongxy
* @email 1179705413@qq.com
* @date 2020-12-01 03:46:33
*/
public class UserDO implements Serializable {
private static final long serialVersionUID = 1L;
//主键
//java中的long能表示的范围比js中number大,也就意味着部分数值在js中存不下(变成不准确的值)
//所以通过序列化成字符串来解决
@JsonSerialize(using = LongToStringSerializer.class)
private Long id;
//登录名
private String username;
//登录密码
private String password;
//昵称
private String nickName;
//用户头像
private String userPhoto;
//用户性别01
private Integer userSex;
//账户余额
//java中的long能表示的范围比js中number大,也就意味着部分数值在js中存不下(变成不准确的值)
//所以通过序列化成字符串来解决
@JsonSerialize(using = LongToStringSerializer.class)
private Long accountBalance;
//用户状态0正常
private Integer status;
//创建时间
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date createTime;
//更新时间
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date updateTime;
/**
* 设置:主键
*/
public void setId(Long id) {
this.id = id;
}
/**
* 获取:主键
*/
public Long getId() {
return id;
}
/**
* 设置:登录名
*/
public void setUsername(String username) {
this.username = username;
}
/**
* 获取:登录名
*/
public String getUsername() {
return username;
}
/**
* 设置:登录密码
*/
public void setPassword(String password) {
this.password = password;
}
/**
* 获取:登录密码
*/
public String getPassword() {
return password;
}
/**
* 设置:昵称
*/
public void setNickName(String nickName) {
this.nickName = nickName;
}
/**
* 获取:昵称
*/
public String getNickName() {
return nickName;
}
/**
* 设置:用户头像
*/
public void setUserPhoto(String userPhoto) {
this.userPhoto = userPhoto;
}
/**
* 获取:用户头像
*/
public String getUserPhoto() {
return userPhoto;
}
/**
* 设置用户性别01
*/
public void setUserSex(Integer userSex) {
this.userSex = userSex;
}
/**
* 获取用户性别01
*/
public Integer getUserSex() {
return userSex;
}
/**
* 设置:账户余额
*/
public void setAccountBalance(Long accountBalance) {
this.accountBalance = accountBalance;
}
/**
* 获取:账户余额
*/
public Long getAccountBalance() {
return accountBalance;
}
/**
* 设置用户状态0正常
*/
public void setStatus(Integer status) {
this.status = status;
}
/**
* 获取用户状态0正常
*/
public Integer getStatus() {
return status;
}
/**
* 设置:创建时间
*/
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
/**
* 获取:创建时间
*/
public Date getCreateTime() {
return createTime;
}
/**
* 设置:更新时间
*/
public void setUpdateTime(Date updateTime) {
this.updateTime = updateTime;
}
/**
* 获取:更新时间
*/
public Date getUpdateTime() {
return updateTime;
}
}

View File

@ -1,30 +0,0 @@
package com.java2nb.system.service;
import com.java2nb.system.domain.UserDO;
import java.util.List;
import java.util.Map;
/**
*
*
* @author xiongxy
* @email 1179705413@qq.com
* @date 2020-12-01 03:46:33
*/
public interface UserService {
UserDO get(Long id);
List<UserDO> list(Map<String, Object> map);
int count(Map<String, Object> map);
int save(UserDO user);
int update(UserDO user);
int remove(Long id);
int batchRemove(Long[] ids);
}

View File

@ -1,55 +0,0 @@
package com.java2nb.system.service.impl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Map;
import com.java2nb.system.dao.UserDao;
import com.java2nb.system.domain.UserDO;
import com.java2nb.system.service.UserService;
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserDao userDao;
@Override
public UserDO get(Long id){
return userDao.get(id);
}
@Override
public List<UserDO> list(Map<String, Object> map){
return userDao.list(map);
}
@Override
public int count(Map<String, Object> map){
return userDao.count(map);
}
@Override
public int save(UserDO user){
return userDao.save(user);
}
@Override
public int update(UserDO user){
return userDao.update(user);
}
@Override
public int remove(Long id){
return userDao.remove(id);
}
@Override
public int batchRemove(Long[] ids){
return userDao.batchRemove(ids);
}
}

View File

@ -1,138 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.java2nb.system.dao.UserDao">
<select id="get" resultType="com.java2nb.system.domain.UserDO">
select `id`,`username`,`password`,`nick_name`,`user_photo`,`user_sex`,`account_balance`,`status`,`create_time`,`update_time` from user where id = #{value}
</select>
<select id="list" resultType="com.java2nb.system.domain.UserDO">
select `id`,`username`,`password`,`nick_name`,`user_photo`,`user_sex`,`account_balance`,`status`,`create_time`,`update_time` from user
<where>
<if test="id != null and id != ''"> and id = #{id} </if>
<if test="username != null and username != ''"> and username = #{username} </if>
<if test="password != null and password != ''"> and password = #{password} </if>
<if test="nickName != null and nickName != ''"> and nick_name = #{nickName} </if>
<if test="userPhoto != null and userPhoto != ''"> and user_photo = #{userPhoto} </if>
<if test="userSex != null and userSex != ''"> and user_sex = #{userSex} </if>
<if test="accountBalance != null and accountBalance != ''"> and account_balance = #{accountBalance} </if>
<if test="status != null and status != ''"> and status = #{status} </if>
<if test="createTime != null and createTime != ''"> and create_time = #{createTime} </if>
<if test="updateTime != null and updateTime != ''"> and update_time = #{updateTime} </if>
</where>
<choose>
<when test="sort != null and sort.trim() != ''">
order by ${sort} ${order}
</when>
<otherwise>
order by id desc
</otherwise>
</choose>
<if test="offset != null and limit != null">
limit #{offset}, #{limit}
</if>
</select>
<select id="count" resultType="int">
select count(*) from user
<where>
<if test="id != null and id != ''"> and id = #{id} </if>
<if test="username != null and username != ''"> and username = #{username} </if>
<if test="password != null and password != ''"> and password = #{password} </if>
<if test="nickName != null and nickName != ''"> and nick_name = #{nickName} </if>
<if test="userPhoto != null and userPhoto != ''"> and user_photo = #{userPhoto} </if>
<if test="userSex != null and userSex != ''"> and user_sex = #{userSex} </if>
<if test="accountBalance != null and accountBalance != ''"> and account_balance = #{accountBalance} </if>
<if test="status != null and status != ''"> and status = #{status} </if>
<if test="createTime != null and createTime != ''"> and create_time = #{createTime} </if>
<if test="updateTime != null and updateTime != ''"> and update_time = #{updateTime} </if>
</where>
</select>
<insert id="save" parameterType="com.java2nb.system.domain.UserDO">
insert into user
(
`id`,
`username`,
`password`,
`nick_name`,
`user_photo`,
`user_sex`,
`account_balance`,
`status`,
`create_time`,
`update_time`
)
values
(
#{id},
#{username},
#{password},
#{nickName},
#{userPhoto},
#{userSex},
#{accountBalance},
#{status},
#{createTime},
#{updateTime}
)
</insert>
<insert id="saveSelective" parameterType="com.java2nb.system.domain.UserDO">
insert into user
(
<if test="id != null"> `id`, </if>
<if test="username != null"> `username`, </if>
<if test="password != null"> `password`, </if>
<if test="nickName != null"> `nick_name`, </if>
<if test="userPhoto != null"> `user_photo`, </if>
<if test="userSex != null"> `user_sex`, </if>
<if test="accountBalance != null"> `account_balance`, </if>
<if test="status != null"> `status`, </if>
<if test="createTime != null"> `create_time`, </if>
<if test="updateTime != null"> `update_time` </if>
)
values
(
<if test="id != null"> #{id}, </if>
<if test="username != null"> #{username}, </if>
<if test="password != null"> #{password}, </if>
<if test="nickName != null"> #{nickName}, </if>
<if test="userPhoto != null"> #{userPhoto}, </if>
<if test="userSex != null"> #{userSex}, </if>
<if test="accountBalance != null"> #{accountBalance}, </if>
<if test="status != null"> #{status}, </if>
<if test="createTime != null"> #{createTime}, </if>
<if test="updateTime != null"> #{updateTime} </if>
)
</insert>
<update id="update" parameterType="com.java2nb.system.domain.UserDO">
update user
<set>
<if test="username != null">`username` = #{username}, </if>
<if test="password != null">`password` = #{password}, </if>
<if test="nickName != null">`nick_name` = #{nickName}, </if>
<if test="userPhoto != null">`user_photo` = #{userPhoto}, </if>
<if test="userSex != null">`user_sex` = #{userSex}, </if>
<if test="accountBalance != null">`account_balance` = #{accountBalance}, </if>
<if test="status != null">`status` = #{status}, </if>
<if test="createTime != null">`create_time` = #{createTime}, </if>
<if test="updateTime != null">`update_time` = #{updateTime}</if>
</set>
where id = #{id}
</update>
<delete id="remove">
delete from user where id = #{value}
</delete>
<delete id="batchRemove">
delete from user where id in
<foreach item="id" collection="array" open="(" separator="," close=")">
#{id}
</foreach>
</delete>
</mapper>

266
README.md
View File

@ -1,231 +1,97 @@
[![index]( https://s1.ax1x.com/2020/07/03/NOSA5q.jpg )]( https://cloud.tencent.com/act/cps/redirect?redirect=1052&cps_key=736e609d66e0ac4e57813316cec6fd0b&from=console )
<p align="center">
<a href="https://www.swiftproxy.net/?code=T2WV1VT50"><img src="https://xxyopen.com/images/ad1.png" alt="AD" ></a>
<a href="https://cloud.tencent.com/act/cps/redirect?redirect=2446&cps_key=736e609d66e0ac4e57813316cec6fd0b&from=console"><img src="https://youdoc.github.io/img/tencent.jpg" alt="AD" ></a>
</p>
<p align="center">
<a href='https://github.com/201206030/novel-plus'><img alt="Github stars" src="https://img.shields.io/github/stars/201206030/novel-plus?logo=github"></a>
<a href='https://github.com/201206030/novel-plus'><img alt="Github forks" src="https://img.shields.io/github/forks/201206030/novel-plus?logo=github"></a>
<a href='https://gitee.com/novel_dev_team/novel-plus'><img alt="Gitee stars" src="https://gitee.com/novel_dev_team/novel-plus/badge/star.svg?theme=gitee"></a>
<a href='https://gitee.com/novel_dev_team/novel-plus'><img alt="Gitee forks" src="https://gitee.com/novel_dev_team/novel-plus/badge/fork.svg?theme=gitee"></a>
</p>
# 小说精品屋-plus
<p align="center">
👉 <a href='https://novel.xxyopen.com'>官网</a> | 👉 <a href='https://www.bilibili.com/video/BV1Zo4y187Mi'>项目演示</a> | 👉 <a href='https://docs.xxyopen.com/course/novelplus/1.html'>安装教程</a>
</p>
#### 项目小说精品屋-微服务版
## 项目介绍
基于小说精品屋-plus构建的Spring Cloud 微服务小说门户平台
novel-plus 是一个多端PCWAP阅读功能完善的原创文学 CMS
系统由前台门户系统作家后台管理系统平台后台管理系统和爬虫管理系统等多个子系统构成包括小说推荐作品检索小说排行小说阅读小说评论会员中心作家专区等功能支持自定义多模版可拓展的多种小说内容存储方式内置数据库分表存储和
TXT 文本存储阅读主题切换多爬虫源自动采集和更新数据会员充值订阅模式新闻发布和实时统计报表
Gitee仓库地址 https://gitee.com/xiongxyang/novel-cloud
## 项目地址
GitHub仓库地址 https://github.com/201206030/novel-cloud
- 学习版[GitHub](https://github.com/201206030/novel) [码云](https://gitee.com/novel_dev_team/novel)
[保姆级教程](https://docs.xxyopen.com)
- **应用版**[GitHub](https://github.com/201206030/novel-plus) [码云](https://gitee.com/novel_dev_team/novel-plus)
- 微服务版[GitHub](https://github.com/201206030/novel-cloud) [码云](https://gitee.com/novel_dev_team/novel-cloud)
#### 演示地址
[点击前往](http://47.106.243.172:8888/)
#### 前言
小说精品屋-plus致力于打造一个完整的商用小说门户平台使用前建议先阅读此文档
#### 项目介绍
小说精品屋-plus是在[小说精品屋](https://github.com/201206030/fiction_house)的基础上去除了漫画和弹幕模块专注于小说是一个多端PC、移动阅读、功能完善的小说原创/爬虫网站项目既包含了作家专区供原创作者上传小说又提供了爬虫工具通过规则多线程全自动采集任意小说网站数据已兼容99%的小说网站),新书自动入库,老书自动更新。
小说精品屋-plus重新进行了数据库设计代码重构和功能增强提升了程序整体的可读性和性能增加了很多商用特性主要升级如下
- [x] 数据库重新设计结构调整
- [x] 服务端代码重构MyBatis3升级为MyBatis3DynamicSql
- [x] 移动站与PC站站点分离浏览器自动识别跳转
- [x] PC站UI更新
- [x] 新闻模块
- [x] 排行榜
- [x] 小说评论模块
- [x] 阅读主题模块
- [x] 作家专区
- [x] 充值
- [x] 订阅
- [x] 后台管理系统
- [x] 爬虫管理系统
#### 项目结构
## 项目结构
```
novel-plus -- 父工程
novel-common -- 通用模块
novel-front -- 前台门户系统
novel-crawl -- 爬虫管理系统
novel-admin -- 后台管理系统
novel-front -- 前台门户&作家后台
novel-crawl -- 爬虫
novel-admin -- 管理后台
templates -- 前端模版
```
#### 技术选型
## 技术选型
| 技术 | 说明
| -------------------- | ---------------------------
| 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
| 技术 | 说明
|---------------------| ---------------------------
| Spring Boot | Spring 应用快速开发脚手架
| Spring AI | Spring 官方 AI 框架
| MyBatis | 持久层 ORM 框架
| MyBatis Dynamic SQL | Mybatis 动态 sql
| PageHelper | MyBatis 分页插件
| MyBatis Generator | 持久层代码生成插
| Sharding-JDBC | 代码层分库分表中间件
| JJWT | JWT 登录支持
| Spring Security | 安全框架
| Apache Shiro | 安全框架
| Redis | 缓存方案
| Aliyun OSS | 阿里云对象存储服务图片存储备选方案
| Lombok | 简化对象封装工具
| Docker | 应用容器引擎
| MySQL | 数据库服务
| Thymeleaf | 模板引擎
| Layui | 前端 UI 框架
#### PC站截图
## 项目截图
1. 首页
### 绿色主题模版
![img](https://oscimg.oschina.net/oscnet/up-bbb1c7f72e183327bff754a9fa8bb75223e.png)
[![点击查看大图](https://www.xxyopen.com/images/green_novel.png)](https://www.xxyopen.com/images/green_novel.png)
[![点击查看大图](https://www.xxyopen.com/images/resource/os/novel-plus/green3.png)](https://www.xxyopen.com/images/resource/os/novel-plus/green3.png)
[![点击查看大图](https://www.xxyopen.com/images/resource/os/novel-plus/green2.png)](https://www.xxyopen.com/images/resource/os/novel-plus/green2.png)
2. 分类索引页
## 演示视频
![img](https://oscimg.oschina.net/oscnet/up-d0b2e03129bfae47b8bb96a491b73d383c5.png)
https://www.bilibili.com/video/BV18e41197xs
3. 搜索页
## 增值服务
![img](https://gitee.com/xiongxyang/novel-plus/raw/release_v2.1.0/assets/QQ20200520-215756.png)
👉 [了解详情](https://novel.xxyopen.com/service.htm)
![img](https://oscimg.oschina.net/oscnet/up-ed5f689557718924acac76bc3ebca36afcb.png)
## 微信公众号
4. 排行榜
发布最新更新动态最新前端模版最新爬虫规则文档教程等
![img](https://oscimg.oschina.net/oscnet/up-78d5a68586cd92a86c669311f414508f922.png)
![](https://youdoc.github.io/img/qrcode_for_gh.jpg)
5. 详情页
![img](https://oscimg.oschina.net/oscnet/up-8be2495a2869f93626b0c9c1df6f329747a.png)
6. 阅读页
![img](https://oscimg.oschina.net/oscnet/up-517c84148d2db8e11717a8bbecc57fa1be7.png)
7. 用户中心
![img](https://oscimg.oschina.net/oscnet/up-805a30e7a663a3fd5cb39a7ea26bc132a01.png)
8. 充值
![img](https://oscimg.oschina.net/oscnet/up-5a601b0b3af3224d0bebcfe12fc15075d34.png)
![img](https://oscimg.oschina.net/oscnet/up-face25d02c07b05b2ce954cc4bf4ee6a0cc.png)
9. 作家专区
![img](https://oscimg.oschina.net/oscnet/up-30766372cc7f56480ff1d7d55198204f6ea.png)
![img](https://s3.ax1x.com/2020/11/17/DVFiQI.png)
![img](https://s1.ax1x.com/2020/11/09/B7X5oF.png)
![img](https://s1.ax1x.com/2020/11/09/B7XLsx.png)
10. 购买
![img](https://oscimg.oschina.net/oscnet/up-ce0f585efd82a9670335f118cf5897c85e9.png)
![img](https://oscimg.oschina.net/oscnet/up-f849960f4c1303fea77d26e64fc505a7180.png)
#### 手机站截图
1. 首页
<img src="https://s3.ax1x.com/2020/12/04/DbsSoj.jpg" alt="index" style="zoom:33%;" />
2. 小说列表页
<img src="https://s3.ax1x.com/2020/12/04/DbrfsO.jpg" alt="微信图片_20190904181558" style="zoom: 33%;" />
3. 小说详情页
<img src="https://s3.ax1x.com/2020/12/04/DbsklV.jpg" alt="QQ图片20191018161901" style="zoom:33%;" />
4. 小说阅读页
<img src="https://s3.ax1x.com/2020/12/04/Dbsew4.jpg" alt="QQ图片20191018161901" style="zoom:33%;" />
#### 爬虫管理系统截图
![img](https://s1.ax1x.com/2020/11/03/BsOgbD.png)
![img](https://s1.ax1x.com/2020/11/03/BsOHr8.png)
#### 后台管理系统截图
![img](https://oscimg.oschina.net/oscnet/up-0552343538674a22a64819834100558f39b.png)
![img](https://s3.ax1x.com/2020/12/01/DWgLNT.png)
![img](https://s3.ax1x.com/2020/12/01/DfmRCd.png)
![img](https://oscimg.oschina.net/oscnet/up-faf5dda7320674c29a1772bc0c81d74762e.png)
#### 安装步骤
##### 数据库安装
1. 安装MySQL软件
2. 修改MySQL`max_allowed_packet `配置建议100M
3. 新建数据库设置编码为utf8mb4
4. 执行sql/novel_plus.sql脚本文件
##### 爬虫管理系统安装
1. 修改novel-common模块下application-dev.yml文件中的数据库的配置
2. 修改novel-crawl模块下application.yml文件中的管理员账号密码
3. 启动程序打开浏览器默认8081端口访问
4. 选择已有或新增爬虫源支持自定义爬虫规则点击`开启`按钮开始爬取小说数据
##### 前台小说门户安装
1. 修改novel-common模块下application-dev.yml文件中的数据库的配置
2. 启动程序打开浏览器默认8080端口访问
**喜欢此项目的可以给我的GitHub和Gitee加个Star支持一下 **
#### 其他安装教程
包安装教程[点击前往](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
#### QQ交流群
![mini-code](https://s1.ax1x.com/2020/10/31/BUQVeI.png)
#### 微信公众号发布最新更新资讯
![mini-code](https://s3.ax1x.com/2020/12/03/DoImOx.png)
#### 赞赏支持
## 赞赏支持
开源项目不易若此项目能得到你的青睐那么你可以赞赏支持作者持续开发与维护
- 服务器的费用也是一笔开销
- 为用户提供更好的开发环境
- 一杯咖啡
- 编写更完备的文档教程
- 发布更多前端模版和爬虫规则
- 一杯咖啡
![mini-code](https://s1.ax1x.com/2020/10/31/BUQJwq.png)
![](https://s1.ax1x.com/2020/10/31/BUQJwq.png)
### 免责声明
## 免责声明
本项目提供的爬虫工具仅用于采集项目初期的测试数据请勿用于商业盈利
用户使用本系统从事任何违法违规的事情一切后果由用户自行承担作者不承担任何责任
#### 备注
精品小说屋所有相关项目均已在开源中国公开感兴趣的可进入[开源中国](https://www.oschina.net/p/fiction_house)按关键字`精品小说屋`搜索。
[![index](https://s1.ax1x.com/2020/07/03/NOSuMF.jpg)](https://www.aliyun.com/minisite/goods?userCode=uf4nasee )
本项目提供的爬虫工具仅用于采集项目初期的测试数据请勿用于商业盈利 用户使用本系统从事任何违法违规的事情一切后果由用户自行承担作者不承担任何责任

Binary file not shown.

Before

Width:  |  Height:  |  Size: 81 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 411 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 263 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 75 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 105 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 63 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 461 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 111 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 93 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 91 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 130 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 82 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 61 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 310 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 223 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 79 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 69 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 155 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 360 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 357 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 307 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 929 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 194 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 185 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 85 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 77 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 764 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 MiB

View File

@ -0,0 +1,53 @@
mode:
# 单机模式
type: Standalone
# 元数据持久化
repository:
# 数据库持久化
type: JDBC
# 数据源配置
dataSources:
ds_1:
dataSourceClassName: com.zaxxer.hikari.HikariDataSource
driverClassName: com.mysql.cj.jdbc.Driver
jdbcUrl: jdbc:mysql://localhost:3306/novel_plus?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai
username: root
password: test123456
ds_2:
dataSourceClassName: com.zaxxer.hikari.HikariDataSource
driverClassName: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/information_schema?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai
username: root
password: test123456
# 规则配置
rules:
- !SINGLE
tables:
- "*.*"
- !SHARDING
tables: # 数据分片规则配置
book_content:
# 分库策略缺省表示使用默认分库策略
actualDataNodes: ds_${1}.book_content${0..9}
# 分表策略
tableStrategy:
standard:
# 分片列名称
shardingColumn: index_id
# 分片算法名称
shardingAlgorithmName: bookContentSharding
shardingAlgorithms:
bookContentSharding:
# 行表达式分片算法使用 Groovy 的表达式提供对 SQL 语句中的 = IN 的分片操作支持
type: INLINE
props:
# 分片算法的行表达式
algorithm-expression: book_content${index_id % 10}
props:
# 是否在日志中打印 SQL
sql-show: true

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

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

3
doc/sql/20210913.sql Normal file
View File

@ -0,0 +1,3 @@
alter table book_index add column storage_type varchar(10) NOT NULL DEFAULT 'db' COMMENT '存储方式' after book_price ;

121
doc/sql/20230413.sql Normal file
View File

@ -0,0 +1,121 @@
CREATE TABLE `website_info`
(
id bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
name varchar(50) NOT NULL COMMENT '网站名',
domain varchar(50) NOT NULL COMMENT '网站域名',
keyword varchar(50) NOT NULL COMMENT 'SEO关键词',
description varchar(512) NOT NULL COMMENT '网站描述',
qq varchar(20) NOT NULL COMMENT '站长QQ',
logo varchar(200) NOT NULL COMMENT '网站logo图片默认',
logo_dark varchar(200) NOT NULL COMMENT '网站logo图片深色',
create_time datetime null comment '创建时间',
create_user_id bigint null comment '创建人ID',
update_time datetime null comment '更新时间',
update_user_id bigint null comment '更新人ID',
PRIMARY KEY (`id`)
) ENGINE = InnoDB
DEFAULT CHARSET = utf8mb4 COMMENT ='网站信息表';
INSERT INTO website_info (id, name, domain, keyword, description, qq, logo, logo_dark, create_time, create_user_id,
update_time, update_user_id)
VALUES (1, '小说精品屋', 'www.xxyopen.com', '小说精品屋,小说,小说CMS,原创文学系统,开源小说系统,免费小说建站程序',
'小说精品屋是一个多端PCWAP阅读功能完善的原创文学CMS系统由前台门户系统作家后台管理系统平台后台管理系统爬虫管理系统等多个子系统构成支持会员充值订阅模式新闻发布和实时统计报表等功能新书自动入库老书自动更新',
'1179705413', 'https://youdoc.gitee.io/resource/images/logo/logo.png',
'https://youdoc.gitee.io/resource/images/logo/logo_white.png', null, null, null, null);
INSERT INTO sys_menu (menu_id, parent_id, name, url, perms, type, icon, order_num, gmt_create, gmt_modified)
VALUES (300, 0, '网站管理', '', '', 0, 'fa fa-television', 6, null, null);
INSERT
INTO `sys_menu`(`menu_id`, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`)
VALUES (301, 300, '网站信息', 'novel/websiteInfo', 'novel:websiteInfo:websiteInfo', '1', 'fa', '6');
INSERT INTO sys_role_menu (role_id, menu_id)
VALUES (1, 300);
INSERT INTO sys_role_menu (role_id, menu_id)
VALUES (1, 301);
INSERT INTO `sys_menu` (menu_id, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`)
VALUES (310, 300, '友情链接', 'novel/friendLink', 'novel:friendLink:friendLink', '1', 'fa', '16');
INSERT INTO `sys_menu` (menu_id, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`)
VALUES (311, 310, '查看', null, 'novel:friendLink:detail', '2', null, '6');
INSERT INTO `sys_menu` (menu_id, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`)
VALUES (312, 310, '新增', null, 'novel:friendLink:add', '2', null, '6');
INSERT INTO `sys_menu` (menu_id, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`)
VALUES (313, 310, '修改', null, 'novel:friendLink:edit', '2', null, '6');
INSERT INTO `sys_menu` (menu_id, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`)
VALUES (314, 310, '删除', null, 'novel:friendLink:remove', '2', null, '6');
INSERT INTO `sys_menu` (menu_id, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`)
VALUES (315, 310, '批量删除', null, 'novel:friendLink:batchRemove', '2', null, '6');
INSERT INTO sys_role_menu (role_id, menu_id)
VALUES (1, 310);
INSERT INTO sys_role_menu (role_id, menu_id)
VALUES (1, 311);
INSERT INTO sys_role_menu (role_id, menu_id)
VALUES (1, 312);
INSERT INTO sys_role_menu (role_id, menu_id)
VALUES (1, 313);
INSERT INTO sys_role_menu (role_id, menu_id)
VALUES (1, 314);
INSERT INTO sys_role_menu (role_id, menu_id)
VALUES (1, 315);
INSERT INTO sys_menu (menu_id, parent_id, name, url, perms, type, icon, order_num, gmt_create, gmt_modified)
VALUES (400, 0, '会员管理', '', '', 0, 'fa fa-vcard', 9, null, null);
INSERT
INTO `sys_menu`(`menu_id`, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`)
VALUES (401, 400, '会员列表', 'novel/user', 'novel:user:user', '1', 'fa', '6');
INSERT INTO sys_role_menu (role_id, menu_id)
VALUES (1, 400);
INSERT INTO sys_role_menu (role_id, menu_id)
VALUES (1, 401);
INSERT INTO sys_menu (menu_id, parent_id, name, url, perms, type, icon, order_num, gmt_create, gmt_modified)
VALUES (500, 0, '订单管理', '', '', 0, 'fa fa-money', 19, null, null);
INSERT
INTO `sys_menu`(`menu_id`, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`)
VALUES (501, 500, '订单列表', 'novel/pay', 'novel:pay:pay', '1', 'fa', '6');
INSERT INTO sys_role_menu (role_id, menu_id)
VALUES (1, 500);
INSERT INTO sys_role_menu (role_id, menu_id)
VALUES (1, 501);
INSERT INTO sys_menu (menu_id, parent_id, name, url, perms, type, icon, order_num, gmt_create, gmt_modified)
VALUES (600, 0, '小说管理', '', '', 0, 'fa fa-book', 15, null, null);
INSERT
INTO `sys_menu`(`menu_id`, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`)
VALUES (601, 600, '小说列表', 'novel/book', 'novel:book:book', '1', 'fa', '6');
INSERT INTO sys_role_menu (role_id, menu_id)
VALUES (1, 600);
INSERT INTO sys_role_menu (role_id, menu_id)
VALUES (1, 601);
INSERT INTO `sys_menu` (menu_id, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`)
VALUES (602, 601, '删除', null, 'novel:book:remove', '2', null, '6');
INSERT INTO sys_role_menu (role_id, menu_id)
VALUES (1, 602);
INSERT
INTO `sys_menu`(`menu_id`, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`)
VALUES (603, 600, '评论管理', 'novel/bookComment', 'novel:bookComment:bookComment', '1', 'fa', '10');
INSERT INTO sys_role_menu (role_id, menu_id)
VALUES (1, 603);
INSERT INTO `sys_menu` (menu_id, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`)
VALUES (604, 603, '删除', null, 'novel:bookComment:remove', '2', null, '6');
INSERT INTO sys_role_menu (role_id, menu_id)
VALUES (1, 604);

51
doc/sql/20230418.sql Normal file
View File

@ -0,0 +1,51 @@
INSERT INTO sys_dict (name, value, type, description, sort, parent_id, create_by, create_date, update_by,
update_date, remarks, del_flag)
VALUES ('轮播图', '0', 'book_rec_type', '小说推荐类型', 0, null, null, null, null, null, '', null);
INSERT INTO sys_dict (name, value, type, description, sort, parent_id, create_by, create_date, update_by,
update_date, remarks, del_flag)
VALUES ('顶部小说栏', '1', 'book_rec_type', '小说推荐类型', 1, null, null, null, null, null, '', null);
INSERT INTO sys_dict (name, value, type, description, sort, parent_id, create_by, create_date, update_by,
update_date, remarks, del_flag)
VALUES ('本周强推', '2', 'book_rec_type', '小说推荐类型', 2, null, null, null, null, null, '', null);
INSERT INTO sys_dict (name, value, type, description, sort, parent_id, create_by, create_date, update_by,
update_date, remarks, del_flag)
VALUES ('热门推荐', '3', 'book_rec_type', '小说推荐类型', 3, null, null, null, null, null, '', null);
INSERT INTO sys_dict (name, value, type, description, sort, parent_id, create_by, create_date, update_by,
update_date, remarks, del_flag)
VALUES ('精品推荐', '4', 'book_rec_type', '小说推荐类型', 4, null, null, null, null, null, '', null);
INSERT INTO `sys_menu` (`menu_id`, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`)
VALUES (320, '300', '小说推荐', 'novel/bookSetting', 'novel:bookSetting:bookSetting', '1', 'fa', '6');
INSERT INTO `sys_menu` (`menu_id`, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`)
VALUES (321, '320', '查看', null, 'novel:bookSetting:detail', '2', null, '6');
INSERT INTO `sys_menu` (`menu_id`, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`)
VALUES (322, '320', '新增', null, 'novel:bookSetting:add', '2', null, '6');
INSERT INTO `sys_menu` (`menu_id`, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`)
VALUES (323, '320', '修改', null, 'novel:bookSetting:edit', '2', null, '6');
INSERT INTO `sys_menu` (`menu_id`, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`)
VALUES (324, '320', '删除', null, 'novel:bookSetting:remove', '2', null, '6');
INSERT INTO `sys_menu` (`menu_id`, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`)
VALUES (325, '320', '批量删除', null, 'novel:bookSetting:batchRemove', '2', null, '6');
INSERT INTO sys_role_menu (role_id, menu_id)
VALUES (1, 320);
INSERT INTO sys_role_menu (role_id, menu_id)
VALUES (1, 321);
INSERT INTO sys_role_menu (role_id, menu_id)
VALUES (1, 322);
INSERT INTO sys_role_menu (role_id, menu_id)
VALUES (1, 323);
INSERT INTO sys_role_menu (role_id, menu_id)
VALUES (1, 324);
INSERT INTO sys_role_menu (role_id, menu_id)
VALUES (1, 325);
INSERT INTO `sys_menu` (`menu_id`, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`)
VALUES (410, '400', '会员反馈', 'novel/userFeedback', 'novel:userFeedback:userFeedback', '1', 'fa', '16');
INSERT INTO sys_role_menu (role_id, menu_id)
VALUES (1, 410);

4
doc/sql/20230508.sql Normal file
View File

@ -0,0 +1,4 @@
INSERT INTO `sys_menu` (`menu_id`, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`)
VALUES (305, '301', '修改', null, 'novel:websiteInfo:edit', '2', null, '6');
INSERT INTO sys_role_menu (role_id, menu_id)
VALUES (1, 305);

3
doc/sql/20240512.sql Normal file
View File

@ -0,0 +1,3 @@
update crawl_source
set crawl_rule = replace(crawl_rule, 'ibiquge.net', 'ibiquzw.org')
where id = 16;

44
doc/sql/20250317.sql Normal file
View File

@ -0,0 +1,44 @@
INSERT INTO crawl_source (source_name, crawl_rule, source_status, create_time, update_time)
VALUES ('香书小说网', '{
"bookListUrl": "http://www.xbiqugu.la/fenlei/{catId}_{page}.html",
"catIdRule": {
"catId1": "1",
"catId2": "2",
"catId3": "3",
"catId4": "4",
"catId5": "6",
"catId6": "5"
},
"bookIdPatten": "<a\\\\s+href=\\"http://www.xbiqugu.la/(\\\\d+/\\\\d+)/\\"\\\\s+target=\\"_blank\\">",
"pagePatten": "<em\\\\s+id=\\"pagestats\\">(\\\\d+)/\\\\d+</em>",
"totalPagePatten": "<em\\\\s+id=\\"pagestats\\">\\\\d+/(\\\\d+)</em>",
"bookDetailUrl": "http://www.xbiqugu.la/{bookId}/",
"bookNamePatten": "<h1>([^/]+)</h1>",
"authorNamePatten": "者:([^/]+)</p>",
"picUrlPatten": "src=\\"(http://www.xbiqugu.la/files/article/image/\\\\d+/\\\\d+/\\\\d+s\\\\.jpg)\\"",
"bookStatusRule": {},
"descStart": "<div id=\\"intro\\">",
"descEnd": "</div>",
"upadateTimePatten": "<p>最后更新:(\\\\d+-\\\\d+-\\\\d+\\\\s\\\\d+:\\\\d+:\\\\d+)</p>",
"upadateTimeFormatPatten": "yyyy-MM-dd HH:mm:ss",
"bookIndexUrl": "http://www.xbiqugu.la/{bookId}/",
"indexIdPatten": "<a\\\\s+href=''/\\\\d+/\\\\d+/(\\\\d+)\\\\.html''\\\\s+>[^/]+</a>",
"indexNamePatten": "<a\\\\s+href=''/\\\\d+/\\\\d+/\\\\d+\\\\.html''\\\\s+>([^/]+)</a>",
"bookContentUrl": "http://www.xbiqugu.la/{bookId}/{indexId}.html",
"contentStart": "<div id=\\"content\\">",
"contentEnd": "<p>",
"filterContent":"<div\\\\s+id=\\"content_tip\\">\\\\s*<b>([^/]+)</b>\\\\s*</div>"
}', 0, '2024-06-01 10:11:39', '2024-06-01 10:11:39');
update crawl_source
set crawl_rule = replace(crawl_rule, 'ibiquzw.org', 'biquxs.info')
where id = 16;
delete
from sys_menu
where menu_id = 104;
delete
from sys_menu
where menu_id = 57;

2
doc/sql/Dockerfile Normal file
View File

@ -0,0 +1,2 @@
FROM mysql:8.0
COPY novel_plus.sql /docker-entrypoint-initdb.d/init.sql

3156
doc/sql/novel_plus.sql Normal file

File diff suppressed because it is too large Load Diff

3
doc/sql/readme.md Normal file
View File

@ -0,0 +1,3 @@
1. novel_plus.sql 为全量 sql 文件yyyyMMdd.sql 为增量 sql 文件
2. 第一次安装只需要执行 novel_plus.sql 文件即可
3. 后续版本升级需要根据上次代码版本的时间执行该日期之后的增量 sql 文件简单来说就是 sql 文件夹中相较于上次多出来的 sql 文件

View File

@ -1,6 +0,0 @@
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"]

View File

@ -5,7 +5,7 @@
<groupId>com.java2nb</groupId>
<artifactId>novel-admin</artifactId>
<version>2.11.0</version>
<version>5.0.1</version>
<packaging>jar</packaging>
<name>novel-admin</name>
@ -14,16 +14,14 @@
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.1.RELEASE</version>
<version>2.7.18</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>
<java.version>21</java.version>
<velocity.version>1.7</velocity.version>
<activiti.version>5.22.0</activiti.version>
<shardingsphere-jdbc.version>5.5.1</shardingsphere-jdbc.version>
</properties>
<dependencies>
@ -58,16 +56,16 @@
<groupId>net.sourceforge.nekohtml</groupId>
<artifactId>nekohtml</artifactId>
</dependency>
<!-- 请求参数校验相关 -->
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</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>
<version>8.0.29</version>
</dependency>
<dependency>
@ -75,18 +73,7 @@
<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>
@ -95,18 +82,18 @@
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.5</version>
<version>2.9.0</version>
</dependency>
<!--shiro -->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>1.3.2</version>
<version>1.11.0</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.3.2</version>
<version>1.11.0</version>
</dependency>
<!-- shiro ehcache -->
<dependency>
@ -118,7 +105,7 @@
<artifactId>ehcache-core</artifactId>
</exclusion>
</exclusions>
<version>1.4.0</version>
<version>1.11.0</version>
</dependency>
<dependency>
<groupId>com.github.theborakompanioni</groupId>
@ -129,13 +116,19 @@
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.31</version>
<version>1.2.83</version>
</dependency>
<!--velocity代码生成使用模板 -->
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity</artifactId>
<version>1.7</version>
<exclusions>
<exclusion>
<artifactId>commons-lang</artifactId>
<groupId>commons-lang</groupId>
</exclusion>
</exclusions>
</dependency>
<!--<dependency>-->
<!--<groupId>org.springframework.boot</groupId>-->
@ -164,6 +157,12 @@
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.6.1</version>
<exclusions>
<exclusion>
<artifactId>guava</artifactId>
<groupId>com.google.guava</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
@ -193,16 +192,29 @@
<groupId>org.apache.commons</groupId>
<artifactId>commons-text</artifactId>
<version>1.4</version>
<exclusions>
<exclusion>
<artifactId>commons-lang3</artifactId>
<groupId>org.apache.commons</groupId>
</exclusion>
</exclusions>
</dependency>
<!-- ehchache -->
<!-- ShardingSphere-JDBC -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>shardingsphere-jdbc</artifactId>
<version>${shardingsphere-jdbc.version}</version>
</dependency>
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache</artifactId>
<groupId>org.yaml</groupId>
<artifactId>snakeyaml</artifactId>
<version>2.2</version>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<!--war包部署需要-->
@ -224,41 +236,131 @@
<!--<scope>provided</scope>-->
<!--</dependency>-->
</dependencies>
<!-- <build>
<plugins>
&lt;!&ndash;<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<executable>true</executable>
</configuration>
</plugin>&ndash;&gt;
&lt;!&ndash;SpringBoot项目默认使用spring-boot-maven-plugin要打成被其他项目引用的jar包需要更换此插件&ndash;&gt;
&lt;!&ndash; <plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>&ndash;&gt;
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>-->
<build>
<plugins>
<!--<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<executable>true</executable>
</configuration>
</plugin>-->
<!--SpringBoot项目默认使用spring-boot-maven-plugin要打成被其他项目引用的jar包需要更换此插件-->
<!-- <plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>-->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.8</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<tasks>
<!-- 文件夹 -->
<copy todir="${project.build.directory}/build/config" overwrite="true">
<fileset dir="${basedir}/src/main/build/config">
<include name="*.*"/>
</fileset>
</copy>
<copy file="${project.build.directory}/${project.artifactId}-${project.version}.jar"
tofile="${project.build.directory}/build/${project.artifactId}.jar"/>
<fixcrlf srcdir="${basedir}/src/main/build/scripts" eol="unix"/>
<copy todir="${project.build.directory}/build/bin">
<fileset dir="${basedir}/src/main/build/scripts">
<include name="*.sh"/>
<include name="*.txt"/>
<include name="*.bat"/>
</fileset>
</copy>
<zip destfile='${project.build.directory}/build/${project.artifactId}.zip'>
<zipfileset filemode="755" dir='${project.build.directory}/build/'/>
</zip>
<copy file="${basedir}/src/main/build/docker/Dockerfile"
tofile="${project.build.directory}/build/Dockerfile"/>
</tasks>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<!--<distributionManagement>
<repositories>
<repository>
<id>nexus_release</id>
<name>release</name>
<url>http://47.106.243.172:8081/nexus/content/repositories/releases/</url>
<id>ali</id>
<url>https://maven.aliyun.com/repository/public</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
<snapshotRepository>
<id>nexus_snapshots</id>
<name>snapshots</name>
<url>http://47.106.243.172:8081/nexus/content/repositories/snapshots/</url>
</snapshotRepository>
</distributionManagement>-->
</repositories>
<pluginRepositories>
<pluginRepository>
<id>ali-plugin</id>
<url>https://maven.aliyun.com/repository/public</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>
<profiles>
<profile>
<!-- 定义一个用于切换到中央仓库的profile -->
<id>central-repo</id>
<repositories>
<repository>
<id>central</id>
<url>https://repo.maven.apache.org/maven2/</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>central-plugin</id>
<url>https://repo.maven.apache.org/maven2/</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>
</profile>
</profiles>
</project>

View File

@ -0,0 +1,9 @@
#端口号
server:
port: 8088
spring:
redis:
host: 127.0.0.1
port: 6379
password: test123456

View File

@ -0,0 +1,47 @@
mode:
# 单机模式
type: Standalone
# 元数据持久化
repository:
# 数据库持久化
type: JDBC
# 数据源配置
dataSources:
ds_1:
dataSourceClassName: com.zaxxer.hikari.HikariDataSource
driverClassName: com.mysql.cj.jdbc.Driver
jdbcUrl: jdbc:mysql://localhost:3306/novel_plus?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai
username: root
password: test123456
# 规则配置
rules:
- !SINGLE
tables:
- "*.*"
- !SHARDING
tables: # 数据分片规则配置
book_content:
# 分库策略缺省表示使用默认分库策略
actualDataNodes: ds_${1}.book_content${0..9}
# 分表策略
tableStrategy:
standard:
# 分片列名称
shardingColumn: index_id
# 分片算法名称
shardingAlgorithmName: bookContentSharding
shardingAlgorithms:
bookContentSharding:
# 行表达式分片算法使用 Groovy 的表达式提供对 SQL 语句中的 = IN 的分片操作支持
type: INLINE
props:
# 分片算法的行表达式
algorithm-expression: book_content${index_id % 10}
props:
# 是否在日志中打印 SQL
sql-show: true

View File

@ -0,0 +1,9 @@
FROM openjdk:8
ADD novel-admin.jar /root
ENV dburl=""
ENV username=""
ENV password=""
ENV redishost = ""
ENV redisport = ""
ENV redispwd = ""
ENTRYPOINT ["sh","-c","java -Dspring.datasource.url=${dburl} -Dspring.datasource.username=${username} -Dspring.datasource.password=${password} -Dspring.redis.host=${redishost} -Dspring.redis.port=${redisport} -Dspring.redis.password=${redispwd} -jar /root/novel-admin.jar"]

View File

@ -0,0 +1,94 @@
#!/bin/sh
APP_NAME=novel-admin
JAR_NAME=$APP_NAME\.jar
#PID 代表是PID文件
PID=$APP_NAME\.pid
#使用说明,用来提示输入参数
usage() {
echo "Usage: ./novel-admin.sh [start|stop|restart|status]"
exit 1
}
#检查程序是否在运行
is_exist(){
pid=`ps -ef|grep $JAR_NAME|grep -v grep|awk '{print $2}' `
#如果不存在返回1存在返回0
if [ -z "${pid}" ]; then
return 1
else
return 0
fi
}
#启动方法
start(){
is_exist
if [ $? -eq "0" ]; then
echo ">>> 小说精品屋后台正在运行 PID = ${pid} <<<"
else
echo ">>> 小说精品屋后台开始启动 <<<"
nohup java -jar -Dspring.profiles.active=prod $JAR_NAME >/dev/null 2>&1 &
sleep 20
echo $! > $PID
echo ">>> 小说精品屋后台启动完成 PID = $! <<<"
status
fi
}
#停止方法
stop(){
#is_exist
pidf=$(cat $PID)
#echo "$pidf"
echo ">>> 小说精品屋后台 PID = $pidf 开始停止 <<<"
kill $pidf
rm -rf $PID
sleep 2
is_exist
if [ $? -eq "0" ]; then
echo ">>> 小说精品屋后台 PID = $pid 开始强制停止 <<<"
kill -9 $pid
sleep 2
status
else
status
fi
}
#输出运行状态
status(){
is_exist
if [ $? -eq "0" ]; then
echo ">>> 小说精品屋后台正在运行 PID = ${pid} <<<"
else
echo ">>> 小说精品屋后台没有运行 <<<"
fi
}
#重启
restart(){
stop
start
}
#根据输入参数,选择执行对应方法,不输入则执行使用说明
case "$1" in
"start")
start
;;
"stop")
stop
;;
"status")
status
;;
"restart")
restart
;;
*)
usage
;;
esac
exit 0

View File

@ -1,25 +1,47 @@
package com.java2nb;
import lombok.extern.slf4j.Slf4j;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.transaction.annotation.EnableTransactionManagement;
//关闭SpringSecurity的功能
@EnableAutoConfiguration(exclude = {
org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration.class
})
import javax.sql.DataSource;
import java.net.InetAddress;
import java.sql.Connection;
@EnableTransactionManagement
@ServletComponentScan
@MapperScan("com.java2nb.*.dao")
@SpringBootApplication
@SpringBootApplication(exclude = {
org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration.class
})
@EnableCaching
@Slf4j
public class AdminApplication {
public static void main(String[] args) {
SpringApplication.run(AdminApplication.class, args);
}
@Bean
public CommandLineRunner commandLineRunner(ApplicationContext ctx, DataSource dataSource) {
return args -> {
log.info("创建连接池...");
try (Connection connection = dataSource.getConnection()) {
log.info("连接池已创建.");
log.info("数据库:{}", connection.getMetaData().getDatabaseProductName());
log.info("数据库版本:{}", connection.getMetaData().getDatabaseProductVersion());
}
log.info("项目启动啦,访问路径:{}",
"http://" + InetAddress.getLocalHost().getHostAddress() + ":" + ctx.getEnvironment()
.getProperty("server.port"));
};
}
}

View File

@ -1,19 +1,16 @@
package com.java2nb.common.aspect;
import com.java2nb.common.utils.HttpContextUtils;
import com.java2nb.common.utils.IPUtils;
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
@ -37,11 +34,10 @@ public class WebLogAspect {
logger.info("请求地址 : " + request.getRequestURL().toString());
logger.info("HTTP METHOD : " + request.getMethod());
// 获取真实的ip地址
//logger.info("IP : " + IPAddressUtil.getClientIpAddress(request));
logger.info("IP : " + IPUtils.getIpAddr(request));
logger.info("CLASS_METHOD : " + joinPoint.getSignature().getDeclaringTypeName() + "."
+ joinPoint.getSignature().getName());
+ joinPoint.getSignature().getName());
logger.info("参数 : " + Arrays.toString(joinPoint.getArgs()));
// loggger.info("参数 : " + joinPoint.getArgs());
}

View File

@ -0,0 +1,73 @@
package com.java2nb.common.config;
/**
* @author 11797
*/
public interface CacheKey {
/**
* 首页小说设置
*/
String INDEX_BOOK_SETTINGS_KEY = "indexBookSettingsKey";
/**
* 首页新闻
*/
String INDEX_NEWS_KEY = "indexNewsKey";
/**
* 首页点击榜单
*/
String INDEX_CLICK_BANK_BOOK_KEY = "indexClickBankBookKey";
/**
* 首页友情链接
*/
String INDEX_LINK_KEY = "indexLinkKey";
/**
* 首页新书榜单
*/
String INDEX_NEW_BOOK_KEY = "indexNewBookKey";
/**
* 首页更新榜单
*/
String INDEX_UPDATE_BOOK_KEY = "indexUpdateBookKey";
/**
* 模板目录保存key
*/
String TEMPLATE_DIR_KEY = "templateDirKey";
;
/**
* 正在运行的爬虫线程存储KEY前缀
*/
String RUNNING_CRAWL_THREAD_KEY_PREFIX = "runningCrawlTreadDataKeyPrefix";
/**
* 上一次搜索引擎更新的时间
*/
String ES_LAST_UPDATE_TIME = "esLastUpdateTime";
/**
* 搜索引擎转换锁
*/
String ES_TRANS_LOCK = "esTransLock";
/**
* 上一次搜索引擎是否更新过小说点击量
*/
String ES_IS_UPDATE_VISIT = "esIsUpdateVisit";
/**
* 累积的小说点击量
*/
String BOOK_ADD_VISIT_COUNT = "bookAddVisitCount";
/**
* 测试爬虫规则缓存
*/
String BOOK_TEST_PARSE = "testParse";
}

View File

@ -1,6 +1,7 @@
package com.java2nb.common.config;
public class Constant {
//演示系统账户
public static String DEMO_ACCOUNT = "test";
//自动去除表前缀
@ -16,9 +17,11 @@ public class Constant {
//部门根节点id
public static Long DEPT_ROOT_ID = 0l;
//缓存方式
public static String CACHE_TYPE_REDIS ="redis";
public static String CACHE_TYPE_REDIS = "redis";
public static String LOG_ERROR = "error";
public static final String UPLOAD_FILES_PREFIX = "/files/";
}

View File

@ -1,132 +0,0 @@
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;
}
}

View File

@ -1,82 +0,0 @@
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;
}
}

View File

@ -5,11 +5,8 @@ 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;
@ -29,6 +26,7 @@ import java.util.LinkedHashMap;
*/
@Configuration
public class ShiroConfig {
@Value("${spring.redis.host}")
private String host;
@Value("${spring.redis.password}")
@ -38,9 +36,6 @@ public class ShiroConfig {
@Value("${spring.redis.timeout}")
private int timeout;
@Value("${spring.cache.type}")
private String cacheType ;
@Value("${server.session-timeout}")
private int tomcatTimeout;
@ -67,17 +62,17 @@ public class ShiroConfig {
shiroFilterFactoryBean.setSuccessUrl("/index");
shiroFilterFactoryBean.setUnauthorizedUrl("/403");
LinkedHashMap<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
filterChainDefinitionMap.put("/login","anon");
filterChainDefinitionMap.put("/getVerify","anon");
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("/favicon.ico", "anon");
filterChainDefinitionMap.put("/docs/**", "anon");
filterChainDefinitionMap.put("/layuimini/**", "anon");
filterChainDefinitionMap.put("/druid/**", "anon");
filterChainDefinitionMap.put("/upload/**", "anon");
filterChainDefinitionMap.put("/files/**", "anon");
filterChainDefinitionMap.put(Constant.UPLOAD_FILES_PREFIX + "**", "anon");
filterChainDefinitionMap.put("/logout", "logout");
filterChainDefinitionMap.put("/blog", "anon");
filterChainDefinitionMap.put("/blog/open/**", "anon");
@ -93,11 +88,7 @@ public class ShiroConfig {
//设置realm.
securityManager.setRealm(userRealm());
// 自定义缓存实现 使用redis
if (Constant.CACHE_TYPE_REDIS.equals(cacheType)) {
securityManager.setCacheManager(rediscacheManager());
} else {
securityManager.setCacheManager(ehCacheManager());
}
securityManager.setCacheManager(rediscacheManager());
securityManager.setSessionManager(sessionManager());
return securityManager;
}
@ -109,8 +100,7 @@ public class ShiroConfig {
}
/**
* 开启shiro aop注解支持.
* 使用代理方式;所以需要开启代码支持;
* 开启shiro aop注解支持. 使用代理方式;所以需要开启代码支持;
*
* @param securityManager
* @return
@ -139,8 +129,7 @@ public class ShiroConfig {
}
/**
* cacheManager 缓存 redis实现
* 使用的是shiro-redis开源插件
* cacheManager 缓存 redis实现 使用的是shiro-redis开源插件
*
* @return
*/
@ -152,8 +141,7 @@ public class ShiroConfig {
/**
* RedisSessionDAO shiro sessionDao层的实现 通过redis
* 使用的是shiro-redis开源插件
* RedisSessionDAO shiro sessionDao层的实现 通过redis 使用的是shiro-redis开源插件
*/
@Bean
public RedisSessionDAO redisSessionDAO() {
@ -164,11 +152,7 @@ public class ShiroConfig {
@Bean
public SessionDAO sessionDAO() {
if (Constant.CACHE_TYPE_REDIS.equals(cacheType)) {
return redisSessionDAO();
} else {
return new MemorySessionDAO();
}
return redisSessionDAO();
}
/**
@ -185,19 +169,4 @@ public class ShiroConfig {
return sessionManager;
}
@Bean
public EhCacheManager ehCacheManager() {
EhCacheManager em = new EhCacheManager();
em.setCacheManager(cacheManager());
return em;
}
@Bean("cacheManager2")
CacheManager cacheManager(){
return CacheManager.create();
}
}

View File

@ -1,48 +0,0 @@
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();
}
}

View File

@ -7,11 +7,14 @@ import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter
@Component
class WebConfigurer extends WebMvcConfigurerAdapter {
@Autowired
@Autowired
JnConfig jnConfig;
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/files/**").addResourceLocations("file:///"+ jnConfig.getUploadPath());
}
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler(Constant.UPLOAD_FILES_PREFIX + "**")
.addResourceLocations("file:///" + jnConfig.getUploadPath());
}
}

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