Compare commits

...

170 Commits
3.0 ... 4.0.10

Author SHA1 Message Date
zhaojun
27e8f7961e 🔖 发布 4.0.9 版本 2022-08-15 17:08:57 +08:00
zhaojun
55843cbef6 💄 更新前端页面 2022-08-15 16:35:17 +08:00
zhaojun
ebbb33409f 优化 OneDrive/SharePoint 获取 token 体验,增加信息显示,并优化页面效果。 2022-08-15 13:29:35 +08:00
zhaojun
b39360791f 🐛 修复因缓存未清理导致兼容 readme.md 功能修改无效的 bug 2022-08-15 13:28:35 +08:00
zhaojun
9833378e25 🐛 修复 SharePoint 世纪互联自定义 api 失败的 bug 2022-08-15 13:28:10 +08:00
zhaojun
31df2d16e2 🔖 发布 4.0.9 版本 2022-08-11 21:09:06 +08:00
zhaojun
f8f07912a1 🔨 规范代码 2022-08-11 21:06:40 +08:00
zhaojun
edf43954c6 兼容捐赠版数据文件功能 2022-08-11 21:06:16 +08:00
zhaojun
5a816b1dfb 增加 readme.md 兼容模式 2022-08-11 21:05:25 +08:00
zhaojun
910406c33a 增加最大同时上传数限制 2022-08-11 21:05:18 +08:00
zhaojun
543f76ad1d 增加 readme.md 兼容模式 2022-08-11 21:04:45 +08:00
zhaojun
1cc2d874a1 完善 OneDrive SharePoint 自定义 api 体验 2022-08-11 21:03:11 +08:00
zhaojun
18de372bf9 🐛 修复批量删除直链或直链下载日志数量过多时, 无法正常删除的问题。 2022-08-11 21:02:07 +08:00
zhaojun
5748644814 🐛 修复批量删除直链或直链下载日志数量过多时, 无法正常删除的问题。 2022-08-11 21:02:02 +08:00
zhaojun
fb8060d316 💄 更新前端页面 2022-08-11 21:01:41 +08:00
zhaojun
a4005defe2 更新 github issue 模板 2022-08-05 16:02:34 +08:00
zhaojun
4c90d5bdda 🔖 发布 4.0.8 版本 2022-08-05 15:30:13 +08:00
zhaojun
fa46850bb4 💄 更新前端页面 2022-08-05 15:29:08 +08:00
zhaojun
a7551fce53 完善代码结构 2022-08-05 15:28:52 +08:00
zhaojun
0591669ec9 增加获取单个文件接口请求参数 2022-08-05 15:28:33 +08:00
zhaojun
6286a9e9aa ✏️ 优化提示信息 2022-08-05 15:28:24 +08:00
zhaojun
c67ee1e89d 增加获取单个文件接口 2022-08-05 15:27:58 +08:00
zhaojun
c75695c63a 🐛 修复因类调用自身方法导致事务启用失败的 bug 2022-08-05 15:27:38 +08:00
zhaojun
8f771c652d ✏️ 优化 minio 提示信息 2022-08-05 15:25:52 +08:00
zhaojun
d6e13d6115 🐛 修复获取 m3u8 直链后系统报错的 bug. 2022-08-05 15:25:09 +08:00
zhaojun
8460d17b07 🔨 移动无用代码 2022-08-05 15:24:46 +08:00
zhaojun
49806221b4 💡 增加代码注释 2022-08-05 15:23:36 +08:00
zhaojun
409af8409d 🔨 重构代码,修改包名 2022-08-05 15:22:36 +08:00
zhaojun
6647efeb03 📝 完善 OneDrive SharePoint 反代域名参数的描述信息 2022-08-02 10:25:22 +08:00
zhaojun
c8bd52e26a 统一 sftp、ftp、webdav 下载文件 contentType 为 application/octet-stream, 避免浏览器自动进行默认预览动作 2022-08-01 15:20:06 +08:00
zhaojun
27db6ed14a 🐛 修复本地存储下载时,错误的 contentType 类型导致无法正常下载的问题 2022-08-01 15:17:29 +08:00
zhaojun
b079d03753 🔖 发布 4.0.7 版本 2022-07-31 15:07:11 +08:00
zhaojun
edf8e114ad 💄 更新前端页面 2022-07-31 15:06:55 +08:00
zhaojun
67a84edd4d 优化 S3 协议自动配置跨域逻辑,改为不覆盖原有配置。且增加 GET 跨域,对于在线预览文本、视频场景提供跨域支持. 2022-07-30 20:01:41 +08:00
zhaojun
d798750ee6 优化 S3 协议自动配置跨域逻辑,改为不覆盖原有配置,修改描述. 2022-07-30 20:00:18 +08:00
zhaojun
fea1da86fc 🐛 修复 minio 设置跨域上传报错的 bug 2022-07-30 18:45:19 +08:00
zhaojun
96a0c90600 ⬆️ 更新 pom 依赖,去除无用依赖,升级有漏洞的依赖,划分相关的依赖 2022-07-29 16:50:08 +08:00
赵俊
a054e82740 Merge pull request #404 from wswm152/main
解除对过期内容的引用
2022-07-29 16:19:08 +08:00
无始无名
dc0e84e1e3 解除对过期内容的引用
部分内容在jdk8以上版本中已被去除
2022-07-29 15:05:34 +08:00
zhaojun
ae31005959 🔖 发布 4.0.6 版本 2022-07-28 21:27:18 +08:00
zhaojun
0f167a304d 独立直链和短链功能 2022-07-28 21:24:38 +08:00
zhaojun
43d8143c74 💄 更新前端页面 2022-07-28 21:23:42 +08:00
zhaojun
b2fb1af99b 📝 修复本地存储文件路径描述,对于 docker 环境更容易理解。 2022-07-27 20:49:39 +08:00
zhaojun
a4f4d654a3 ✏️ 修改、完善判断隐藏文件夹方法的代码注释 2022-07-16 17:42:14 +08:00
zhaojun
04d9c24b43 📝 修改文档 docker-compose 错误部分 2022-07-15 22:52:13 +08:00
zhaojun
91a7092190 🔖 发布 4.0.5 版本 2022-07-15 20:50:35 +08:00
zhaojun
f82155f157 💄 更新前端页面 2022-07-15 20:45:29 +08:00
zhaojun
a99218dfa5 🐛 修复 4.0.4 版本更新导致的新增存储源错误的 bug, 其他版本不影响 2022-07-15 15:08:23 +08:00
zhaojun
3e9fe27890 🐛 修复本地存储,文件重命名,前后名称一致时,会无限创建子目录的 bug 2022-07-15 15:07:53 +08:00
zhaojun
7524f58928 💄 更新前端页面 2022-07-15 08:47:25 +08:00
zhaojun
6499f2d220 💄 更新前端页面 2022-07-15 08:47:11 +08:00
zhaojun
40b1f1bc2d 🔖 发布 4.0.4 版本 2022-07-14 20:28:58 +08:00
zhaojun
3bd859d705 ✏️ 删除无用代码 2022-07-14 15:03:59 +08:00
zhaojun
6156d85ba3 🐛 修复启动匿名操作失败的 BUG 2022-07-14 15:03:03 +08:00
zhaojun
e1df2f886b 🐛 修复 url 路径中带 . 访问 404 的 bug 2022-07-13 20:18:48 +08:00
zhaojun
cea42a57bb 🔖 发布 4.0.3 版本 2022-07-13 20:14:24 +08:00
zhaojun
c123d2a671 💄 更新前端页面 2022-07-13 20:13:12 +08:00
zhaojun
02e00b765b 💄 更新前端页面 2022-07-13 20:12:05 +08:00
zhaojun
1992c1f52d 📝 增加异常情况的提示信息 2022-07-13 20:11:50 +08:00
zhaojun
4eb9a721fc 🐛 修复本地存储、FTP、SFTP、WebDav 未启用私有空间,仍然校验私有签名的 bug 2022-07-13 20:10:08 +08:00
zhaojun
f1bac40af4 ✏️ 删除无用代码 2022-07-13 11:19:42 +08:00
zhaojun
0a7fb41e81 🐛 修复 readme 文档仅在首页显示的 bug. 2022-07-13 11:08:30 +08:00
zhaojun
4fd0b8d442 🐛 修复 s3 存储类型不开启私有空间时,文件路径或文件名包含中文无法直链下载的 bug 2022-07-13 11:08:05 +08:00
zhaojun
28150b0c1a 🐛 修复直链下载日志表中 ip 字段长度不足矣存储 ipv6 的 问题 2022-07-13 11:06:29 +08:00
zhaojun
a7813ff7bc 🔖 发布 4.0.2 版本 2022-07-12 19:52:56 +08:00
zhaojun
ae500ef9dc ⬇️ 移除无用依赖,减小项目体积 2022-07-12 19:52:40 +08:00
zhaojun
29d5b84df2 📝 更新文档, 更换图片预览的示例图 2022-07-12 19:49:11 +08:00
zhaojun
28882b198c 💄 更新前端页面 2022-07-12 19:48:42 +08:00
zhaojun
d624c886fe war 打包方式 ipv6 支持 2022-07-12 19:36:45 +08:00
zhaojun
e08654a59e Merge remote-tracking branch 'origin/main' 2022-07-12 19:34:53 +08:00
zhaojun
8fa6a5c9b8 💄 更新前端页面 2022-07-12 19:34:20 +08:00
zhaojun
7620a578fb 服务器代理上传支持特殊字符的文件名,如 # 2022-07-12 19:33:49 +08:00
赵俊
9c9bf93f00 Update README.md 2022-07-11 19:17:54 +08:00
赵俊
912eb694cb Update README.md 2022-07-11 19:11:08 +08:00
zhaojun
78d5ba90cf 💄 更新前端页面 2022-07-11 17:33:53 +08:00
zhaojun
056f9d4449 💄 更新前端页面 2022-07-11 17:33:37 +08:00
zhaojun
9a6020dcc8 增加文件点击习惯设置, 支持设置为单击还是双击 2022-07-11 17:29:15 +08:00
zhaojun
6b3025f379 fix(直链): 统一下载日志 storage_key 字段长度, 防止存储源长度过长后无法正常记录下载日志. 2022-07-11 14:57:30 +08:00
zhaojun
9dffaaee25 fix(异常处理): 存储源不存在时进行提示,修复后提示存储源不存在 2022-07-11 14:56:27 +08:00
zhaojun
bda654a012 fix: 修复管理员修改密码无效的 bug 2022-07-11 14:54:26 +08:00
zhaojun
52271b5117 fix: 修复目录文档某些情况无法匹配成功的 bug 2022-07-11 14:53:44 +08:00
zhaojun
223a6c1970 去除无用的存储类型枚举 2022-07-11 14:53:04 +08:00
zhaojun
60c272b714 修复 SharePoint 无法直链下载的 bug 2022-07-11 14:52:45 +08:00
zhaojun
3b6ed1c78d fix: 修改数据库和日志等文件默认路径为新版路径 2022-07-10 21:56:43 +08:00
zhaojun
5d888bb68f 🔖 发布 4.0.0 版本 2022-07-10 21:44:14 +08:00
zhaojun
082bb07213 fix: 修复 webdav 账号密码错误问题 2022-06-16 20:11:54 +08:00
zhaojun
803b8cdf71 🔖 发布 3.2.5 版本 2022-05-16 21:41:59 +08:00
zhaojun
eca5f7e48b feature: 新增挂载 webdav client pom 依赖 2022-05-16 21:41:36 +08:00
zhaojun
b70c37f3f0 feature: 新增挂载 webdav 功能 2022-05-16 21:40:58 +08:00
zhaojun
5cb2844141 🐛 修复错误的 content_disposition 和 contentType 导致下载文件格式被浏览器识别错误 2022-05-16 20:50:49 +08:00
赵俊
4dd6cdb4b3 合并拉取请求 #348
fix: modify extract driveId regex in WebDavController
2022-05-03 21:16:40 +08:00
quericy
c6127c029f fix: modify extract driveId regex in WebDavController 2022-04-14 10:06:46 +08:00
zhaojun
e149039ecb 🔖 发布 3.2.3 版本 2022-04-13 00:03:49 +08:00
zhaojun
37688d83cf feature: 降低 webdav 日志级别 2022-04-13 00:03:28 +08:00
zhaojun
6692016642 feature: 新增 webdav 开关功能 2022-04-13 00:01:59 +08:00
zhaojun
3f41aeda9a fix(bug): 修复因字段名称修改升级后导致短链异常 bug 2022-04-12 23:38:49 +08:00
赵俊
de86d5c47d 合并拉取请求 #347
feat: support webdav
2022-04-11 09:56:11 +08:00
quericy
c89e072005 feat: support webdav
1, feat:config webDav and milton in configuration;
2, feat:add event handler in WebDavController;
3, feat:check auth by admin in systemConfig;
4, feat:download webDav file by redirect to site DirectLink;
2022-04-10 04:11:34 +08:00
zhaojun
b533b5e959 🔖 发布 3.2.2 版本 2022-04-02 18:50:50 +08:00
zhaojun
d35cf27d47 fix(bug): ftp 默认为被动模式,防止因端口不同,无法读取。 2022-04-02 18:50:26 +08:00
zhaojun
796c4c1fb0 页面更新 2022-04-02 18:49:26 +08:00
zhaojun
1033d6c1a9 fix(bug): 修复某些情况下直链无法正常使用的 BUG 2022-04-02 18:36:44 +08:00
zhaojun
e09c6b4e58 fix(bug): 修复又拍云文件中包含特殊字符时,调用 upyun 接口未进行 url encode 返回 400,影响又拍云单文件直链无法使用。 2022-04-02 18:26:32 +08:00
zhaojun
168b0b08f3 fix(bug): 修复本地存储可以通过特殊路径符获取任意目录的 BUG. 2022-04-02 18:24:49 +08:00
zhaojun
60a6a5348c fix(bug): 修复获取音频信息时,因文件链接 302, 导致无法正常获取音频文件信息的 BUG. 2022-04-02 18:24:00 +08:00
zhaojun
2ec8a5df1f fix(bug): 修复 sharepoint 未自动刷新 accessToken 和 refreshToken 的 bug 2022-02-02 20:50:13 +08:00
zhaojun
47b5f6ac12 🔖 发布 3.2.1 版本 2022-02-02 20:46:45 +08:00
zhaojun
c64c8465f2 fix(bug): 升级相关有漏洞的依赖版本为最新版 2022-02-02 20:46:08 +08:00
zhaojun
f636681dd8 fix(bug): 修复本地存储可通过特殊命令访问到非指定目录的文件 2022-02-02 20:45:05 +08:00
赵俊
eadd2434e0 新增 ZFILE 社区地址 2021-10-30 21:05:11 +08:00
赵俊
b84c0bff42 Merge remote-tracking branch 'origin/master' 2021-10-07 17:53:19 +08:00
赵俊
4cb5b84bfe 🐛 修复 S3 协议无法正常保存的 BUG 2021-10-07 17:52:45 +08:00
赵俊
0351b4401c Merge pull request #286 from pippen57/master
转义SQL关键字, 防止创建表时出现错误
2021-09-25 18:29:42 +08:00
pippen
48cb14be8a 转义SQL关键字, 防止创建表时出现错误 2021-09-25 12:48:31 +08:00
赵俊
eea2ff11f9 ✏️ 修改文档拼写错误 2021-09-21 11:22:00 +08:00
赵俊
325ec1a348 对于因前端 vue history 路由模式下, 直接访问路径时, 出现的 404 响应码, 转化为 200 响应码. (404 下会将请求转发到首页) 2021-09-20 17:06:27 +08:00
赵俊
93205266d3 更新文档 2021-09-20 16:35:30 +08:00
赵俊
6849a4347f 去除自定义 404 错误页面 2021-09-20 16:33:54 +08:00
赵俊
cb5c6a5945 🎨 提交前端页面 2021-09-20 16:33:31 +08:00
赵俊
5ed45c3bb3 🔒 修复因升级 springboot 版本导致的安全和兼容问题 2021-09-20 16:20:25 +08:00
赵俊
4442ec3165 修复因前端 vue history 路由模式下, 直接访问路径时, 请求 /admin/ 下的路由会被权限框架拦截并校验登陆状态, 导致静态页面报错问题. 2021-09-20 16:19:21 +08:00
赵俊
b268a24333 修复因前端 vue history 路由模式下, 直接访问路径时, 接口和路径名冲突问题 2021-09-20 16:17:59 +08:00
赵俊
84f9354d4e 对于因前端 vue history 路由模式下, 直接访问路径时, 出现的 404 响应码, 转化为 200 响应码. (404 下会将请求转发到首页) 2021-09-20 16:17:16 +08:00
赵俊
8dfc4f8004 跨域请求过滤器修改为自注解注册方式 2021-09-20 16:14:45 +08:00
赵俊
1158f5c2b9 🐛 修复 OneDrive 加速域名在直链下未生效的 BUG 2021-09-20 11:18:13 +08:00
赵俊
c5f0e15207 🐛 修复因升级 spring boot 后部分参数过时, 导致的第一次启动无法初始化参数的 BUG 2021-09-19 21:33:07 +08:00
赵俊
68a842ce75 🐛 修复页面路径和接口地址冲突的 BUG 2021-09-19 16:08:19 +08:00
赵俊
3bd4f74dae 🔖 发布 3.2 版本 2021-09-19 15:37:40 +08:00
赵俊
4a0bdc3baf 💬 修改文档和启动日志描述,取消 /#/ 提示 2021-09-19 15:37:10 +08:00
赵俊
603c1b4654 🎨 提交前端页面 2021-09-19 15:36:19 +08:00
赵俊
1136d582df 增加异常处理器,细化异常提示 2021-09-19 14:10:09 +08:00
赵俊
187544fc06 当密码文件无法正常打开时,给予友好提示 2021-09-19 14:09:52 +08:00
赵俊
aa3cde8f59 minio 和 s3 存储引擎支持自定义 region 功能 2021-09-19 11:30:05 +08:00
赵俊
e29a702b6e ✏️ 拼写错误修改 2021-09-19 11:28:40 +08:00
赵俊
e4f663c9f0 🔒 新增自动检测驱动器已存储参数和驱动器支持所有参数比对功能, 防止驱动器新增参数后, 系统已存在的驱动器因 NPE 问题无法正常加载的问题. 2021-09-19 11:27:57 +08:00
赵俊
fb08ef6e78 🐛 如果请求的密码文件链接是 http 的, 且会自动跳转到 https 时, 密码文件无法正常加载的 BUG (原因是 restTemplate http -> https 不会自动重定向) 2021-09-19 10:01:24 +08:00
赵俊
10c465d159 ♻️ 修改 Spring Security 为 Sa-Token 框架. 2021-09-19 09:57:09 +08:00
赵俊
d15d1203b7 跨域配置 2021-09-19 09:56:12 +08:00
赵俊
de48ed3b61 兼容前端 history 模式, 对于 404 请求, 指向到 /index.html 页面 2021-09-19 09:54:23 +08:00
赵俊
d22e2e872a ⬆️ 因旧版本 Spring 的安全问题, 升级 Spring 为 2.5.4 版本, 兼容新版本 2021-09-19 09:53:19 +08:00
赵俊
7da1b454dc 🐛 修复非个人版的 OneDrive CF 加速域名无法正常使用的 BUG 2021-09-18 22:22:50 +08:00
赵俊
463f311dd3 增加本地文件下载/预览行为控制 2021-07-13 21:43:25 +08:00
赵俊
73b42cf654 🔖 发布 3.1 版本 2021-05-30 17:43:37 +08:00
赵俊
1fac59c4cd 🎨 更新静态页面 2021-05-30 17:41:46 +08:00
赵俊
6ed6b4a019 驱动器添加时,默认 ID 修改为 1 2021-05-30 17:40:48 +08:00
赵俊
7bd02437f0 数据库初始化参数增加默认值 2021-05-30 17:40:14 +08:00
赵俊
57aeb5771c 驱动器列表中返回是否已初始化信息 2021-05-30 17:39:40 +08:00
赵俊
695c03a530 Merge remote-tracking branch 'origin/master' 2021-05-30 16:24:58 +08:00
赵俊
6ebc403572 🔧 添加 ZFile Banner 文件 2021-05-30 16:24:28 +08:00
赵俊
7ff6fe43b5 新增自定义直链名称功能功能 2021-05-30 16:23:41 +08:00
赵俊
b34f141181 🔥 移除无用代码 2021-05-30 16:21:11 +08:00
赵俊
87dd7b58d1 🔥 移除无用代码 2021-05-30 16:19:11 +08:00
赵俊
2a949db5d2 m3u8 响应头兼容部分浏览器直接解析 m3u8 文件 2021-05-30 15:53:55 +08:00
赵俊
b889e91fb5 📝 更新文档,更新赞助信息位置 2021-05-14 21:15:54 +08:00
赵俊
b5c757f9f0 📝 更新文档,更新赞助信息位置 2021-04-21 21:04:02 +08:00
赵俊
a465f48b94 📝 更新文档,增加项目 LOGO,修改项目描述信息。 2021-04-21 20:23:54 +08:00
赵俊
797a0a0e4c 新增直链和短链是否显示功能 2021-04-21 20:21:47 +08:00
赵俊
e7ff159b6d 🐛 修复某些下载地址带密钥的存储策略,m3u8 视频无法正常播放的功能 2021-04-11 19:15:50 +08:00
赵俊
a9fbf54bb2 🔊 完善日志输出 2021-04-11 16:02:49 +08:00
赵俊
81f9e262f5 增加获取站点域名方法 2021-04-11 16:00:01 +08:00
赵俊
23bb3960ab 已关闭的驱动器不允许下载 2021-04-11 15:56:08 +08:00
赵俊
c4a17985a4 优化下载地址获取逻辑,直接列表时不直接调用 API 获取下载地址,访问单文件时再调用。 2021-04-11 15:49:33 +08:00
赵俊
75ddcd47f4 :zip: 优化存储器保存逻辑,防止新增加的字段无法正常保存的 BUG。 2021-04-10 20:21:19 +08:00
赵俊
2dd03ae490 🐛 修复 FTP 模式在 Linux 环境下无法正常读取的 BUG 2021-04-10 20:20:03 +08:00
赵俊
5b383c8741 🐛 日志文件无法正常下载功能修复 2021-04-10 20:19:26 +08:00
赵俊
73198d7852 优化本地文件下载功能, 支持断点续传和多线程下载 2021-04-10 18:06:10 +08:00
赵俊
fb0d9721aa OneDrive 和 SharePoint 反代功能 2021-04-10 15:38:16 +08:00
赵俊
b24c663fd6 更新 star 趋势链接 2021-03-27 12:01:37 +08:00
zhaojun1998
6e62cfc84d 📝 更新文档,修改赞助二维码,增加服务器赞助商链接 2021-03-27 11:52:59 +08:00
zhaojun1998
eee22e9dc9 📝 更新文档 2021-03-26 18:24:02 +08:00
701 changed files with 18786 additions and 7717 deletions

View File

@@ -6,43 +6,19 @@ labels: 'bug'
assignees: ''
---
<!--
你好!感谢你正在考虑为 ZFile 提交一个 bug。请花一点点时间尽量详细地回答以下基础问题。
为了帮助我们更好的解决您的问题,请填写以下选项(不填写完整可能会被直接关闭 issue
谢谢!
-->
<!--
请确认你已经做了下面这些事情,若 bug 还是未解决,那么请尽可详细地描述你的问题。
- 我已经安装了最新版的 ZFile
- 我已经阅读了 ZFile 的文档http://docs.zhaojun.im/zfile
- 我已经搜索了已有的 Issues 列表中有关的信息
- 我已经清理过浏览器缓存并重试
-->
## 我的环境
<!--
请登录到管理后台,点击左侧系统监控, 复制或截图此页内容.
-->
## 错误日志
<!--
请登录到管理后台,点击左侧系统监控, 点击右上角诊断日志下载, 然后上传到此 Issue 中.
-->
## 期望行为
<!--
你期望会发生什么?
-->
## 当前行为
<!--
描述 bug 细节,确认出现此问题的复现步骤,例如点击了哪里,发生了什么情况?
你可以粘贴截图或附件。
-->
- 是否已搜索其他 issue没有人提过这个问题
- 当前 ZFile 版本:
- 是否尝试最新版是否已解决此问题:
- 是否尝试重启 ZFile且问题依旧存在
- 是否已尝试清空浏览器缓存,且问题依旧存在?:
- 操作系统(如 Windows、Mac、iOS、安卓
- 浏览器(如 Chrome、Firefox、SafariX 浏览器):
- 做什么操作提示的错误?:
- 期望行为(应该是什么样的结果):
- 当前行为(当前是什么样的结果):
- 错误日志(可选):
- 复现步骤(可选):
- 您的额外信息(可选):

View File

@@ -7,28 +7,11 @@ assignees: ''
---
<!--
你好!感谢你愿意考虑希望 ZFile 增加某个新功能。请花一点点时间尽量详细地回答以下基础问题。
谢谢!
-->
为了帮助我们更好的解决您的问题,请填写以下选项(不填写完整可能会被直接关闭 issue
## 概述
<!--
对这个新功能的一段描述
-->
## 动机
<!--
为什么你希望在 ZFile 中使用这个功能?
-->
## 详细解释
<!--
详细描述这个新功能。
如果这是一个小功能,你可以忽略这部分。
-->
- 是否已搜索其他 issue没有人提过这个功能
- 是否已尝试使用最新版本,且仍然没有此功能?:
- 功能概述:
- 功能动机:
- 详细解释(可选):

View File

@@ -1,14 +0,0 @@
---
name: Question
about: 对 ZFile 有任何问题吗?
title: ''
labels: 'question'
assignees: ''
---
<!--
如果你有任何问题也可以通过此渠道来向我们反馈。
谢谢!
-->

15
.gitignore vendored
View File

@@ -1,11 +1,8 @@
HELP.md
target/
.mvn/wrapper/**
!**/src/main/**
**/src/test/**
mvnw
mvnw.cmd
!.mvn/wrapper/maven-wrapper.jar
!**/src/main/**/target/
!**/src/test/**/target/
### STS ###
.apt_generated
@@ -29,6 +26,12 @@ mvnw.cmd
/nbdist/
/.nb-gradle/
build/
!**/src/main/**/build/
!**/src/test/**/build/
### VS Code ###
.vscode/
/.mvn/wrapper/
/mvnw
/mvnw.cmd
/.script/

181
API.md
View File

@@ -1,181 +0,0 @@
## API 标准
所有 API 均返回 `msg`, `code`, `data` 三个属性.
| code | 描述 |
| :---: | :------------: |
| 0 | 请求成功 |
| -1 | 请求失败 |
| -2 | 文件夹需要密码 |
`code == 0` 时, `data` 中为请求所需数据.
`code != 0` 时, 应当将 `msg` 中的内容作为参考值.
## 驱动器列表
### 请求 URL
`/api/drive/list` `GET`
### 响应
```json
{
"msg": "操作成功",
"code": 0,
"data": [
{
"id": 3, --- ID 是驱动器 ID, 用来唯一区分驱动器
"name": "演示 A 盘", --- 驱动器名称
"enableCache": true, --- 是否开启了缓存
"autoRefreshCache": false, --- 是否开启了缓存自动刷新
"type": { --- 存储源类型
"key": "upyun",
"description": "又拍云 USS"
},
"searchEnable": false, --- 是否开启搜索
"searchIgnoreCase": false, --- 搜索是否忽略大小写
"searchContainEncryptedFile": false --- 搜索是否包含加密文件夹
}
]
}
```
## 获取文件列表
### 请求 URL
`/api/list/{driveId}` `GET`
### URL 参数
| 参数名 | 描述 | 是否必填 | 参考值 |
| :-----: | :-------------------: | :------: | :------------------------------------: |
| driveId | 驱动器 ID | 是 | 参考 `获取驱动器列表` 接口返回的 id 值 |
### 请求参数
| 参数名 | 描述 | 是否必填 | 参考值 |
| :------: | :--------: | :------: | :--------------------------: |
| path | 路径 | 是 | `/`, `/文件夹名称` |
| password | 文件夹密码 | 否 | 当文件夹需要密码时, |
| page | 页数 | 否 | 默认取第一页, 每页固定 30 条 |
### 响应
```json
{
"msg": "操作成功",
"code": 0,
"data": [
{
"name": "密码文件夹",
"time": "2020-01-28 13:17",
"size": 4096,
"type": "FOLDER",
"path": "/",
"url": null
},
{
"name": "新建 文本文档.txt",
"time": "2020-01-28 13:16",
"size": 3,
"type": "FILE",
"path": "/",
"url": "http://127.0.0.1:8080/file/新建 文本文档.txt"
}
]
}
```
## 获取单个文件信息
### 请求 URL
`/api/directlink/{driveId}` `GET`
### URL 参数
| 参数名 | 描述 | 是否必填 | 参考值 |
| :-----: | :-------------------: | :------: | :------------------------------------: |
| driveId | 驱动器 ID | 是 | 参考 `获取驱动器列表` 接口返回的 id 值 |
### 参数
| 参数名 | 描述 | 是否必填 | 参考值 |
| :----: | :--------: | :------: | :------------------: |
| path | 文件全路径 | 是 | `/新建 文本文档.txt` |
### 响应
```json
{
"msg": "操作成功",
"code": 0,
"data": {
"name": "新建 文本文档.txt",
"time": "2020-01-28 13:16",
"size": 3,
"type": "FILE",
"path": "d:/test",
"url": "http://127.0.0.1:8080/file/新建 文本文档.txt"
}
}
```
## 获取系统配置
### 请求 URL
`/api/config/{driveId}` `GET`
### URL 参数
| 参数名 | 描述 | 是否必填 | 参考值 |
| :-----: | :-------------------: | :------: | :------------------------------------: |
| driveId | 驱动器 ID | 是 | 参考 `获取驱动器列表` 接口返回的 id 值 |
### 参数
| 参数名 | 描述 | 是否必填 | 参考值 |
| :----: | :--------: | :------: | :-----------: |
| path | 文件夹名称 | 是 | `/文件夹名称` |
### 响应
```json
{
"msg": "操作成功",
"code": 0,
"data": {
"siteName": "ZFile 演示站",
"searchEnable": false,
"username": "zhao",
"domain": "https://zfile.jun6.net",
"customJs": "",
"customCss": "",
"tableSize": "small",
"showOperator": true,
"showDocument": true,
"announcement": "本站是 ZFile 演示站,交流反馈群 180605017",
"showAnnouncement": true,
"layout": "full",
"readme": null
}
}
```

233
README.md
View File

@@ -1,38 +1,66 @@
# Z-File
<p style="text-align: center">
<img alt="ZFile" src="https://cdn.jun6.net/2021/04/21/69a89344e2a84.png" height="150px">
<br><br>
基于 Java 的在线网盘程序,支持对接 S3、OneDrive、SharePoint、又拍云、本地存储、FTP、SFTP 等存储源,支持在线浏览图片、播放音视频,文本文件等文件类型。
<br><br>
<img src="https://img.shields.io/badge/license-MIT-blue.svg?longCache=true&style=flat-square" alt="license">
<img src="https://api.codacy.com/project/badge/Grade/70b793267f7941d58cbd93f50c9a8e0a" alt="codady">
<img src="https://img.shields.io/github/last-commit/zhaojun1998/zfile.svg?style=flat-square" alt="last commit">
<img src="https://img.shields.io/github/downloads/zhaojun1998/zfile/total?style=flat-square" alt="downloads">
<img src="https://img.shields.io/github/v/release/zhaojun1998/zfile?style=flat-square" alt="release">
<img src="https://img.shields.io/github/commit-activity/y/zhaojun1998/zfile?style=flat-square" alt="commit activity">
<br>
<img src="https://img.shields.io/github/issues/zhaojun1998/zfile?style=flat-square" alt="issues">
<img src="https://img.shields.io/github/issues-closed-raw/zhaojun1998/zfile?style=flat-square" alt="closed issues">
<img src="https://img.shields.io/github/forks/zhaojun1998/zfile?style=flat-square" alt="forks">
<img src="https://img.shields.io/github/stars/zhaojun1998/zfile?style=flat-square" alt="stars">
<img src="https://img.shields.io/github/watchers/zhaojun1998/zfile?style=flat-square" alt="watchers">
</p>
![https://img.shields.io/badge/license-MIT-blue.svg?style=flat-square](https://img.shields.io/badge/license-MIT-blue.svg?longCache=true&style=flat-square)
[![Codacy Badge](https://api.codacy.com/project/badge/Grade/70b793267f7941d58cbd93f50c9a8e0a)](https://www.codacy.com/manual/zhaojun1998/zfile?utm_source=github.com&amp;utm_medium=referral&amp;utm_content=zhaojun1998/zfile&amp;utm_campaign=Badge_Grade)
![https://img.shields.io/badge/springboot-2.0.6-orange.svg?style=flat-square](https://img.shields.io/badge/springboot-2.0.6-yellow.svg?longCache=true&style=popout-square)
![GitHub tag (latest SemVer)](https://img.shields.io/github/tag/zhaojun1998/zfile.svg?style=flat-square)
## 相关地址
此项目是一个在线文件目录的程序, 支持各种对象存储和本地存储, 使用定位是个人放常用工具下载, 或做公共的文件库. 不会向多账户方向开发.
预览地址: [https://zfile.vip](https://zfile.vip)
前端基于 [h5ai](https://larsjung.de/h5ai/) 的原有功能使用 Vue 重新开发了一遍. 后端采用 SpringBoot, 数据库采用内嵌数据库.
文档地址: [https://docs.zfile.vip](https://docs.zfile.vip)
预览地址: [https://zfile.jun6.net](https://zfile.jun6.net)
社区地址: [https://bbs.zfile.vip](https://bbs.zfile.vip)
文档地址: [http://docs.zhaojun.im/zfile](http://docs.zhaojun.im/zfile)
项目源码: [https://github.com/zhaojun1998/zfile](https://github.com/zhaojun1998/zfile)
前端源码: [https://github.com/zhaojun1998/zfile-vue](https://github.com/zhaojun1998/zfile-vue)
## 系统特色
* 内存缓存 (免安装)
* 内存数据库 (免安装)
* 个性化配置
* 自定义目录的 readme 说明文件
* 支持文件操作:上传, 删除, 重命名, 新建文件夹. 后续还会支持移动和复制文件(详见下方**后续计划**.
* 操作系统级的文件操作体验
1. 支持拖拽上传和 Ctrl + V 粘贴上传文件和文件夹
2. 支持 Ctrl + A 全选文件, 按 Esc 取消全选.
3. 支持拖拽批量选择文件
4. 支持按住 Shift 多选文件
5. 支持多选文件后按 Delete 键删除文件.
6. 按 Backspace 返回上级文件夹.
* 全新的 UI 风格, 更简洁易用.
* 支持给文件生成直链(短链,永久直链,二维码)
* 视频播放器支持调用本地软件进行下载如迅雷、Motrix. 支持调用本地播放器播放,更好的进行视频解码: PotPlayer IINA, VLC, nPlayer, MXPlayer(Free/Pro)
* 全新画廊模式, 支持按照瀑布流显示图片, 支持自定义 N 栏, 自定义每栏的间距
* 支持给文件夹配置 markdown 文档, 并配置显示方式, 如顶部、底部、弹窗
* 支持给文件夹设置密码
* 支持隐藏文件或文件夹
* 后台登录支持设置图片验证码和 2FA 身份认证,防止后台被暴力破解
* 支持自定义文件格式后缀, 避免系统内置的不完善导致文件无法预览.
* Docker 支持
* 自定义 JS, CSS
* 文件夹密码
* 支持在线浏览文本文件, 视频, 图片, 音乐. (支持 FLV 和 HLS)
* 文件/目录二维码
* 缓存动态开启, ~~缓存自动刷新 (v2.2 及以前版本支持)~~
* ~~全局搜索 (v2.2 及以前版本支持)~~
* 同时挂载多个存储策略
* 支持 阿里云 OSS, FTP, 华为云 OBS, 本地存储, MINIO, OneDrive 国际/家庭/个人版, OneDrive 世纪互联版, 七牛云 KODO, 腾讯云 COS, 又拍云 USS.
* 支持 S3 协议, 阿里云 OSS, FTP, SFTP, 华为云 OBS, 本地存储, MINIO, OneDrive 国际/家庭/个人版/世纪互联版/SharePoint, , 七牛云 KODO, 腾讯云 COS, 又拍云 USS.
## 快速开始
<details>
<summary>普通安装 (点击展开)</summary>
安装依赖环境:
```bash
# CentOS系统
yum install -y java-1.8.0-openjdk unzip
```
@@ -52,29 +80,14 @@ apt update && apt install -y adoptopenjdk-8-hotspot-jre
```
> 如为更新程序, 则请先执行 `~/zfile/bin/stop.sh && rm -rf ~/zfile` 清理旧程序. 首次安装请忽略此选项.
下载项目:
```bash
cd ~
export ZFILE_INSTALL_PATH=~/zfile
mkdir -p $ZFILE_INSTALL_PATH && cd $ZFILE_INSTALL_PATH
wget https://c.jun6.net/ZFILE/zfile-release.war
mkdir zfile && unzip zfile-release.war -d zfile && rm -rf zfile-release.war
chmod +x zfile/bin/*.sh
```
> 下载指定版本可以将 `zfile-release.war` 改为 `zfile-x.x.war`,如 `zfile-2.2.war`。
程序的目录结构为:
```
├── zfile
├── META-INF
├── WEB-INF
└── bin
├── start.sh # 启动脚本
└── stop.sh # 停止脚本
├── restart.sh # 重启脚本
unzip zfile-release.war && rm -rf zfile-release.war
chmod +x $ZFILE_INSTALL_PATH/bin/*.sh
```
启动项目:
@@ -83,60 +96,118 @@ chmod +x zfile/bin/*.sh
~/zfile/bin/start.sh
```
篇幅有限, 更详细的安装教程及介绍请参考: [ZFile 文档](http://docs.zhaojun.im/zfile)
访问地址:
</details>
用户前台: http://127.0.0.1:8080/#/main
---
初始安装: http://127.0.0.1:8080/#/install
<details>
<summary>Docker (点击展开)</summary>
管理后台: http://127.0.0.1:8080/#/admin
```bash
docker run -d --name=zfile --restart=always \
-p 8080:8080 \
-v /root/zfile/db:/root/.zfile-v4/db \
-v /root/zfile/logs:/root/.zfile-v4/logs \
zhaojun1998/zfile
```
> 如需映射配置文件则需要先在宿主机下载配置文件,然后映射到容器内:
```bash
# 下载到 application.properties 文件到 /root 目录下, 此目录可自行更改, 如:
curl -o /root/application.properties https://c.jun6.net/ZFILE/application.properties
# 然后增加一个 -v 参数,将此源文件映射到容器内(如修改宿主机的 application.properties 为其他路径, 则下面命令也要一起修改),如:
docker run -d --name=zfile --restart=always \
-p 8080:8080 \
-v /root/zfile/db:/root/.zfile-v4/db \
-v /root/zfile/logs:/root/.zfile-v4/logs \
-v /root/application.properties:/root/application.properties \
zhaojun1998/zfile
```
</details>
---
<details>
<summary>Docker Compose (点击展开)</summary>
```yml
version: '3.3'
services:
zfile:
container_name: zfile
restart: always
ports:
- '8080:8080'
volumes:
- '/root/zfile/db:/root/.zfile-v4/db'
- '/root/zfile/logs:/root/.zfile-v4/logs'
image: zhaojun1998/zfile
```
> 如需映射配置文件则需要先在宿主机下载配置文件,然后映射到容器内:
下载到 application.properties 文件到 /root 目录下, 此目录可自行更改, 命令如:
```bash
curl -o /root/application.properties https://c.jun6.net/ZFILE/application.properties
```
> 然后增加一个 -v 参数,将此源文件映射到容器内(如修改宿主机的 application.properties 为其他路径, 则下面命令也要一起修改), 如:
```yml
version: '3.3'
services:
zfile:
container_name: zfile
restart: always
ports:
- '8080:8080'
volumes:
- '/root/zfile/db:/root/.zfile-v4/db'
- '/root/zfile/logs:/root/.zfile-v4/logs'
- '/root/application.properties:/root/application.properties'
image: zhaojun1998/zfile
```
</details>
---
篇幅有限, 更详细的安装教程及介绍请参考: [ZFile 文档](https://docs.zfile.vip)
## 预览
![前台首页](https://cdn.jun6.net/2020/04/19/d590d2bde13bb.png)
![后台设置-驱动器设置](https://cdn.jun6.net/2020/04/19/d58fc2debcce8.png)
![后台设置-驱动器设置](https://cdn.jun6.net/2020/04/19/0f321e47fc18c.png)
![后台设置-显示设置](https://cdn.jun6.net/2020/04/19/6d7c300b89671.png)
![前台首页](https://cdn.jun6.net/uPic/2022/07/11/eJU1B5.png)
![前台设置](https://cdn.jun6.net/uPic/2022/07/11/Y0fK7b.png)
![图片预览](https://cdn.jun6.net/uPic/2022/07/12/BP8wog.png)
![视频预览](https://cdn.jun6.net/uPic/2022/07/11/MsubMr.png)
![文本预览](https://cdn.jun6.net/2021/03/23/b00efdfb4892e.png)
![音频预览](https://cdn.jun6.net/uPic/2022/07/11/7U5IoK.png)
![管理登录](https://cdn.jun6.net/uPic/2022/07/11/U2XKcg.png)
![后台设置-站点设置](https://cdn.jun6.net/uPic/2022/07/11/9zsedD.png)
![后台设置-驱动器列表](https://cdn.jun6.net/uPic/2022/07/11/y2pFa1.png)
![后台设置-新增驱动器](https://cdn.jun6.net/uPic/2022/07/11/I1NWzF.png)
## 常见问题
### 默认路径
默认 H2 数据库文件地址: `~/.zfile/db/`, `~` 表示用户目录
windows 为 `C:/Users/用户名/`
linux 为 `/home/用户名/`, root 用户为 `/root/`
> 2.3 及以后版本路径为 `~/.zfile-new/db/`
### 文档文件和加密文件
- 目录文档显示文件名为 `readme.md`
- 目录需要密码访问, 添加文件 `password.txt` (无法拦截此文件被下载, 但可以改名文件)
## 开发计划
- [x] API 支持 [点击查看文档](https://github.com/zhaojun1998/zfile/blob/master/API.md)
- [x] 更方便的部署方式
- [x] 布局优化 - 自定义操作按钮 (现为右键实现)
- [x] 后台优化 - 设置按照其功能进行分离
- [x] 体验优化 - 支持前后端分离部署
- [x] 体验优化 - 文本预览更换 vscode 同款编辑器 monaco editor
- [x] 新功能 - Docker 支持
- [x] 架构调整 - 支持多存储策略
- [x] 体验优化 - 忽略文件列表 (正则表达式)
- [ ] 新功能 - 后台支持上传、编辑、删除等操作
- [ ] 体验优化 - 自定义支持预览的文件后缀 (正则表达式)
- [ ] 体验优化 - 一键安装脚本
## 支持作者
如果本项目对你有帮助,请作者喝杯咖啡吧。
<img src="http://cdn.jun6.net/alipay.png" width="200" height="312">
<img src="http://cdn.jun6.net/wechat.png" width="222" height="300">
<img src="https://cdn.jun6.net/2021/03/27/152704e91f13d.png" width="400" alt="赞助我">
## Stargazers over time
[![starcharts stargazers over time](https://starchart.cc/zhaojun1998/zfile.svg)](https://starchart.cc/zhaojun1998/zfile.svg)
## 开发工具赞助
<a href="https://www.jetbrains.com/?from=zfile"><img src="https://cdn.jun6.net/2021/04/21/26e410d60b0b0.png?1=1" width="100px"></a>

202
pom.xml
View File

@@ -1,28 +1,27 @@
<?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">
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.6.RELEASE</version>
<relativePath/>
<version>2.6.8</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>im.zhaojun</groupId>
<artifactId>zfile</artifactId>
<version>3.0</version>
<version>4.0.10</version>
<name>zfile</name>
<packaging>war</packaging>
<description>一个在线的文件浏览系统</description>
<properties>
<java.version>1.8</java.version>
<org.mapstruct.version>1.5.1.Final</org.mapstruct.version>
</properties>
<dependencies>
<!-- spring boot 官方相关 -->
<dependency>
<groupId>org.springframework.boot</groupId>
@@ -32,14 +31,6 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
@@ -49,32 +40,40 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<!-- 数据库驱动-->
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<!-- 数据库相关 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.29</version>
<scope>runtime</scope>
</dependency>
<!-- 工具类 -->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.1.3</version>
<groupId>org.xerial</groupId>
<artifactId>sqlite-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-core</artifactId>
<version>7.15.0</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.2</version>
</dependency>
<!-- 存储策略相关 API, 对象存储、FTP、 Rest API-->
<!-- 存储策略相关 SDK、 工具类-->
<dependency>
<groupId>com.upyun</groupId>
<artifactId>java-sdk</artifactId>
@@ -83,36 +82,110 @@
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk-s3</artifactId>
<version>1.11.699</version>
<version>1.12.261</version>
</dependency>
<dependency>
<groupId>com.qiniu</groupId>
<artifactId>qiniu-java-sdk</artifactId>
<version>7.11.0</version>
</dependency>
<dependency>
<groupId>com.jcraft</groupId>
<artifactId>jsch</artifactId>
<version>0.1.55</version>
</dependency>
<dependency>
<groupId>com.github.lookfirst</groupId>
<artifactId>sardine</artifactId>
<version>5.10</version>
</dependency>
<!-- 登陆/权限相关 -->
<dependency>
<groupId>cn.dev33</groupId>
<artifactId>sa-token-spring-boot-starter</artifactId>
<version>1.30.0</version>
</dependency>
<!-- 文档相关 -->
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-spring-boot-starter</artifactId>
<version>3.0.3</version>
</dependency>
<!-- 工具类 -->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.3</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.24</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.8</version>
</dependency>
<dependency>
<groupId>commons-net</groupId>
<artifactId>commons-net</artifactId>
<version>3.6</version>
<version>3.8.0</version>
</dependency>
<!-- 其他工具类 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
</dependency>
<dependency>
<groupId>com.mpatric</groupId>
<artifactId>mp3agic</artifactId>
<version>0.9.1</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.61</version>
<version>1.2.83</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>30.1.1-jre</version>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
<version>${org.mapstruct.version}</version>
</dependency>
<dependency>
<groupId>commons-chain</groupId>
<artifactId>commons-chain</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>dev.samstevens.totp</groupId>
<artifactId>totp-spring-boot-starter</artifactId>
<version>1.7.1</version>
</dependency>
<dependency>
<groupId>com.beust</groupId>
<artifactId>jcommander</artifactId>
<version>1.82</version>
</dependency>
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20200518</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpmime</artifactId>
<version>4.5.13</version>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
<version>1.70</version>
</dependency>
</dependencies>
@@ -122,6 +195,44 @@
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
<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>
<annotationProcessorPaths>
<path>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>${org.mapstruct.version}</version>
</path>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.16</version>
</path>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok-mapstruct-binding</artifactId>
<version>0.2.0</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
<plugin>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>com.uyoqu.framework</groupId>
@@ -139,10 +250,13 @@
<jvms>
<jvm>-Djava.security.egd=file:/dev/./urandom</jvm>
<jvm>-Dfile.encoding=utf-8</jvm>
<jvm>-Djava.net.preferIPv4Stack=false</jvm>
<jvm>-Djava.net.preferIPv4Addresses=true</jvm>
</jvms>
</configuration>
</plugin>
</plugins>
</build>
</project>
</build>
</project>

View File

@@ -0,0 +1,173 @@
/*
* Copyright (c) 2011-2022, baomidou (jobob@qq.com).
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.baomidou.mybatisplus.core.handlers;
import com.baomidou.mybatisplus.annotation.EnumValue;
import com.baomidou.mybatisplus.annotation.IEnum;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.ExceptionUtils;
import com.baomidou.mybatisplus.core.toolkit.ReflectionKit;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import org.apache.ibatis.reflection.DefaultReflectorFactory;
import org.apache.ibatis.reflection.MetaClass;
import org.apache.ibatis.reflection.ReflectorFactory;
import org.apache.ibatis.reflection.invoker.Invoker;
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Arrays;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;
/**
* 自定义枚举属性转换器
*
* @author hubin
* @since 2017-10-11
*/
public class MybatisEnumTypeHandler<E extends Enum<E>> extends BaseTypeHandler<E> {
private static final Map<String, String> TABLE_METHOD_OF_ENUM_TYPES = new ConcurrentHashMap<>();
private static final ReflectorFactory REFLECTOR_FACTORY = new DefaultReflectorFactory();
private final Class<E> enumClassType;
private final Class<?> propertyType;
private final Invoker getInvoker;
public MybatisEnumTypeHandler(Class<E> enumClassType) {
if (enumClassType == null) {
throw new IllegalArgumentException("Type argument cannot be null");
}
this.enumClassType = enumClassType;
MetaClass metaClass = MetaClass.forClass(enumClassType, REFLECTOR_FACTORY);
String name = "value";
if (!IEnum.class.isAssignableFrom(enumClassType)) {
name = findEnumValueFieldName(this.enumClassType).orElseThrow(() -> new IllegalArgumentException(String.format("Could not find @EnumValue in Class: %s.", this.enumClassType.getName())));
}
this.propertyType = ReflectionKit.resolvePrimitiveIfNecessary(metaClass.getGetterType(name));
this.getInvoker = metaClass.getGetInvoker(name);
}
/**
* 查找标记标记EnumValue字段
*
* @param clazz class
* @return EnumValue字段
* @since 3.3.1
*/
public static Optional<String> findEnumValueFieldName(Class<?> clazz) {
if (clazz != null && clazz.isEnum()) {
String className = clazz.getName();
return Optional.ofNullable(CollectionUtils.computeIfAbsent(TABLE_METHOD_OF_ENUM_TYPES, className, key -> {
Optional<Field> fieldOptional = findEnumValueAnnotationField(clazz);
return fieldOptional.map(Field::getName).orElse(null);
}));
}
return Optional.empty();
}
private static Optional<Field> findEnumValueAnnotationField(Class<?> clazz) {
return Arrays.stream(clazz.getDeclaredFields()).filter(field -> field.isAnnotationPresent(EnumValue.class)).findFirst();
}
/**
* 判断是否为MP枚举处理
*
* @param clazz class
* @return 是否为MP枚举处理
* @since 3.3.1
*/
public static boolean isMpEnums(Class<?> clazz) {
return clazz != null && clazz.isEnum() && (IEnum.class.isAssignableFrom(clazz) || findEnumValueFieldName(clazz).isPresent());
}
@SuppressWarnings("Duplicates")
@Override
public void setNonNullParameter(PreparedStatement ps, int i, E parameter, JdbcType jdbcType)
throws SQLException {
if (jdbcType == null) {
ps.setObject(i, this.getValue(parameter));
} else {
// see r3589
ps.setObject(i, this.getValue(parameter), jdbcType.TYPE_CODE);
}
}
@Override
public E getNullableResult(ResultSet rs, String columnName) throws SQLException {
Object value = rs.getObject(columnName);
if (null == value && rs.wasNull()) {
return null;
}
return this.valueOf(value);
}
@Override
public E getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
Object value = rs.getObject(columnIndex, this.propertyType);
if (null == value && rs.wasNull()) {
return null;
}
return this.valueOf(value);
}
@Override
public E getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
Object value = cs.getObject(columnIndex, this.propertyType);
if (null == value && cs.wasNull()) {
return null;
}
return this.valueOf(value);
}
private E valueOf(Object value) {
E[] es = this.enumClassType.getEnumConstants();
return Arrays.stream(es).filter((e) -> equalsValue(value, getValue(e))).findAny().orElse(null);
}
/**
* 值比较
*
* @param sourceValue 数据库字段值
* @param targetValue 当前枚举属性值
* @return 是否匹配
* @since 3.3.0
*/
protected boolean equalsValue(Object sourceValue, Object targetValue) {
String sValue = StringUtils.toStringTrim(sourceValue);
String tValue = StringUtils.toStringTrim(targetValue);
if (sourceValue instanceof Number && targetValue instanceof Number
&& new BigDecimal(sValue).compareTo(new BigDecimal(tValue)) == 0) {
return true;
}
return Objects.equals(sValue, tValue);
}
private Object getValue(Object object) {
try {
return this.getInvoker.invoke(object, new Object[0]);
} catch (ReflectiveOperationException e) {
throw ExceptionUtils.mpe(e);
}
}
}

View File

@@ -1,20 +1,43 @@
package im.zhaojun.zfile;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.scheduling.annotation.EnableAsync;
/**
* @author zhaojun
*/
@EnableAsync
import javax.annotation.PostConstruct;
@SpringBootApplication
@EnableAspectJAutoProxy(exposeProxy = true)
@EnableAspectJAutoProxy(exposeProxy = true, proxyTargetClass = true)
@ServletComponentScan(basePackages = "im.zhaojun.zfile.*.filter")
@ComponentScan(basePackages = "im.zhaojun.zfile.*")
public class ZfileApplication {
public static void main(String[] args) {
SpringApplication.run(ZfileApplication.class, args);
}
}
@Value("${spring.datasource.driver-class-name}")
private String datasourceDriveClassName;
@Value("${spring.datasource.url}")
private String datasourceUrl;
@PostConstruct
public void init() {
if (StrUtil.equals(datasourceDriveClassName, "org.sqlite.JDBC")) {
String path = datasourceUrl.replace("jdbc:sqlite:", "");
String folderPath = FileUtil.getParent(path, 1);
if (!FileUtil.exist(folderPath)) {
FileUtil.mkdir(folderPath);
}
}
}
}

View File

@@ -0,0 +1,17 @@
package im.zhaojun.zfile.admin.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Referer 校验注解,标注了此注解的请求,会被校验 Referer 是否符合要求.
*
* @author zhaojun
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface RefererCheck {
}

View File

@@ -0,0 +1,75 @@
package im.zhaojun.zfile.admin.annotation;
import im.zhaojun.zfile.admin.model.enums.StorageParamTypeEnum;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 标记存储类型参数名称
*
* @author zhaojun
*/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface StorageParamItem {
/**
* 字段显示排序值, 值越小, 越靠前. 默认为 99
*/
int order() default 99;
/**
* 参数键, 如果为空, 则使用字段名称.
*/
String key() default "";
/**
* 参数名称, 用于网页上显示名称.
*/
String name();
/**
* 字段类型, 默认为 input, 可选值为: input, select, switch.
*/
StorageParamTypeEnum type() default StorageParamTypeEnum.INPUT;
/**
* 当 {@link #type} 为 select 时, 选项的值.
*/
StorageParamSelectOption[] options() default {};
/**
* 当 {@link #type} 为 select 时, 选项的值. 通过 {@link StorageParamSelect#getOptions)} 方法获取选项值.
*/
Class<? extends StorageParamSelect> optionsClass() default StorageParamSelect.class;
/**
* 参数值是否可以为空. 如不为空,则抛出异常.
*/
boolean required() default true;
/**
* 如果填写值为空,则给予默认值.
* 支持 ${xxx} 变量, 会读取配置文件中的值, 如获取失败, 会默认为空.
*/
String defaultValue() default "";
/**
* 参数描述信息, 用户在用户填写时, 进行提示.
*/
String description() default "";
/**
* 参数下方的提示链接, 如果为空, 则不显示.
*/
String link() default "";
/**
* 参数下方的提示链接文件信息, 如果为空, 则默认为链接地址.
*/
String linkName() default "";
}

View File

@@ -0,0 +1,28 @@
package im.zhaojun.zfile.admin.annotation;
import im.zhaojun.zfile.admin.model.param.IStorageParam;
import im.zhaojun.zfile.admin.annotation.model.StorageSourceParamDef;
import java.util.List;
/**
* 存储源参数下拉值接口.
*
* @author zhaojun
*/
public interface StorageParamSelect {
/**
* 获取存储源参数下拉选项列表.
*
* @param storageParamItem
* 存储源下拉参数定义
*
* @param targetParam
* 存储源参数
*
* @return 存储源参数下拉选项列表
*/
List<StorageSourceParamDef.Options> getOptions(StorageParamItem storageParamItem, IStorageParam targetParam);
}

View File

@@ -0,0 +1,27 @@
package im.zhaojun.zfile.admin.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 标记存储类型参数类型为 select 时, 数据的下拉值.
*
* @author zhaojun
*/
@Target(ElementType.ANNOTATION_TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface StorageParamSelectOption {
/**
* 选项显示值
*/
String label();
/**
* 选项存储值
*/
String value();
}

View File

@@ -0,0 +1,95 @@
package im.zhaojun.zfile.admin.annotation.model;
import im.zhaojun.zfile.admin.annotation.StorageParamSelectOption;
import im.zhaojun.zfile.admin.model.enums.StorageParamTypeEnum;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.Getter;
import java.util.List;
/**
* 存储源参数定义, 包含参数名称、描述、必填、默认值等信息.
*
* @author zhaojun
*/
@Data
@AllArgsConstructor
@Builder
public class StorageSourceParamDef {
/**
* 字段显示排序值, 值越小, 越靠前.
*/
private int order;
/**
* 参数 key
*/
private String key;
/**
* 参数名称
*/
private String name;
/**
* 参数描述
*/
private String description;
/**
* 是否必填
*/
private boolean required;
/**
* 默认值
*/
private String defaultValue;
/**
* 链接地址
*/
private String link;
/**
* 链接名称
*/
private String linkName;
/**
* 字段类型, 默认为 input, 可选值为: input, select, switch.
*/
private StorageParamTypeEnum type;
/**
* 当 {@link #type} 为 select 时, 选项的值.
*/
private List<Options> options;
@Getter
public static class Options {
private final String label;
private final String value;
public Options(String value) {
this.label = value;
this.value = value;
}
public Options(String label, String value) {
this.label = label;
this.value = value;
}
public Options(StorageParamSelectOption storageParamSelectOption) {
this.label = storageParamSelectOption.label();
this.value = storageParamSelectOption.value();
}
}
}

View File

@@ -0,0 +1,30 @@
package im.zhaojun.zfile.admin.annotation.select.impl;
import im.zhaojun.zfile.admin.annotation.StorageParamItem;
import im.zhaojun.zfile.admin.annotation.StorageParamSelect;
import im.zhaojun.zfile.admin.model.param.IStorageParam;
import im.zhaojun.zfile.admin.annotation.model.StorageSourceParamDef;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
/**
* 编码格式动态参数.
*
* @author zhaojun
*/
public class EncodingStorageParamSelect implements StorageParamSelect {
@Override
public List<StorageSourceParamDef.Options> getOptions(StorageParamItem storageParamItem, IStorageParam targetParam) {
List<StorageSourceParamDef.Options> options = new ArrayList<>();
for (String name : Charset.availableCharsets().keySet()) {
StorageSourceParamDef.Options option = new StorageSourceParamDef.Options(name);
options.add(option);
}
return options;
}
}

View File

@@ -0,0 +1,14 @@
package im.zhaojun.zfile.admin.constant;
/**
* 存储源设置字段常量.
*
* @author zhaojun
*/
public class StorageConfigConstant {
public static final String ACCESS_TOKEN_KEY = "accessToken";
public static final String REFRESH_TOKEN_KEY = "refreshToken";
}

View File

@@ -0,0 +1,18 @@
package im.zhaojun.zfile.admin.constant;
/**
* 系统设置字段常量.
*
* @author zhaojun
*/
public class SystemConfigConstant {
public static final String USERNAME = "username";
public static final String PASSWORD = "password";
public static final String LOGIN_VERIFY_MODE = "loginVerifyMode";
public static final String RSA_HEX_KEY = "rsaHexKey";
}

View File

@@ -0,0 +1,108 @@
package im.zhaojun.zfile.admin.controller;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import com.github.xiaoymin.knife4j.annotations.ApiSort;
import im.zhaojun.zfile.home.model.dto.CacheInfoDTO;
import im.zhaojun.zfile.admin.service.StorageSourceService;
import im.zhaojun.zfile.common.util.AjaxJson;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
/**
* 存储源缓存维护接口
*
* @author zhaojun
*/
@RestController
@Api(tags = "存储源模块-缓存")
@ApiSort(5)
@RequestMapping("/admin/cache")
public class CacheController {
@Resource
private StorageSourceService storageSourceService;
@ApiOperationSupport(order = 1)
@ApiOperation(value = "启用存储源缓存", notes = "开启缓存后N 秒内重复请求相同文件夹,不会重复调用 API。" +
"参数 N 在配置文件中设置 {zfile.cache.timeout},默认为 1800 秒。")
@ApiImplicitParam(paramType = "path", name = "storageId", value = "存储源 id", required = true)
@PostMapping("/{storageId}/enable")
public AjaxJson<Void> enableCache(@PathVariable("storageId") Integer storageId) {
storageSourceService.updateCacheStatus(storageId, true);
return AjaxJson.getSuccess();
}
@ApiOperationSupport(order = 2)
@ApiOperation(value = "禁用存储源缓存")
@ApiImplicitParam(paramType = "path", name = "storageId", value = "存储源 id", required = true)
@PostMapping("/{storageId}/disable")
public AjaxJson<Void> disableCache(@PathVariable("storageId") Integer storageId) {
storageSourceService.updateCacheStatus(storageId, false);
return AjaxJson.getSuccess();
}
@ApiOperationSupport(order = 3)
@ApiOperation(value = "查看存储源缓存", notes = "可查看存储源缓存的所有目录路径")
@ApiImplicitParam(paramType = "path", name = "storageId", value = "存储源 id", required = true)
@GetMapping("/{storageId}/info")
public AjaxJson<CacheInfoDTO> cacheInfo(@PathVariable("storageId") Integer storageId) {
CacheInfoDTO cacheInfo = storageSourceService.findCacheInfo(storageId);
return AjaxJson.getSuccessData(cacheInfo);
}
@ApiOperationSupport(order = 4)
@ApiOperation(value = "刷新存储源缓存", notes = "刷新存储源缓存路径,系统会重新预热此路径的内容")
@ApiImplicitParams({
@ApiImplicitParam(paramType = "path", name = "storageId", value = "存储源 id", required = true),
@ApiImplicitParam(paramType = "body", name = "key", value = "缓存 key", required = true)
})
@PostMapping("/{storageId}/refresh")
public AjaxJson<Void> refreshCache(@PathVariable("storageId") Integer storageId, String key) throws Exception {
storageSourceService.refreshCache(storageId, key);
return AjaxJson.getSuccess();
}
@ApiOperationSupport(order = 5)
@ApiOperation(value = "开启缓存自动刷新", notes = "开启后每隔 N 秒检测到期的缓存, 对于过期缓存尝试调用 API, 重新写入缓存." +
"参数 N 在配置文件中设置 {zfile.cache.auto-refresh-interval},默认为 5 秒。")
@ApiImplicitParam(paramType = "path", name = "storageId", value = "存储源 id", required = true)
@PostMapping("/{storageId}/auto-refresh/start")
public AjaxJson<Void> enableAutoRefresh(@PathVariable("storageId") Integer storageId) {
storageSourceService.startAutoCacheRefresh(storageId);
return AjaxJson.getSuccess();
}
@ApiOperationSupport(order = 5)
@ApiOperation(value = "关闭缓存自动刷新")
@ApiImplicitParam(paramType = "path", name = "storageId", value = "存储源 id", required = true)
@PostMapping("/{storageId}/auto-refresh/stop")
public AjaxJson<Void> disableAutoRefresh(@PathVariable("storageId") Integer storageId) {
storageSourceService.stopAutoCacheRefresh(storageId);
return AjaxJson.getSuccess();
}
@ApiOperationSupport(order = 6)
@ApiOperation(value = "清空缓存")
@ApiImplicitParam(paramType = "path", name = "storageId", value = "存储源 id", required = true)
@PostMapping("/{storageId}/clear")
public AjaxJson<Void> clearCache(@PathVariable("storageId") Integer storageId) {
storageSourceService.clearCache(storageId);
return AjaxJson.getSuccess();
}
}

View File

@@ -0,0 +1,47 @@
package im.zhaojun.zfile.admin.controller;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ZipUtil;
import com.github.xiaoymin.knife4j.annotations.ApiSort;
import im.zhaojun.zfile.common.util.FileResponseUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.Resource;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.io.File;
import java.util.Date;
/**
* 获取系统日志接口
*
* @author zhaojun
*/
@Api(tags = "日志")
@ApiSort(8)
@Slf4j
@RestController
@RequestMapping("/admin")
public class LogController {
@Value("${zfile.log.path}")
private String zfileLogPath;
@GetMapping("/log/download")
@ApiOperation(value = "下载系统日志")
public ResponseEntity<Resource> downloadLog() {
if (log.isDebugEnabled()) {
log.debug("下载诊断日志");
}
File fileZip = ZipUtil.zip(zfileLogPath);
String currentDate = DateUtil.format(new Date(), "yyyy-MM-dd HH:mm:ss");
return FileResponseUtil.exportSingleThread(fileZip, "ZFile 诊断日志 - " + currentDate + ".zip");
}
}

View File

@@ -0,0 +1,150 @@
package im.zhaojun.zfile.admin.controller.link;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import com.github.xiaoymin.knife4j.annotations.ApiSort;
import im.zhaojun.zfile.admin.convert.DownloadLogConvert;
import im.zhaojun.zfile.admin.model.entity.DownloadLog;
import im.zhaojun.zfile.admin.model.entity.StorageSource;
import im.zhaojun.zfile.admin.model.request.link.BatchDeleteRequest;
import im.zhaojun.zfile.admin.model.request.link.QueryDownloadLogRequest;
import im.zhaojun.zfile.admin.model.result.link.DownloadLogResult;
import im.zhaojun.zfile.admin.service.DownloadLogService;
import im.zhaojun.zfile.admin.service.StorageSourceService;
import im.zhaojun.zfile.common.util.AjaxJson;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Stream;
/**
* 直链下载日志接口
*
* @author zhaojun
*/
@Api(tags = "直链日志管理")
@ApiSort(7)
@Controller
@RequestMapping("/admin/download/log")
public class DownloadLogManagerController {
@Resource
private StorageSourceService storageSourceService;
@Resource
private DownloadLogConvert downloadLogConvert;
@Resource
private DownloadLogService downloadLogService;
@ApiOperationSupport(order = 1)
@GetMapping("/list")
@ApiOperation(value = "直链下载日志")
@ResponseBody
@ApiImplicitParams({
@ApiImplicitParam(paramType = "query", name = "key", value = "直链 key"),
@ApiImplicitParam(paramType = "query", name = "page", value = "分页页数"),
@ApiImplicitParam(paramType = "query", name = "limit", value = "每页条数"),
@ApiImplicitParam(paramType = "query", name = "orderBy", defaultValue = "createDate", value = "排序字段"),
@ApiImplicitParam(paramType = "query", name = "orderDirection", defaultValue = "desc", value = "排序顺序")
})
public AjaxJson<?> list(QueryDownloadLogRequest queryDownloadLogRequest,
@RequestParam(required = false, defaultValue = "create_time") String orderBy,
@RequestParam(required = false, defaultValue = "desc") String orderDirection) {
Page<DownloadLog> pages = Page.of(queryDownloadLogRequest.getPage(), queryDownloadLogRequest.getLimit());
boolean asc = Objects.equals(orderDirection, "asc");
pages.addOrder(new OrderItem(orderBy, asc));
DownloadLog downloadLog = new DownloadLog();
QueryWrapper<DownloadLog> queryWrapper = new QueryWrapper<>(downloadLog);
if (StrUtil.isNotEmpty(queryDownloadLogRequest.getStorageKey())) {
queryWrapper.eq("storage_key", queryDownloadLogRequest.getStorageKey());
}
if (StrUtil.isNotEmpty(queryDownloadLogRequest.getPath())) {
queryWrapper.like("path", queryDownloadLogRequest.getPath());
}
if (StrUtil.isNotEmpty(queryDownloadLogRequest.getShortKey())) {
queryWrapper.like("short_key", queryDownloadLogRequest.getShortKey());
}
if (StrUtil.isNotEmpty(queryDownloadLogRequest.getIp())) {
queryWrapper.like("ip", queryDownloadLogRequest.getIp());
}
if (StrUtil.isNotEmpty(queryDownloadLogRequest.getReferer())) {
queryWrapper.like("referer", queryDownloadLogRequest.getReferer());
}
if (StrUtil.isNotEmpty(queryDownloadLogRequest.getUserAgent())) {
queryWrapper.like("user_agent", queryDownloadLogRequest.getUserAgent());
}
if (ObjectUtil.isNotEmpty(queryDownloadLogRequest.getDateFrom())) {
queryWrapper.ge("create_time", queryDownloadLogRequest.getDateFrom());
}
if (ObjectUtil.isNotEmpty(queryDownloadLogRequest.getDateTo())) {
queryWrapper.le("create_time", queryDownloadLogRequest.getDateFrom());
}
Page<DownloadLog> selectResult = downloadLogService.page(pages, queryWrapper);
long total = selectResult.getTotal();
List<DownloadLog> records = selectResult.getRecords();
Map<String, StorageSource> cache = new HashMap<>();
Stream<DownloadLogResult> shortLinkResultList = records.stream().map(model -> {
String storageKey = model.getStorageKey();
StorageSource storageSource;
if (cache.containsKey(storageKey)) {
storageSource = cache.get(storageKey);
} else {
storageSource = storageSourceService.findByStorageKey(storageKey);
cache.put(storageKey, storageSource);
}
return downloadLogConvert.entityToResultList(model, storageSource);
});
return AjaxJson.getPageData(total, shortLinkResultList);
}
@ApiOperationSupport(order = 2)
@DeleteMapping("/delete/{id}")
@ApiOperation(value = "删除直链")
@ApiImplicitParam(paramType = "path", name = "id", value = "直链 id", required = true)
@ResponseBody
public AjaxJson<Void> deleteById(@PathVariable Integer id) {
downloadLogService.removeById(id);
return AjaxJson.getSuccess();
}
@ApiOperationSupport(order = 3)
@PostMapping("/delete/batch")
@ResponseBody
@ApiImplicitParam(paramType = "query", name = "ids", value = "直链 id", required = true)
@ApiOperation(value = "批量删除直链")
public AjaxJson<Void> batchDelete(@RequestBody BatchDeleteRequest batchDeleteRequest) {
List<Integer> ids = batchDeleteRequest.getIds();
downloadLogService.removeBatchByIds(ids);
return AjaxJson.getSuccess();
}
}

View File

@@ -0,0 +1,143 @@
package im.zhaojun.zfile.admin.controller.link;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import com.github.xiaoymin.knife4j.annotations.ApiSort;
import im.zhaojun.zfile.admin.convert.ShortLinkConvert;
import im.zhaojun.zfile.admin.model.entity.ShortLink;
import im.zhaojun.zfile.admin.model.entity.StorageSource;
import im.zhaojun.zfile.admin.model.request.link.BatchDeleteRequest;
import im.zhaojun.zfile.admin.model.result.link.ShortLinkResult;
import im.zhaojun.zfile.admin.service.ShortLinkService;
import im.zhaojun.zfile.admin.service.StorageSourceService;
import im.zhaojun.zfile.common.util.AjaxJson;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Stream;
/**
* 直链管理接口
*
* @author zhaojun
*/
@Api(tags = "直链管理")
@ApiSort(7)
@Controller
@RequestMapping("/admin")
public class ShortLinkManagerController {
@Resource
private ShortLinkService shortLinkService;
@Resource
private StorageSourceService storageSourceService;
@Resource
private ShortLinkConvert shortLinkConvert;
@ApiOperationSupport(order = 1)
@GetMapping("/link/list")
@ApiOperation(value = "搜索短链")
@ResponseBody
@ApiImplicitParams({
@ApiImplicitParam(paramType = "query", name = "key", value = "短链 key"),
@ApiImplicitParam(paramType = "query", name = "storageId", value = "存储源 ID"),
@ApiImplicitParam(paramType = "query", name = "url", value = "短链 url"),
@ApiImplicitParam(paramType = "query", name = "dateFrom", value = "短链创建时间从"),
@ApiImplicitParam(paramType = "query", name = "dateTo", value = "短链创建时间至"),
@ApiImplicitParam(paramType = "query", name = "page", value = "分页页数"),
@ApiImplicitParam(paramType = "query", name = "limit", value = "每页条数"),
@ApiImplicitParam(paramType = "query", name = "orderBy", defaultValue = "createDate", value = "排序字段"),
@ApiImplicitParam(paramType = "query", name = "orderDirection", defaultValue = "desc", value = "排序顺序")
})
public AjaxJson<?> list(String key, String storageId,
String url,
String dateFrom,
String dateTo,
Integer page,
Integer limit,
@RequestParam(required = false, defaultValue = "create_date") String orderBy,
@RequestParam(required = false, defaultValue = "desc") String orderDirection) {
Page<ShortLink> pages = Page.of(page, limit);
boolean asc = Objects.equals(orderDirection, "asc");
pages.addOrder(new OrderItem(orderBy, asc));
QueryWrapper<ShortLink> queryWrapper = new QueryWrapper<>(new ShortLink());
if (StrUtil.isNotEmpty(storageId)) {
queryWrapper.eq("storage_id", storageId);
}
if (StrUtil.isNotEmpty(key)) {
queryWrapper.like("short_key", key);
}
if (StrUtil.isNotEmpty(url)) {
queryWrapper.like("url", url);
}
if (StrUtil.isNotEmpty(dateFrom)) {
queryWrapper.ge("create_date", dateFrom);
}
if (StrUtil.isNotEmpty(dateTo)) {
queryWrapper.le("create_date", dateTo);
}
Page<ShortLink> selectResult = shortLinkService.page(pages, queryWrapper);
long total = selectResult.getTotal();
List<ShortLink> records = selectResult.getRecords();
Map<Integer, StorageSource> cache = new HashMap<>();
Stream<ShortLinkResult> shortLinkResultList = records.stream().map(shortLink -> {
Integer shortLinkStorageId = shortLink.getStorageId();
StorageSource storageSource;
if (cache.containsKey(shortLinkStorageId)) {
storageSource = cache.get(shortLinkStorageId);
} else {
storageSource = storageSourceService.findById(shortLinkStorageId);
cache.put(shortLinkStorageId, storageSource);
}
return shortLinkConvert.entityToResultList(shortLink, storageSource);
});
return AjaxJson.getPageData(total, shortLinkResultList);
}
@ApiOperationSupport(order = 2)
@DeleteMapping("/link/delete/{id}")
@ApiOperation(value = "删除短链")
@ApiImplicitParam(paramType = "path", name = "id", value = "短链 id", required = true)
@ResponseBody
public AjaxJson<Void> deleteById(@PathVariable Integer id) {
shortLinkService.removeById(id);
return AjaxJson.getSuccess();
}
@ApiOperationSupport(order = 3)
@PostMapping("/link/delete/batch")
@ResponseBody
@ApiImplicitParam(paramType = "query", name = "ids", value = "短链 id", required = true)
@ApiOperation(value = "批量删除短链")
public AjaxJson<Void> batchDelete(@RequestBody BatchDeleteRequest batchDeleteRequest) {
shortLinkService.removeBatchByIds(batchDeleteRequest.getIds());
return AjaxJson.getSuccess();
}
}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,109 @@
package im.zhaojun.zfile.admin.controller.setting;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import com.github.xiaoymin.knife4j.annotations.ApiSort;
import im.zhaojun.zfile.admin.model.request.setting.UpdateLinkSettingRequest;
import im.zhaojun.zfile.admin.model.request.setting.UpdateSecuritySettingRequest;
import im.zhaojun.zfile.admin.model.request.setting.UpdateSiteSettingRequest;
import im.zhaojun.zfile.admin.model.request.setting.UpdateUserNameAndPasswordRequest;
import im.zhaojun.zfile.admin.model.request.setting.UpdateViewSettingRequest;
import im.zhaojun.zfile.admin.service.SystemConfigService;
import im.zhaojun.zfile.common.util.AjaxJson;
import im.zhaojun.zfile.home.model.dto.SystemConfigDTO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.BeanUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import javax.validation.Valid;
/**
* 站点设定值接口
*
* @author zhaojun
*/
@Api(tags = "站点设置模块")
@ApiSort(2)
@RestController
@RequestMapping("/admin")
public class SettingController {
@Resource
private SystemConfigService systemConfigService;
@ApiOperationSupport(order = 1)
@ApiOperation(value = "获取站点信息",
notes = "获取站点相关信息,如站点名称,风格样式,是否显示公告,是否显示文档区,自定义 CSSJS 等参数")
@GetMapping("/config")
public AjaxJson<SystemConfigDTO> getConfig() {
SystemConfigDTO systemConfigDTO = systemConfigService.getSystemConfig();
return AjaxJson.getSuccessData(systemConfigDTO);
}
@ApiOperationSupport(order = 2)
@ApiOperation(value = "修改管理员账号密码")
@PutMapping("/config/password")
public AjaxJson<?> updatePwd(@Valid @RequestBody UpdateUserNameAndPasswordRequest settingRequest) {
SystemConfigDTO systemConfigDTO = new SystemConfigDTO();
BeanUtils.copyProperties(settingRequest, systemConfigDTO);
String password = systemConfigDTO.getPassword();
if (StrUtil.isNotEmpty(password)) {
systemConfigDTO.setPassword(SecureUtil.md5(password));
}
systemConfigService.updateSystemConfig(systemConfigDTO);
return AjaxJson.getSuccess();
}
@ApiOperationSupport(order = 3)
@ApiOperation(value = "修改站点设置")
@PutMapping("/config/site")
public AjaxJson<?> updateSiteSetting(@Valid @RequestBody UpdateSiteSettingRequest settingRequest) {
SystemConfigDTO systemConfigDTO = new SystemConfigDTO();
BeanUtils.copyProperties(settingRequest, systemConfigDTO);
systemConfigService.updateSystemConfig(systemConfigDTO);
return AjaxJson.getSuccess();
}
@ApiOperationSupport(order = 4)
@ApiOperation(value = "修改显示设置")
@PutMapping("/config/view")
public AjaxJson<?> updateViewSetting(@Valid @RequestBody UpdateViewSettingRequest settingRequest) {
SystemConfigDTO systemConfigDTO = new SystemConfigDTO();
BeanUtils.copyProperties(settingRequest, systemConfigDTO);
systemConfigService.updateSystemConfig(systemConfigDTO);
return AjaxJson.getSuccess();
}
@ApiOperationSupport(order = 5)
@ApiOperation(value = "修改登陆安全设置")
@PutMapping("/config/security")
public AjaxJson<?> updateSecuritySetting(@Valid @RequestBody UpdateSecuritySettingRequest settingRequest) {
SystemConfigDTO systemConfigDTO = new SystemConfigDTO();
BeanUtils.copyProperties(settingRequest, systemConfigDTO);
systemConfigService.updateSystemConfig(systemConfigDTO);
return AjaxJson.getSuccess();
}
@ApiOperationSupport(order = 6)
@ApiOperation(value = "修改直链设置")
@PutMapping("/config/link")
public AjaxJson<?> updateLinkSetting(@Valid @RequestBody UpdateLinkSettingRequest settingRequest) {
SystemConfigDTO systemConfigDTO = new SystemConfigDTO();
BeanUtils.copyProperties(settingRequest, systemConfigDTO);
systemConfigService.updateSystemConfig(systemConfigDTO);
return AjaxJson.getSuccess();
}
}

View File

@@ -0,0 +1,44 @@
package im.zhaojun.zfile.admin.controller.stroage;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import com.github.xiaoymin.knife4j.annotations.ApiSort;
import im.zhaojun.zfile.common.context.StorageSourceContext;
import im.zhaojun.zfile.home.model.enums.StorageTypeEnum;
import im.zhaojun.zfile.admin.annotation.model.StorageSourceParamDef;
import im.zhaojun.zfile.common.util.AjaxJson;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/**
* 系统元数据接口
*
* @author zhaojun
*/
@Api(tags = "存储源模块-元数据")
@ApiSort(4)
@RestController
@RequestMapping("/admin")
public class StorageMetaDataController {
@GetMapping("/support-storage")
@ApiOperationSupport(order = 1)
@ApiOperation(value = "获取支持的存储源类型", notes = "获取系统支持的存储源类型")
public AjaxJson<StorageTypeEnum[]> supportStorage() {
return AjaxJson.getSuccessData(StorageTypeEnum.values());
}
@GetMapping("/storage-params")
@ApiOperationSupport(order = 2)
@ApiOperation(value = "获取指定存储源类型的所有参数信息", notes = "获取指定存储源类型的参数,如本地存储只需要填路径地址,而对象存储需要填 AccessKey, SecretKey 等信息.")
public AjaxJson<List<StorageSourceParamDef>> getFormByStorageType(StorageTypeEnum storageType) {
List<StorageSourceParamDef> storageSourceConfigList = StorageSourceContext.getStorageSourceParamListByType(storageType);
return AjaxJson.getSuccessData(storageSourceConfigList);
}
}

View File

@@ -0,0 +1,148 @@
package im.zhaojun.zfile.admin.controller.stroage;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import com.github.xiaoymin.knife4j.annotations.ApiSort;
import im.zhaojun.zfile.admin.model.entity.StorageSource;
import im.zhaojun.zfile.admin.model.request.SaveStorageSourceRequest;
import im.zhaojun.zfile.admin.model.result.storage.StorageSourceAdminResult;
import im.zhaojun.zfile.admin.service.StorageSourceService;
import im.zhaojun.zfile.common.cache.RefreshTokenCache;
import im.zhaojun.zfile.common.util.AjaxJson;
import im.zhaojun.zfile.home.convert.StorageSourceConvert;
import im.zhaojun.zfile.home.model.dto.StorageSourceDTO;
import im.zhaojun.zfile.home.model.request.UpdateStorageSortRequest;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.util.List;
/**
* 存储源基础设置模块接口
*
* @author zhaojun
*/
@Api(tags = "存储源模块-基础")
@ApiSort(3)
@RestController
@RequestMapping("/admin")
public class StorageSourceController {
@Resource
private StorageSourceService storageSourceService;
@Resource
private StorageSourceConvert storageSourceConvert;
@ApiOperationSupport(order = 1)
@ApiOperation(value = "获取所有存储源列表", notes = "获取所有添加的存储源列表,按照排序值由小到大排序")
@GetMapping("/storages")
public AjaxJson<List<StorageSourceAdminResult>> storageList() {
List<StorageSource> list = storageSourceService.findAllOrderByOrderNum();
List<StorageSourceAdminResult> storageSourceAdminResults = storageSourceConvert.entityToAdminResultList(list);
storageSourceAdminResults.forEach(storageSourceAdminResult -> {
RefreshTokenCache.RefreshTokenInfo refreshTokenInfo = RefreshTokenCache.getRefreshTokenInfo(storageSourceAdminResult.getId());
storageSourceAdminResult.setRefreshTokenInfo(refreshTokenInfo);
});
return AjaxJson.getSuccessData(storageSourceAdminResults);
}
@ApiOperationSupport(order = 2)
@ApiOperation(value = "获取指定存储源参数", notes = "获取指定存储源基本信息及其参数")
@ApiImplicitParam(paramType = "path", name = "storageId", value = "存储源 id", required = true)
@GetMapping("/storage/{storageId}")
public AjaxJson<StorageSourceDTO> storageItem(@PathVariable Integer storageId) {
StorageSourceDTO storageSourceDTO = storageSourceService.findStorageSourceDTOById(storageId);
return AjaxJson.getSuccessData(storageSourceDTO);
}
@ApiOperationSupport(order = 3)
@ApiOperation(value = "保存存储源参数", notes = "保存存储源的所有参数")
@PostMapping("/storage")
public AjaxJson<Void> saveStorageItem(@RequestBody SaveStorageSourceRequest saveStorageSourceRequest) {
storageSourceService.saveStorageSource(saveStorageSourceRequest);
return AjaxJson.getSuccess();
}
@ApiOperationSupport(order = 4)
@ApiOperation(value = "删除存储源", notes = "删除存储源基本设置和拓展设置")
@ApiImplicitParam(paramType = "path", name = "storageId", value = "存储源 id", required = true)
@DeleteMapping("/storage/{storageId}")
public AjaxJson<Void> deleteStorageItem(@PathVariable Integer storageId) {
storageSourceService.deleteById(storageId);
return AjaxJson.getSuccess();
}
@ApiOperationSupport(order = 5)
@ApiOperation(value = "启用存储源", notes = "开启存储源后可在前台显示")
@ApiImplicitParam(paramType = "path", name = "storageId", value = "存储源 id", required = true)
@PostMapping("/storage/{storageId}/enable")
public AjaxJson<Void> enable(@PathVariable Integer storageId) {
StorageSource storageSource = storageSourceService.findById(storageId);
storageSource.setEnable(true);
storageSourceService.updateById(storageSource);
return AjaxJson.getSuccess();
}
@ApiOperationSupport(order = 6)
@ApiOperation(value = "停止存储源", notes = "停用存储源后不在前台显示")
@ApiImplicitParam(paramType = "path", name = "storageId", value = "存储源 id", required = true)
@PostMapping("/storage/{storageId}/disable")
public AjaxJson<Void> disable(@PathVariable Integer storageId) {
StorageSource storageSource = storageSourceService.findById(storageId);
storageSource.setEnable(false);
storageSourceService.updateById(storageSource);
return AjaxJson.getSuccess();
}
@ApiOperationSupport(order = 7)
@ApiOperation(value = "更新存储源顺序")
@PostMapping("/storage/sort")
public AjaxJson<Void> updateStorageSort(@RequestBody List<UpdateStorageSortRequest> updateStorageSortRequestList) {
storageSourceService.updateStorageSort(updateStorageSortRequestList);
return AjaxJson.getSuccess();
}
@ApiOperationSupport(order = 8)
@ApiOperation(value = "校验存储源 key 是否重复")
@ApiImplicitParam(paramType = "query", name = "storageKey", value = "存储源 key", required = true)
@GetMapping("/storage/exist/key")
public AjaxJson<Boolean> existKey(String storageKey) {
boolean exist = storageSourceService.existByStorageKey(storageKey);
return AjaxJson.getSuccessData(exist);
}
@ApiOperationSupport(order = 9)
@ApiOperation(value = "修改 readme 兼容模式", notes = "修改 readme 兼容模式是否启用")
@ApiImplicitParams({
@ApiImplicitParam(paramType = "path", name = "storageId", value = "存储源 id", required = true),
@ApiImplicitParam(paramType = "path", name = "status", value = "存储源兼容模式状态", required = true)
})
@PostMapping("/storage/{storageId}/compatibility_readme/{status}")
public AjaxJson<Void> changeCompatibilityReadme(@PathVariable Integer storageId, @PathVariable Boolean status) {
StorageSource storageSource = storageSourceService.findById(storageId);
storageSource.setCompatibilityReadme(status);
storageSourceService.updateById(storageSource);
return AjaxJson.getSuccess();
}
}

View File

@@ -0,0 +1,53 @@
package im.zhaojun.zfile.admin.controller.stroage;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import com.github.xiaoymin.knife4j.annotations.ApiSort;
import im.zhaojun.zfile.admin.model.entity.FilterConfig;
import im.zhaojun.zfile.admin.service.FilterConfigService;
import im.zhaojun.zfile.common.util.AjaxJson;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.util.List;
/**
* 存储源过滤器维护接口
*
* @author zhaojun
*/
@Api(tags = "存储源模块-过滤文件")
@ApiSort(6)
@RestController
@RequestMapping("/admin")
public class StorageSourceFilterController {
@Resource
private FilterConfigService filterConfigService;
@ApiOperationSupport(order = 1)
@ApiOperation(value = "获取存储源过滤文件列表", notes = "根据存储源 ID 获取存储源设置的过滤文件列表")
@ApiImplicitParam(paramType = "path", name = "storageId", value = "存储源 id", required = true)
@GetMapping("/storage/{storageId}/filters")
public AjaxJson<List<FilterConfig>> getFilters(@PathVariable Integer storageId) {
return AjaxJson.getSuccessData(filterConfigService.findByStorageId(storageId));
}
@ApiOperationSupport(order = 2)
@ApiOperation(value = "保存存储源过滤文件列表", notes = "保存指定存储源 ID 设置的过滤文件列表")
@ApiImplicitParam(paramType = "path", name = "storageId", value = "存储源 id", required = true)
@PostMapping("/storage/{storageId}/filters")
public AjaxJson<Void> saveFilters(@PathVariable Integer storageId, @RequestBody List<FilterConfig> filter) {
filterConfigService.batchSave(storageId, filter);
return AjaxJson.getSuccess();
}
}

View File

@@ -0,0 +1,53 @@
package im.zhaojun.zfile.admin.controller.stroage;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import com.github.xiaoymin.knife4j.annotations.ApiSort;
import im.zhaojun.zfile.admin.model.entity.PasswordConfig;
import im.zhaojun.zfile.admin.service.PasswordConfigService;
import im.zhaojun.zfile.common.util.AjaxJson;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.util.List;
/**
* 存储源密码维护接口
*
* @author zhaojun
*/
@Api(tags = "存储源模块-密码文件夹")
@ApiSort(6)
@RestController
@RequestMapping("/admin")
public class StorageSourcePasswordController {
@Resource
private PasswordConfigService passwordConfigService;
@ApiOperationSupport(order = 1)
@ApiOperation(value = "获取存储源密码文件夹列表", notes = "根据存储源 ID 获取存储源设置的密码文件夹列表")
@ApiImplicitParam(paramType = "path", name = "storageId", value = "存储源 id", required = true)
@GetMapping("/storage/{storageId}/password")
public AjaxJson<List<PasswordConfig>> getPasswordList(@PathVariable Integer storageId) {
return AjaxJson.getSuccessData(passwordConfigService.findByStorageId(storageId));
}
@ApiOperationSupport(order = 2)
@ApiOperation(value = "保存存储源密码文件夹列表", notes = "保存指定存储源 ID 设置的密码文件夹列表")
@ApiImplicitParam(paramType = "path", name = "storageId", value = "存储源 id", required = true)
@PostMapping("/storage/{storageId}/password")
public AjaxJson<Void> savePasswordList(@PathVariable Integer storageId, @RequestBody List<PasswordConfig> password) {
passwordConfigService.batchSave(storageId, password);
return AjaxJson.getSuccess();
}
}

View File

@@ -0,0 +1,53 @@
package im.zhaojun.zfile.admin.controller.stroage;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import com.github.xiaoymin.knife4j.annotations.ApiSort;
import im.zhaojun.zfile.admin.model.entity.ReadmeConfig;
import im.zhaojun.zfile.admin.service.ReadmeConfigService;
import im.zhaojun.zfile.common.util.AjaxJson;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.util.List;
/**
* 存储源文档模块维护接口
*
* @author zhaojun
*/
@Api(tags = "存储源模块-README")
@ApiSort(7)
@RestController
@RequestMapping("/admin")
public class StorageSourceReadmeController {
@Resource
private ReadmeConfigService readmeConfigService;
@ApiOperationSupport(order = 1)
@ApiOperation(value = "获取存储源文档文件夹列表", notes = "根据存储源 ID 获取存储源设置的文档文件夹列表")
@ApiImplicitParam(paramType = "path", name = "storageId", value = "存储源 id", required = true)
@GetMapping("/storage/{storageId}/readme")
public AjaxJson<List<ReadmeConfig>> getReadmeList(@PathVariable Integer storageId) {
return AjaxJson.getSuccessData(readmeConfigService.findByStorageId(storageId));
}
@ApiOperationSupport(order = 2)
@ApiOperation(value = "保存存储源文档文件夹列表", notes = "保存指定存储源 ID 设置的文档文件夹列表")
@ApiImplicitParam(paramType = "path", name = "storageId", value = "存储源 id", required = true)
@PostMapping("/storage/{storageId}/readme")
public AjaxJson<Void> saveReadmeList(@PathVariable Integer storageId, @RequestBody List<ReadmeConfig> readme) {
readmeConfigService.batchSave(storageId, readme);
return AjaxJson.getSuccess();
}
}

View File

@@ -0,0 +1,24 @@
package im.zhaojun.zfile.admin.convert;
import im.zhaojun.zfile.admin.model.entity.DownloadLog;
import im.zhaojun.zfile.admin.model.entity.StorageSource;
import im.zhaojun.zfile.admin.model.result.link.DownloadLogResult;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.springframework.stereotype.Component;
/**
* 下载日志实体类转换器
*
* @author zhaojun
*/
@Component
@Mapper(componentModel = "spring")
public interface DownloadLogConvert {
@Mapping(source = "downloadLog.id", target = "id")
@Mapping(source = "storageSource.name", target = "storageName")
@Mapping(source = "storageSource.type", target = "storageType")
DownloadLogResult entityToResultList(DownloadLog downloadLog, StorageSource storageSource);
}

View File

@@ -0,0 +1,24 @@
package im.zhaojun.zfile.admin.convert;
import im.zhaojun.zfile.admin.model.entity.ShortLink;
import im.zhaojun.zfile.admin.model.entity.StorageSource;
import im.zhaojun.zfile.admin.model.result.link.ShortLinkResult;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.springframework.stereotype.Component;
/**
* 直链实体类器
*
* @author zhaojun
*/
@Component
@Mapper(componentModel = "spring")
public interface ShortLinkConvert {
@Mapping(source = "shortLink.id", target = "id")
@Mapping(source = "storageSource.name", target = "storageName")
@Mapping(source = "storageSource.type", target = "storageType")
ShortLinkResult entityToResultList(ShortLink shortLink, StorageSource storageSource);
}

View File

@@ -0,0 +1,22 @@
package im.zhaojun.zfile.admin.exception;
import lombok.Getter;
/**
* 禁止的文件操作异常
*
* @author zhaojun
*/
@Getter
public class ForbidFileOperationException extends RuntimeException {
private final Integer storageId;
private final String action;
public ForbidFileOperationException(Integer storageId, String action) {
this.storageId = storageId;
this.action = action;
}
}

View File

@@ -0,0 +1,21 @@
package im.zhaojun.zfile.admin.exception;
import im.zhaojun.zfile.admin.model.param.IStorageParam;
import lombok.Getter;
/**
* 存储源自动设置 cors 异常
*
* @author zhaojun
*/
@Getter
public class StorageSourceAutoConfigCorsException extends RuntimeException {
private final IStorageParam iStorageParam;
public StorageSourceAutoConfigCorsException(String message, Throwable cause, IStorageParam iStorageParam) {
super(message, cause);
this.iStorageParam = iStorageParam;
}
}

View File

@@ -0,0 +1,15 @@
package im.zhaojun.zfile.admin.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import im.zhaojun.zfile.admin.model.entity.DownloadLog;
import org.apache.ibatis.annotations.Mapper;
/**
* 下载日志 Mapper 接口
*
* @author zhaojun
*/
@Mapper
public interface DownloadLogMapper extends BaseMapper<DownloadLog> {
}

View File

@@ -0,0 +1,61 @@
package im.zhaojun.zfile.admin.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import im.zhaojun.zfile.admin.model.entity.FilterConfig;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* 过滤器配置表 Mapper 接口
*
* @author zhaojun
*/
@Mapper
public interface FilterConfigMapper extends BaseMapper<FilterConfig> {
/**
* 根据存储源 ID 获取存储源配置列表
*
* @param storageId
* 存储源 ID
*
* @return 存储源过滤器配置列表
*/
List<FilterConfig> findByStorageId(@Param("storageId") Integer storageId);
/**
* 根据存储源 ID 删除过滤器配置
*
* @param storageId
* 存储源 ID
*
* @return 删除条数
*/
int deleteByStorageId(@Param("storageId") Integer storageId);
/**
* 获取所有类型为禁止访问的过滤规则
*
* @param storageId
* 存储 ID
*
* @return 禁止访问的过滤规则列表
*/
List<FilterConfig> findByStorageIdAndInaccessible(@Param("storageId")Integer storageId);
/**
* 获取所有类型为禁止下载的过滤规则
*
* @param storageId
* 存储 ID
*
* @return 禁止下载的过滤规则列表
*/
List<FilterConfig> findByStorageIdAndDisableDownload(@Param("storageId")Integer storageId);
}

View File

@@ -0,0 +1,39 @@
package im.zhaojun.zfile.admin.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import im.zhaojun.zfile.admin.model.entity.PasswordConfig;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* 存储源密码配置表 Mapper 接口
*
* @author zhaojun
*/
@Mapper
public interface PasswordConfigMapper extends BaseMapper<PasswordConfig> {
/**
* 根据存储源 ID 获取密码规则配置
*
* @param storageId
* 存储源 ID
*
* @return 存储源密码规则配置列表
*/
List<PasswordConfig> findByStorageId(@Param("storageId") Integer storageId);
/**
* 根据存储源 ID 删除要密码规则配置
*
* @param storageId
* 存储源 ID
*
* @return 删除记录数
*/
int deleteByStorageId(@Param("storageId") Integer storageId);
}

View File

@@ -0,0 +1,40 @@
package im.zhaojun.zfile.admin.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import im.zhaojun.zfile.admin.model.entity.ReadmeConfig;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* 存储源文档配置表 Mapper 接口
*
* @author zhaojun
*/
@Mapper
public interface ReadmeConfigMapper extends BaseMapper<ReadmeConfig> {
/**
* 根据存储源 ID 查询文档配置
*
* @param storageId
* 存储源ID
*
* @return 存储源文档配置列表
*/
List<ReadmeConfig> findByStorageId(@Param("storageId") Integer storageId);
/**
* 根据存储源 ID 删除文档配置
*
* @param storageId
* 存储源ID
*
* @return 删除记录数
*/
int deleteByStorageId(@Param("storageId") Integer storageId);
}

View File

@@ -0,0 +1,41 @@
package im.zhaojun.zfile.admin.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import im.zhaojun.zfile.admin.model.entity.ShortLink;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
/**
* 短链接配置表 Mapper 接口
*
* @author zhaojun
*/
@Mapper
public interface ShortLinkMapper extends BaseMapper<ShortLink> {
/**
* 根据短链接 key 查询短链接
*
* @param key
* 短链接 key
*
* @return 短链接信息
*/
ShortLink findByKey(@Param("key")String key);
/**
* 根据存储源 ID 和文件路径查询短链接
*
* @param storageId
* 存储源 ID
*
* @param url
* 短链接 url
*
* @return 短链接信息
*/
ShortLink findByStorageIdAndUrl(@Param("storageId") Integer storageId, @Param("url") String url);
}

View File

@@ -0,0 +1,65 @@
package im.zhaojun.zfile.admin.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import im.zhaojun.zfile.admin.model.entity.StorageSourceConfig;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* 存储源拓展设置 Mapper 接口
*
* @author zhaojun
*/
@Mapper
public interface StorageSourceConfigMapper extends BaseMapper<StorageSourceConfig> {
/**
* 根据存储源 ID 查询存储源拓展配置, 并按照存储源 id 排序
*
* @param storageId
* 存储源 ID
*
* @return 存储源拓展配置列表
*/
List<StorageSourceConfig> findByStorageIdOrderById(@Param("storageId") Integer storageId);
/**
* 获取指定存储源的指定参数名称
*
* @param storageId
* 存储源 id
*
* @param name
* 参数名
*
* @return 参数信息
*/
StorageSourceConfig findByStorageIdAndName(@Param("storageId") Integer storageId, @Param("name") String name);
/**
* 根据存储源 ID 删除存储源拓展配置
*
* @param storageId
* 存储源 ID
*
* @return 删除记录数
*/
int deleteByStorageId(@Param("storageId") Integer storageId);
/**
* 批量插入存储源拓展配置
*
* @param list
* 存储源拓展配置列表
*
* @return 插入记录数
*/
int insertList(@Param("list") List<StorageSourceConfig> list);
}

View File

@@ -0,0 +1,98 @@
package im.zhaojun.zfile.admin.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import im.zhaojun.zfile.admin.model.entity.StorageSource;
import im.zhaojun.zfile.home.model.enums.StorageTypeEnum;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* 存储源基本配置 Mapper 接口
*
* @author zhaojun
*/
@Mapper
public interface StorageSourceMapper extends BaseMapper<StorageSource> {
/**
* 获取所有已启用的存储源, 并按照存储源排序值排序
*
* @return 存储源列表
*/
List<StorageSource> findListByEnableOrderByOrderNum();
/**
* 获取所有存储源, 并按照存储源排序值排序
*
* @return 存储源列表
*/
List<StorageSource> findAllOrderByOrderNum();
/**
* 获取存储源 ID 最大值
*
* @return 存储源 ID 最大值
*/
Integer selectMaxId();
/**
* 根据存储源类型获取存储源列表
*
* @param type
* 存储源类型
*
* @return 存储源列表
*/
List<StorageSource> findByType(@Param("type") StorageTypeEnum type);
/**
* 根据存储源 ID 设置排序值
*
* @param orderNum
* 排序值
*
* @param id
* 存储源 ID
*/
void updateSetOrderNumById(@Param("orderNum") int orderNum, @Param("id") Integer id);
/**
* 根据存储源 key 获取存储源
*
* @param storageKey
* 存储源 key
*
* @return 存储源信息
*/
StorageSource findByStorageKey(@Param("storageKey") String storageKey);
/**
* 根据存储源 key 获取存储源 id
*
* @param storageKey
* 存储源 key
*
* @return 存储源 id
*/
Integer findIdByStorageKey(@Param("storageKey") String storageKey);
/**
* 根据存储源 id 获取存储源 key
*
* @param id
* 存储源 id
*
* @return 存储源 key
*/
String findKeyById(@Param("id")Integer id);
}

View File

@@ -0,0 +1,48 @@
package im.zhaojun.zfile.admin.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import im.zhaojun.zfile.admin.model.entity.SystemConfig;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* 系统配置 Mapper 接口
*
* @author zhaojun
*/
@Mapper
public interface SystemConfigMapper extends BaseMapper<SystemConfig> {
/**
* 获取所有系统设置
*
* @return 系统设置列表
*/
List<SystemConfig> findAll();
/**
* 根据系统设置名称获取设置信息
*
* @param name
* 系统设置名称
*
* @return 系统设置信息
*/
SystemConfig findByName(@Param("name")String name);
/**
* 批量保存系统设置
*
* @param list
* 系统设置列表
*
* @return 保存记录数
*/
int saveAll(@Param("list")List<SystemConfig> list);
}

View File

@@ -0,0 +1,49 @@
package im.zhaojun.zfile.admin.model.dto;
import lombok.Data;
/**
* OneDrive Token DTO
*
* @author zhaojun
*/
@Data
public class OneDriveToken {
private String clientId;
private String clientSecret;
private String redirectUri;
private String accessToken;
private String refreshToken;
private boolean success;
private String body;
public static OneDriveToken success(String clientId, String clientSecret, String redirectUri, String accessToken, String refreshToken, String body) {
OneDriveToken token = new OneDriveToken();
token.setClientId(clientId);
token.setClientSecret(clientSecret);
token.setRedirectUri(redirectUri);
token.setSuccess(true);
token.setBody(body);
token.setAccessToken(accessToken);
token.setRefreshToken(refreshToken);
return token;
}
public static OneDriveToken fail(String clientId, String clientSecret, String redirectUri, String body) {
OneDriveToken token = new OneDriveToken();
token.setClientId(clientId);
token.setClientSecret(clientSecret);
token.setRedirectUri(redirectUri);
token.setSuccess(false);
token.setBody(body);
return token;
}
}

View File

@@ -1,18 +1,20 @@
package im.zhaojun.zfile.cache;
package im.zhaojun.zfile.admin.model.dto;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* 缓存对象用户表示那个存储源的那个文件夹.
*
* @author zhaojun
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class DriveCacheKey {
public class StorageSourceCacheKey {
private Integer driveId;
private Integer storageId;
private String key;

View File

@@ -0,0 +1,83 @@
package im.zhaojun.zfile.admin.model.entity;
import cn.hutool.extra.servlet.ServletUtil;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import im.zhaojun.zfile.common.util.RequestHolder;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.http.HttpHeaders;
import javax.servlet.http.HttpServletRequest;
import java.io.Serializable;
import java.util.Date;
/**
* 文件下载日志 entity
*
* @author zhaojun
*/
@Data
@ApiModel(value="文件下载日志")
@TableName(value = "`download_log`")
@NoArgsConstructor
public class DownloadLog implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(value = "id", type = IdType.INPUT)
@ApiModelProperty(value = "ID, 新增无需填写", example = "1")
private Integer id;
@TableField(value = "`path`")
@ApiModelProperty(value="文件路径")
private String path;
@TableField(value = "`storage_key`")
@ApiModelProperty(value="存储源 key")
private String storageKey;
@TableField(value = "`create_time`")
@ApiModelProperty(value="访问时间")
private Date createTime;
@TableField(value = "`ip`")
@ApiModelProperty(value="访问 ip")
private String ip;
@TableField(value = "short_key")
@ApiModelProperty(value = "短链 key", example = "voldd3")
private String shortKey;
@TableField(value = "`user_agent`")
@ApiModelProperty(value="访问 user_agent")
private String userAgent;
@TableField(value = "`referer`")
@ApiModelProperty(value="访问 referer")
private String referer;
public DownloadLog(String path, String storageKey, String shortKey) {
this.path = path;
this.storageKey = storageKey;
this.shortKey = shortKey;
this.createTime = new Date();
HttpServletRequest request = RequestHolder.getRequest();
this.ip = ServletUtil.getClientIP(request);
this.referer = request.getHeader(HttpHeaders.REFERER);
this.userAgent = request.getHeader(HttpHeaders.USER_AGENT);
}
}

View File

@@ -0,0 +1,52 @@
package im.zhaojun.zfile.admin.model.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonIgnore;
import im.zhaojun.zfile.admin.model.enums.FilterConfigHiddenModeEnum;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
/**
* 存储源过滤配置 entity
*
* @author zhaojun
*/
@Data
@ApiModel(value="存储源过滤配置")
@TableName(value = "filter_config")
public class FilterConfig implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(value = "id", type = IdType.AUTO)
@ApiModelProperty(value = "ID, 新增无需填写", example = "1")
@JsonIgnore
private Integer id;
@TableField(value = "storage_id")
@ApiModelProperty(value = "存储源 ID", required = true, example = "1")
private Integer storageId;
@TableField(value = "expression")
@ApiModelProperty(value = "过滤表达式", required = true, example = "/*.png")
private String expression;
@TableField(value = "description")
@ApiModelProperty(value = "表达式描述", required = true, example = "用来辅助记忆表达式")
private String description;
@TableField(value = "mode")
@ApiModelProperty(value = "模式", required = true, example = "隐藏模式,仅隐藏: hidden, 隐藏后不可访问: inaccessible, 隐藏后不可下载: disable_download")
private FilterConfigHiddenModeEnum mode;
}

View File

@@ -0,0 +1,51 @@
package im.zhaojun.zfile.admin.model.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonIgnore;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
/**
* 密码设置 entity
*
* @author zhaojun
*/
@Data
@ApiModel(value="密码设置")
@TableName(value = "password_config")
public class PasswordConfig implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(value = "id", type = IdType.INPUT)
@ApiModelProperty(value = "ID, 新增无需填写", example = "1")
@JsonIgnore
private Integer id;
@TableField(value = "storage_id")
@ApiModelProperty(value = "存储源 ID", required = true, example = "1")
private Integer storageId;
@TableField(value = "expression")
@ApiModelProperty(value = "密码文件夹表达式", required = true, example = "/*.png")
private String expression;
@TableField(value = "password")
@ApiModelProperty(value = "密码值", required = true, example = "123456")
private String password;
@TableField(value = "description")
@ApiModelProperty(value = "表达式描述", required = true, example = "用来辅助记忆表达式")
private String description;
}

View File

@@ -0,0 +1,57 @@
package im.zhaojun.zfile.admin.model.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonIgnore;
import im.zhaojun.zfile.admin.model.enums.ReadmeDisplayModeEnum;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
/**
* readme 文档配置 entity
*
* @author zhaojun
*/
@Data
@ApiModel(value="readme 文档配置")
@TableName(value = "`readme_config`")
public class ReadmeConfig implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(value = "id", type = IdType.INPUT)
@ApiModelProperty(value = "ID, 新增无需填写", example = "1")
@JsonIgnore
private Integer id;
@TableField(value = "`storage_id`")
@ApiModelProperty(value="存储源 ID")
private Integer storageId;
@TableField(value = "`description`")
@ApiModelProperty(value = "表达式描述", required = true, example = "用来辅助记忆表达式")
private String description;
@TableField(value = "`expression`")
@ApiModelProperty(value="路径表达式")
private String expression;
@TableField(value = "`readme_text`")
@ApiModelProperty(value="readme 文本内容, 支持 md 语法.")
private String readmeText;
@TableField(value = "`display_mode`")
@ApiModelProperty(value = "显示模式", required = true, example = "readme 显示模式,支持顶部显示: top, 底部显示:bottom, 弹窗显示: dialog")
private ReadmeDisplayModeEnum displayMode;
}

View File

@@ -0,0 +1,48 @@
package im.zhaojun.zfile.admin.model.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
import java.util.Date;
/**
* 短链信息 entity
*/
@Data
@ApiModel(description = "短链信息")
@TableName(value = "short_link")
public class ShortLink implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(value = "id", type = IdType.AUTO)
@ApiModelProperty(value = "ID, 新增无需填写", example = "1")
private Integer id;
@TableField(value = "storage_id")
@ApiModelProperty(value = "存储源 ID", example = "1")
private Integer storageId;
@TableField(value = "short_key")
@ApiModelProperty(value = "短链 key", example = "voldd3")
private String shortKey;
@TableField(value = "url")
@ApiModelProperty(value = "短链 url", example = "/directlink/1/test02.png")
private String url;
@TableField(value = "create_date")
@ApiModelProperty(value = "创建时间", example = "2021-11-22 10:05")
private Date createDate;
}

View File

@@ -0,0 +1,110 @@
package im.zhaojun.zfile.admin.model.entity;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.util.BooleanUtil;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import im.zhaojun.zfile.admin.model.enums.SearchModeEnum;
import im.zhaojun.zfile.home.model.enums.StorageTypeEnum;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
/**
* 存储源基本属性 entity
*/
@Data
@ApiModel(description = "存储源基本属性")
@TableName(value = "storage_source")
public class StorageSource implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(value = "id", type = IdType.AUTO)
@ApiModelProperty(value = "ID, 新增无需填写", example = "1")
private Integer id;
@TableField(value = "`enable`")
@ApiModelProperty(value = "是否启用", example = "true")
private Boolean enable;
@TableField(value = "`enable_file_operator`")
@ApiModelProperty(value = "是否启用文件操作功能", example = "true", notes = "是否启用文件上传,编辑,删除等操作.")
private Boolean enableFileOperator;
@TableField(value = "`enable_file_anno_operator`")
@ApiModelProperty(value = "是否允许匿名进行文件操作", example = "true", notes = "是否允许匿名进行文件上传,编辑,删除等操作.")
private Boolean enableFileAnnoOperator;
@TableField(value = "`enable_cache`")
@ApiModelProperty(value = "是否开启缓存", example = "true")
private Boolean enableCache;
@TableField(value = "`name`")
@ApiModelProperty(value = "存储源名称", example = "阿里云 OSS 存储")
private String name;
@TableField(value = "`key`")
@ApiModelProperty(value = "存储源别名", example = "存储源别名,用于 URL 中展示, 如 http://ip:port/{存储源别名}")
private String key;
@TableField(value = "`remark`")
@ApiModelProperty(value = "存储源备注", example = "这是一个备注信息, 用于管理员区分不同的存储源, 此字段仅管理员可见")
private String remark;
@TableField(value = "auto_refresh_cache")
@ApiModelProperty(value = "是否开启缓存自动刷新", example = "true")
private Boolean autoRefreshCache;
@TableField(value = "`type`")
@ApiModelProperty(value = "存储源类型")
private StorageTypeEnum type;
@TableField(value = "search_enable")
@ApiModelProperty(value = "是否开启搜索", example = "true")
private Boolean searchEnable;
@TableField(value = "search_ignore_case")
@ApiModelProperty(value = "搜索是否忽略大小写", example = "true")
private Boolean searchIgnoreCase;
@TableField(value = "`search_mode`")
@ApiModelProperty(value = "搜索模式", example = "SEARCH_CACHE", notes = "仅从缓存中搜索或直接全量搜索")
private SearchModeEnum searchMode;
@TableField(value = "order_num")
@ApiModelProperty(value = "排序值", example = "1")
private Integer orderNum;
@TableField(value = "default_switch_to_img_mode")
@ApiModelProperty(value = "是否默认开启图片模式", example = "true")
private Boolean defaultSwitchToImgMode;
@TableField(value = "compatibility_readme")
@ApiModelProperty(value = "兼容 readme 模式", example = "true", notes = "兼容模式, 目录文档读取 readme.md 文件")
private Boolean compatibilityReadme;
public boolean allowOperator() {
// 允许文件操作,且允许匿名操作或者当前登录用户是管理员
return BooleanUtil.isTrue(enableFileOperator) && (BooleanUtil.isTrue(enableFileAnnoOperator) || StpUtil.isLogin());
}
}

View File

@@ -0,0 +1,53 @@
package im.zhaojun.zfile.admin.model.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import im.zhaojun.zfile.home.model.enums.StorageTypeEnum;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
/**
* 存储源拓展属性 entity
*/
@Data
@ApiModel(description = "存储源拓展属性")
@TableName(value = "storage_source_config")
public class StorageSourceConfig implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(value = "id", type = IdType.AUTO)
@ApiModelProperty(value = "ID, 新增无需填写", example = "1")
private Integer id;
@TableField(value = "`name`")
@ApiModelProperty(value = "存储源属性名称 name", example = "bucketName")
private String name;
@TableField(value = "`type`")
@ApiModelProperty(value = "存储源类型")
private StorageTypeEnum type;
@TableField(value = "title")
@ApiModelProperty(value = "存储源属性名称", example = "Bucket 名称")
private String title;
@TableField(value = "storage_id")
@ApiModelProperty(value = "存储源 id", example = "1")
private Integer storageId;
@TableField(value = "`value`")
@ApiModelProperty(value = "存储源对应的值", example = "my-bucket")
private String value;
}

View File

@@ -0,0 +1,42 @@
package im.zhaojun.zfile.admin.model.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
/**
* 系统设置 entity
*/
@Data
@ApiModel(description = "系统设置")
@TableName(value = "system_config")
public class SystemConfig implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(value = "id", type = IdType.AUTO)
@ApiModelProperty(value = "ID, 新增无需填写", example = "1")
private Integer id;
@TableField(value = "name")
@ApiModelProperty(value = "系统设置名称", example = "siteName")
private String name;
@TableField(value = "`value`")
@ApiModelProperty(value = "系统设置值", example = "ZFile 演示站")
private String value;
@TableField(value = "title")
@ApiModelProperty(value = "系统设置描述", example = "站点名称")
private String title;
}

View File

@@ -0,0 +1,31 @@
package im.zhaojun.zfile.admin.model.enums;
import com.baomidou.mybatisplus.annotation.EnumValue;
import com.fasterxml.jackson.annotation.JsonValue;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* 文件点击模式枚举, 用于控制文件是单击打开还是双击打开
*
* @author zhaojun
*/
@Getter
@AllArgsConstructor
public enum FileClickModeEnum {
/**
* 单击打开文件/文件夹
*/
CLICK("click"),
/**
* 双击打开文件/文件夹
*/
DBCLICK("dbclick");
@EnumValue
@JsonValue
private final String value;
}

View File

@@ -0,0 +1,53 @@
package im.zhaojun.zfile.admin.model.enums;
import com.baomidou.mybatisplus.annotation.EnumValue;
import com.fasterxml.jackson.annotation.JsonValue;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* 文件操作类型枚举
*
* @author zhaojun
*/
@Getter
@AllArgsConstructor
public enum FileOperatorTypeEnum {
/**
* 获取文件上传链接操作
*/
UPLOAD("上传", "upload"),
/**
* 新建文件夹操作
*/
NEW_FOLDER("新建文件夹", "new_folder"),
/**
* 删除文件&文件夹操作
*/
DELETE("删除", "delete"),
/**
* 重命名文件&文件夹操作
*/
RENAME("重命名", "rename"),
/**
* 复制文件&文件夹操作
*/
COPY("复制", "copy"),
/**
* 移动文件&文件夹操作
*/
MOVE("移动", "move");
private final String name;
@EnumValue
@JsonValue
private final String value;
}

View File

@@ -0,0 +1,36 @@
package im.zhaojun.zfile.admin.model.enums;
import com.baomidou.mybatisplus.annotation.EnumValue;
import com.fasterxml.jackson.annotation.JsonValue;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* 文件夹隐藏模式枚举
*
* @author zhaojun
*/
@Getter
@AllArgsConstructor
public enum FilterConfigHiddenModeEnum {
/**
* 仅隐藏
*/
HIDDEN("hidden"),
/**
* 隐藏并不可访问 (针对目录)
*/
INACCESSIBLE("inaccessible"),
/**
* 隐藏并不可访问 (针对文件)
*/
DISABLE_DOWNLOAD("disable_download");
@EnumValue
@JsonValue
private final String value;
}

View File

@@ -0,0 +1,36 @@
package im.zhaojun.zfile.admin.model.enums;
import com.baomidou.mybatisplus.annotation.EnumValue;
import com.fasterxml.jackson.annotation.JsonValue;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* 登陆验证方式枚举
*
* @author zhaojun
*/
@Getter
@AllArgsConstructor
public enum LoginVerifyModeEnum {
/**
* 不启用登陆模式
*/
OFF_MODE("off"),
/**
* 图形验证码模式
*/
IMG_VERIFY_MODE("image"),
/**
* 图形验证码模式
*/
TWO_FACTOR_AUTHENTICATION_MODE("2fa");
@EnumValue
@JsonValue
private final String value;
}

View File

@@ -0,0 +1,36 @@
package im.zhaojun.zfile.admin.model.enums;
import com.baomidou.mybatisplus.annotation.EnumValue;
import com.fasterxml.jackson.annotation.JsonValue;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* Readme 展示模式枚举
*
* @author zhaojun
*/
@Getter
@AllArgsConstructor
public enum ReadmeDisplayModeEnum {
/**
* 顶部显示
*/
TOP("top"),
/**
* 底部显示
*/
BOTTOM("bottom"),
/**
* 弹窗显示
*/
DIALOG("dialog");
@EnumValue
@JsonValue
private final String value;
}

View File

@@ -0,0 +1,36 @@
package im.zhaojun.zfile.admin.model.enums;
import com.baomidou.mybatisplus.annotation.EnumValue;
import com.fasterxml.jackson.annotation.JsonValue;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* Referer 防盗链类型枚举
*
* @author zhaojun
*/
@Getter
@AllArgsConstructor
public enum RefererTypeEnum {
/**
* 不启用 Referer 防盗链
*/
OFF("off"),
/**
* 启用白名单模式
*/
WHITE_LIST("white_list"),
/**
* 启用黑名单模式
*/
BLACK_LIST("black_list");
@EnumValue
@JsonValue
private final String value;
}

View File

@@ -0,0 +1,31 @@
package im.zhaojun.zfile.admin.model.enums;
import com.baomidou.mybatisplus.annotation.EnumValue;
import com.fasterxml.jackson.annotation.JsonValue;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* 文件搜索模式枚举
*
* @author zhaojun
*/
@Getter
@AllArgsConstructor
public enum SearchModeEnum {
/**
* 仅搜索缓存
*/
SEARCH_CACHE_MODE("SEARCH_CACHE"),
/**
* 搜索全部
*/
SEARCH_ALL_MODE("SEARCH_ALL");
@EnumValue
@JsonValue
private final String value;
}

View File

@@ -0,0 +1,36 @@
package im.zhaojun.zfile.admin.model.enums;
import com.baomidou.mybatisplus.annotation.EnumValue;
import com.fasterxml.jackson.annotation.JsonValue;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* 存储源参数类型枚举
*
* @author zhaojun
*/
@Getter
@AllArgsConstructor
public enum StorageParamTypeEnum {
/**
* 输入框
*/
INPUT("input"),
/**
* 下拉框
*/
SELECT("select"),
/**
* 开关
*/
SWITCH("switch");
@EnumValue
@JsonValue
private final String value;
}

View File

@@ -0,0 +1,13 @@
package im.zhaojun.zfile.admin.model.param;
import lombok.Getter;
/**
* 阿里云初始化参数
*
* @author zhaojun
*/
@Getter
public class AliyunParam extends S3BaseParam {
}

View File

@@ -0,0 +1,41 @@
package im.zhaojun.zfile.admin.model.param;
import im.zhaojun.zfile.admin.annotation.StorageParamItem;
import im.zhaojun.zfile.admin.annotation.select.impl.EncodingStorageParamSelect;
import im.zhaojun.zfile.admin.model.enums.StorageParamTypeEnum;
import lombok.Getter;
/**
* 本地存储初始化参数
*
* @author zhaojun
*/
@Getter
public class FtpParam extends ProxyDownloadParam {
@StorageParamItem(name = "域名或 IP")
private String host;
@StorageParamItem(name = "端口")
private int port;
@StorageParamItem(name = "编码格式",
defaultValue = "UTF-8",
type = StorageParamTypeEnum.SELECT,
optionsClass = EncodingStorageParamSelect.class,
description = "表示文件夹及文件名称的编码格式,不表示文本内容的编码格式.")
private String encoding;
@StorageParamItem(name = "用户名", required = false)
private String username;
@StorageParamItem(name = "密码", required = false)
private String password;
@StorageParamItem(name = "加速域名", required = false, description = "如不配置加速域名,则使用服务器中转下载, 反之则使用加速域名下载.")
private String domain;
@StorageParamItem(name = "基路径", defaultValue = "/", description = "基路径表示读取的根文件夹,不填写表示允许读取所有。如: '/''/文件夹1'")
private String basePath;
}

View File

@@ -0,0 +1,13 @@
package im.zhaojun.zfile.admin.model.param;
import lombok.Getter;
/**
* 华为云初始化参数
*
* @author zhaojun
*/
@Getter
public class HuaweiParam extends S3BaseParam {
}

View File

@@ -0,0 +1,5 @@
package im.zhaojun.zfile.admin.model.param;
public interface IStorageParam {
}

View File

@@ -0,0 +1,18 @@
package im.zhaojun.zfile.admin.model.param;
import im.zhaojun.zfile.admin.annotation.StorageParamItem;
import lombok.Getter;
/**
* 本地存储初始化参数
*
* @author zhaojun
*/
@Getter
public class LocalParam extends ProxyDownloadParam {
@StorageParamItem(name = "文件路径", description = "只支持绝对路径<br>Docker 方式部署的话需提前映射宿主机路径! " +
"(<a class='link' target='_blank' href='https://docs.docker.com/engine/reference/run/#volume-shared-filesystems'>配置文档</a>)")
private String filePath;
}

View File

@@ -0,0 +1,36 @@
package im.zhaojun.zfile.admin.model.param;
import im.zhaojun.zfile.admin.annotation.StorageParamItem;
import lombok.Getter;
/**
* 微软云初始化参数
*
* @author zhaojun
*/
@Getter
public class MicrosoftDriveParam implements IStorageParam {
@StorageParamItem(name = "clientId", defaultValue = "${zfile.onedrive.clientId}", order = 1)
private String clientId;
@StorageParamItem(name = "SecretKey", defaultValue = "${zfile.onedrive.clientSecret}", order = 2)
private String clientSecret;
@StorageParamItem(name = "回调地址", description = "如使用自定义 api, 需将此处默认的域名修改为您的域名, 如 https://xxx.com/onedrive/callback, 且需在 api 中配置为回调域名.", defaultValue = "${zfile.onedrive.redirectUri}", order = 3)
private String redirectUri;
@StorageParamItem(name = "访问令牌", link = "/onedrive/authorize", linkName = "前往获取令牌", order = 3)
private String accessToken;
@StorageParamItem(name = "刷新令牌", order = 4)
private String refreshToken;
@StorageParamItem(name = "反代域名", required = false, order = 7, description = "世纪互联版不建议启用,国际版启用后不一定比启用前快,这个要根据仔细网络情况决定.",
link = "https://docs.zfile.vip/#/advanced?id=onedrive-cf", linkName = "配置文档")
private String proxyDomain;
@StorageParamItem(name = "基路径", defaultValue = "/", order = 8, description = "基路径表示读取的根文件夹,不填写表示允许读取所有。如: '/''/文件夹1'")
private String basePath;
}

View File

@@ -0,0 +1,23 @@
package im.zhaojun.zfile.admin.model.param;
import im.zhaojun.zfile.admin.annotation.StorageParamItem;
import lombok.Getter;
/**
* MinIO 初始化参数
*
* @author zhaojun
*/
@Getter
public class MinIOParam extends S3BaseParam {
@StorageParamItem(name = "Bucket 域名 / CDN 加速域名", required = false, order = 5, description = "为 minio 的服务地址,非 web 访问地址,一般为 http://ip:9000")
private String domain;
@StorageParamItem(name = "地域", defaultValue = "auto")
private String region;
@StorageParamItem(name = "服务地址", order = 5, description = "为 minio 的服务地址,非 web 访问地址,一般为 http://ip:9000")
private String endPoint;
}

View File

@@ -0,0 +1,27 @@
package im.zhaojun.zfile.admin.model.param;
import im.zhaojun.zfile.admin.annotation.StorageParamItem;
import lombok.Getter;
/**
* OneDrive 初始化参数
*
* @author zhaojun
*/
@Getter
public class OneDriveChinaParam extends OneDriveParam {
@StorageParamItem(name = "clientId", defaultValue = "${zfile.onedrive-china.clientId}", order = 1)
private String clientId;
@StorageParamItem(name = "SecretKey", defaultValue = "${zfile.onedrive-china.clientSecret}", order = 2)
private String clientSecret;
@StorageParamItem(name = "回调地址", description = "如使用自定义 api, 需将此处默认的域名修改为您的域名, 如 https://xxx.com/onedrive/china-callback, 且需在 api 中配置为回调域名.",
defaultValue = "${zfile.onedrive-china.redirectUri}", order = 3)
private String redirectUri;
@StorageParamItem(name = "访问令牌", link = "/onedrive/china-authorize", linkName = "前往获取令牌", order = 3)
private String accessToken;
}

View File

@@ -0,0 +1,13 @@
package im.zhaojun.zfile.admin.model.param;
import lombok.Getter;
/**
* OneDrive 初始化参数
*
* @author zhaojun
*/
@Getter
public class OneDriveParam extends MicrosoftDriveParam {
}

View File

@@ -0,0 +1,13 @@
package im.zhaojun.zfile.admin.model.param;
import lombok.Getter;
/**
* 代理下载参数
*
* @author zhaojun
*/
@Getter
public class ProxyDownloadParam extends ProxyTransferParam {
}

View File

@@ -0,0 +1,24 @@
package im.zhaojun.zfile.admin.model.param;
import im.zhaojun.zfile.admin.annotation.StorageParamItem;
import im.zhaojun.zfile.admin.model.enums.StorageParamTypeEnum;
import lombok.Getter;
/**
* 代理上传下载参数
*
* @author zhaojun
*/
@Getter
public class ProxyTransferParam implements IStorageParam {
@StorageParamItem(name = "加速域名", required = false, description = "如不配置加速域名,则使用服务器中转下载, 反之则使用加速域名下载.")
private String domain;
@StorageParamItem(name = "生成签名链接", type = StorageParamTypeEnum.SWITCH, defaultValue = "true", description = "下载会生成带签名的下载链接, 如不想对外开放直链, 可以防止被当做直链使用.")
private boolean isPrivate;
@StorageParamItem(name = "下载签名有效期", required = false, defaultValue = "1800", description = "用于下载签名的有效期, 单位为秒, 如不配置则默认为 1800 秒.")
private Integer tokenTime;
}

View File

@@ -0,0 +1,10 @@
package im.zhaojun.zfile.admin.model.param;
/**
* 代理上传参数
*
* @author zhaojun
*/
public class ProxyUploadParam extends ProxyTransferParam {
}

View File

@@ -0,0 +1,13 @@
package im.zhaojun.zfile.admin.model.param;
import lombok.Getter;
/**
* 七牛云初始化参数
*
* @author zhaojun
*/
@Getter
public class QiniuParam extends S3BaseParam {
}

View File

@@ -0,0 +1,43 @@
package im.zhaojun.zfile.admin.model.param;
import im.zhaojun.zfile.admin.annotation.StorageParamItem;
import im.zhaojun.zfile.admin.model.enums.StorageParamTypeEnum;
import lombok.Getter;
/**
* S3 通用参数
*
* @author zhaojun
*/
@Getter
public class S3BaseParam implements IStorageParam {
@StorageParamItem(name = "AccessKey", order = 1)
private String accessKey;
@StorageParamItem(name = "SecretKey", order = 2)
private String secretKey;
@StorageParamItem(name = "区域", order = 3, description = "如下拉列表中没有的区域,或想使用内网地址,可直接输入后回车,如: xxx-cn-beijing.example.com")
private String endPoint;
@StorageParamItem(name = "存储空间名称", order = 4)
private String bucketName;
@StorageParamItem(name = "Bucket 域名 / CDN 加速域名", required = false, order = 5)
private String domain;
@StorageParamItem(name = "基路径", order = 6, required = false, defaultValue = "/", description = "基路径表示读取的根文件夹,不填写表示允许读取所有。如: '/''/文件夹1'")
private String basePath;
@StorageParamItem(name = "是否是私有空间", order = 7, type = StorageParamTypeEnum.SWITCH, defaultValue = "true", description = "私有空间会生成带签名的下载链接")
private boolean isPrivate;
@StorageParamItem(name = "下载签名有效期", required = false, defaultValue = "1800", description = "当为私有空间时, 用于下载签名的有效期, 单位为秒, 如不配置则默认为 1800 秒.")
private Integer tokenTime;
@StorageParamItem(name = "是否自动配置 CORS 跨域设置", order = 100, type = StorageParamTypeEnum.SWITCH, defaultValue = "true", description = "如不配置跨域设置,可能会无法导致无法上传,或上传后看不到文件")
private boolean autoConfigCors;
}

View File

@@ -0,0 +1,28 @@
package im.zhaojun.zfile.admin.model.param;
import im.zhaojun.zfile.admin.annotation.StorageParamItem;
import im.zhaojun.zfile.admin.annotation.StorageParamSelectOption;
import im.zhaojun.zfile.admin.model.enums.StorageParamTypeEnum;
import lombok.Getter;
/**
* S3 初始化参数
*
* @author zhaojun
*/
@Getter
public class S3Param extends S3BaseParam {
@StorageParamItem(name = "EndPoint", order = 3)
private String endPoint;
@StorageParamItem(name = "地域", order = 3)
private String region;
@StorageParamItem(name = "域名风格", type = StorageParamTypeEnum.SWITCH,
options = { @StorageParamSelectOption(value = "path-style", label = "path-style"),
@StorageParamSelectOption(value = "bucket-virtual-hosting", label = "bucket-virtual-hosting")},
linkName = "查看 S3 API 说明文档", link = "https://docs.aws.amazon.com/zh_cn/AmazonS3/latest/userguide/VirtualHosting.html#path-style-access")
private String pathStyle;
}

View File

@@ -0,0 +1,13 @@
package im.zhaojun.zfile.admin.model.param;
import lombok.Getter;
/**
* SFTP 初始化参数
*
* @author zhaojun
*/
@Getter
public class SftpParam extends FtpParam {
}

View File

@@ -0,0 +1,27 @@
package im.zhaojun.zfile.admin.model.param;
import im.zhaojun.zfile.admin.annotation.StorageParamItem;
import lombok.Getter;
/**
* SharePoint 世纪互联初始化参数
*
* @author zhaojun
*/
@Getter
public class SharePointChinaParam extends SharePointParam {
@StorageParamItem(name = "clientId", defaultValue = "${zfile.onedrive-china.clientId}", order = 1)
private String clientId;
@StorageParamItem(name = "SecretKey", defaultValue = "${zfile.onedrive-china.clientSecret}", order = 2)
private String clientSecret;
@StorageParamItem(name = "回调地址", description = "如使用自定义 api, 需将此处默认的域名修改为您的域名, 如 https://xxx.com/onedrive/china-callback, 且需在 api 中配置为回调域名.",
defaultValue = "${zfile.onedrive-china.redirectUri}", order = 3)
private String redirectUri;
@StorageParamItem(name = "访问令牌", link = "/onedrive/china-authorize", linkName = "前往获取令牌", order = 3)
private String accessToken;
}

View File

@@ -0,0 +1,26 @@
package im.zhaojun.zfile.admin.model.param;
import im.zhaojun.zfile.admin.annotation.StorageParamItem;
import lombok.Getter;
/**
* SharePoint 初始化参数
*
* @author zhaojun
*/
@Getter
public class SharePointParam extends MicrosoftDriveParam {
@StorageParamItem(name = "clientId", defaultValue = "${zfile.onedrive.clientId}", order = 1)
private String clientId;
@StorageParamItem(name = "SecretKey", defaultValue = "${zfile.onedrive.clientSecret}", order = 2)
private String clientSecret;
@StorageParamItem(name = "网站", order = 5)
private String siteId;
@StorageParamItem(name = "子目录", order = 6, description = "表示 SharePoint 子列表/子网站,在世纪互联网站 Tab 卡中 \"网站内容\" 新增.")
private String listId;
}

View File

@@ -0,0 +1,17 @@
package im.zhaojun.zfile.admin.model.param;
import im.zhaojun.zfile.admin.annotation.StorageParamItem;
import lombok.Getter;
/**
* 腾讯云初始化参数
*
* @author zhaojun
*/
@Getter
public class TencentParam extends S3BaseParam {
@StorageParamItem(key = "secretId", name = "SecretId", order = 1)
private String accessKey;
}

View File

@@ -0,0 +1,35 @@
package im.zhaojun.zfile.admin.model.param;
import im.zhaojun.zfile.admin.annotation.StorageParamItem;
import lombok.Getter;
/**
* 又拍云初始化参数
*
* @author zhaojun
*/
@Getter
public class UpYunParam implements IStorageParam {
@StorageParamItem(name = "存储空间名称")
private String bucketName;
@StorageParamItem(name = "用户名")
private String username;
@StorageParamItem(name = "密码")
private String password;
@StorageParamItem(name = "下载域名", description = "填写您在又拍云绑定的域名.")
private String domain;
@StorageParamItem(name = "基路径", defaultValue = "/", description = "基路径表示读取的根文件夹,不填写表示允许读取所有。如: '/''/文件夹1'")
private String basePath;
@StorageParamItem(name = "Token", required = false, link = "https://help.upyun.com/knowledge-base/cdn-token-limite/", linkName = "官方配置文档",description = "可在又拍云后台开启 \"访问控制\" -> \"Token 防盗链\",控制资源内容的访问时限,即时间戳防盗链。")
private String token;
@StorageParamItem(name = "Token 有效期", required = false, defaultValue = "1800", description = "Token (防盗链)有效期,单位为秒。")
private int tokenTime;
}

View File

@@ -0,0 +1,23 @@
package im.zhaojun.zfile.admin.model.param;
import im.zhaojun.zfile.admin.annotation.StorageParamItem;
import lombok.Getter;
/**
* WebDav 初始化参数
*
* @author zhaojun
*/
@Getter
public class WebdavParam extends ProxyDownloadParam {
@StorageParamItem(key = "url", name = "WebDAV 链接")
private String url;
@StorageParamItem(key = "username", name = "用户名", required = false)
private String username;
@StorageParamItem(key = "password", name = "密码", required = false)
private String password;
}

View File

@@ -0,0 +1,23 @@
package im.zhaojun.zfile.admin.model.request;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
* 下载排行请求类
*
* @author zhaojun
*/
@Data
public class DownloadTopInfoRequest {
@ApiModelProperty(value = "排行数量", required = true)
private Integer top;
@ApiModelProperty(value = "开始时间")
private String startTime;
@ApiModelProperty(value = "结束时间")
private String endTime;
}

View File

@@ -0,0 +1,72 @@
package im.zhaojun.zfile.admin.model.request;
import com.baomidou.mybatisplus.annotation.TableField;
import im.zhaojun.zfile.admin.model.enums.SearchModeEnum;
import im.zhaojun.zfile.home.model.dto.StorageSourceAllParam;
import im.zhaojun.zfile.home.model.enums.StorageTypeEnum;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
* 保存存储源信息请求类
*
* @author zhaojun
*/
@Data
@ApiModel(description = "存储源基本参数")
public class SaveStorageSourceRequest {
@ApiModelProperty(value = "ID, 新增无需填写", example = "1")
private Integer id;
@ApiModelProperty(value = "存储源名称", example = "阿里云 OSS 存储")
private String name;
@ApiModelProperty(value = "存储源别名", example = "存储源别名,用于 URL 中展示, 如 http://ip:port/{存储源别名}")
private String key;
@ApiModelProperty(value = "存储源备注", example = "这是一个备注信息, 用于管理员区分不同的存储源, 此字段仅管理员可见")
private String remark;
@ApiModelProperty(value = "存储源类型", example = "ftp")
private StorageTypeEnum type;
@ApiModelProperty(value = "是否启用", example = "true")
private Boolean enable;
@ApiModelProperty(value = "是否启用文件操作功能", example = "true", notes = "是否启用文件上传,编辑,删除等操作.")
private Boolean enableFileOperator;
@ApiModelProperty(value = "是否允许匿名进行文件操作", example = "true", notes = "是否允许匿名进行文件上传,编辑,删除等操作.")
private Boolean enableFileAnnoOperator;
@ApiModelProperty(value = "是否开启缓存", example = "true")
private boolean enableCache;
@ApiModelProperty(value = "是否开启缓存自动刷新", example = "true")
private boolean autoRefreshCache;
@ApiModelProperty(value = "是否开启搜索", example = "true")
private boolean searchEnable;
@ApiModelProperty(value = "搜索是否忽略大小写", example = "true")
private boolean searchIgnoreCase;
@TableField(value = "`search_mode`")
@ApiModelProperty(value = "搜索模式", example = "SEARCH_CACHE", notes = "仅从缓存中搜索或直接全量搜索")
private SearchModeEnum searchMode;
@ApiModelProperty(value = "排序值", example = "1")
private Integer orderNum;
@ApiModelProperty(value = "存储源拓展属性")
private StorageSourceAllParam storageSourceAllParam;
@ApiModelProperty(value = "是否默认开启图片模式", example = "true")
private boolean defaultSwitchToImgMode;
@ApiModelProperty(value = "兼容 readme 模式", example = "true", notes = "兼容模式, 目录文档读取 readme.md 文件")
private boolean compatibilityReadme;
}

View File

@@ -0,0 +1,15 @@
package im.zhaojun.zfile.admin.model.request.link;
import lombok.Data;
import java.util.List;
/**
* @author zhaojun
*/
@Data
public class BatchDeleteRequest {
private List<Integer> ids;
}

View File

@@ -0,0 +1,46 @@
package im.zhaojun.zfile.admin.model.request.link;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotEmpty;
/**
* 查询下载日志请求参数
*
* @author zhaojun
*/
@Data
public class QueryDownloadLogRequest {
@ApiModelProperty(value="文件路径")
private String path;
@ApiModelProperty(value="存储源 key")
private String storageKey;
@ApiModelProperty(value="短链 key")
private String shortKey;
@ApiModelProperty(value="访问时间从")
private String dateFrom;
@ApiModelProperty(value="访问时间至")
private String dateTo;
@ApiModelProperty(value="访问 ip")
private String ip;
@ApiModelProperty(value="访问 user_agent")
private String userAgent;
@ApiModelProperty(value="访问 referer")
private String referer;
@NotEmpty(message = "分页页数不能为空")
private Integer page;
@NotEmpty(message = "每页条数不能为空")
private Integer limit;
}

View File

@@ -0,0 +1,28 @@
package im.zhaojun.zfile.admin.model.request.login;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import javax.validation.constraints.NotBlank;
/**
* 验证 2FA 认证返回结果
*
* @author zhaojun
*/
@Data
@AllArgsConstructor
@ApiModel(description = "验证二步验证结果")
public class VerifyLogin2FARequest {
@ApiModelProperty(value = "二步验证二维码", required = true, example = "EwBoxxxxxxxxxxxxxxxbAI=")
@NotBlank(message = "二步验证密钥不能为空")
private String secret;
@ApiModelProperty(value = "APP 生成的二步验证验证码", required = true, example = "125612")
@NotBlank(message = "二步验证验证码不能为空")
private String code;
}

View File

@@ -0,0 +1,34 @@
package im.zhaojun.zfile.admin.model.request.s3;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotBlank;
/**
* 获取 S3 bucket 列表请求类
*
* @author zhaojun
*/
@Data
@ApiModel(value="S3 bucket 列表请求类")
public class GetS3BucketListRequest {
@NotBlank(message = "accessKey 不能为空")
@ApiModelProperty(value = "accessKey", required = true, example = "XQEWQJI129JAS12")
private String accessKey;
@NotBlank(message = "secretKey 不能为空")
@ApiModelProperty(value = "secretKey", required = true, example = "EWQJI129JAS11AE2")
private String secretKey;
@NotBlank(message = "EndPoint 不能为空")
@ApiModelProperty(value = "Endpoint 接入点", required = true, example = "oss-cn-beijing.aliyuncs.com")
private String endPoint;
@ApiModelProperty(value = "Endpoint 接入点", required = true, example = "cn-beijing")
// @NotBlank(message = "地域不能为空")
private String region;
}

View File

@@ -0,0 +1,41 @@
package im.zhaojun.zfile.admin.model.request.setting;
import im.zhaojun.zfile.admin.model.enums.RefererTypeEnum;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
* 直链设置请求参数类
*
* @author zhaojun
*/
@Data
@ApiModel(description = "直链设置请求参数类")
public class UpdateLinkSettingRequest {
@ApiModelProperty(value = "是否记录下载日志", example = "true")
private Boolean recordDownloadLog;
@ApiModelProperty(value = "直链 Referer 防盗链类型")
private RefererTypeEnum refererType;
@ApiModelProperty(value = "直链 Referer 是否允许为空")
private Boolean refererAllowEmpty;
@ApiModelProperty(value = "直链 Referer 值")
private String refererValue;
@ApiModelProperty(value = "直链地址前缀")
private String directLinkPrefix;
@ApiModelProperty(value = "是否显示生成直链功能(含直链和路径短链)", example = "true", required = true)
private Boolean showLinkBtn;
@ApiModelProperty(value = "是否显示生成短链功能", example = "true", required = true)
private Boolean showShortLink;
@ApiModelProperty(value = "是否显示生成路径链接功能", example = "true", required = true)
private Boolean showPathLink;
}

View File

@@ -0,0 +1,26 @@
package im.zhaojun.zfile.admin.model.request.setting;
import im.zhaojun.zfile.admin.model.enums.LoginVerifyModeEnum;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
* 登陆安全设置请求参数类
*
* @author zhaojun
*/
@Data
@ApiModel(description = "登陆安全设置请求参数类")
public class UpdateSecuritySettingRequest {
@ApiModelProperty(value = "是否在前台显示登陆按钮", example = "true")
private Boolean showLogin;
@ApiModelProperty(value = "登陆验证方式,支持验证码和 2FA 认证")
private LoginVerifyModeEnum loginVerifyMode;
@ApiModelProperty(value = "登陆验证 Secret")
private String loginVerifySecret;
}

View File

@@ -0,0 +1,38 @@
package im.zhaojun.zfile.admin.model.request.setting;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotBlank;
/**
* 站点设置请求参数类
*
* @author zhaojun
*/
@Data
@ApiModel(description = "站点设置请求参数类")
public class UpdateSiteSettingRequest {
@ApiModelProperty(value = "站点名称", required = true, example = "ZFile Site Name")
@NotBlank(message = "站点名称不能为空")
private String siteName;
@ApiModelProperty(value = "站点域名", required = true, example = "https://zfile.vip")
@NotBlank(message = "站点域名不能为空")
private String domain;
@ApiModelProperty(value = "前端域名", notes = "前端域名,前后端分离情况下需要配置.", example = "http://xxx.example.com")
private String frontDomain;
@ApiModelProperty(value = "头像地址", example = "https://cube.elemecdn.com/3/7c/3ea6beec64369c2642b92c6726f1epng.png")
private String avatar;
@ApiModelProperty(value = "备案号", example = "冀ICP备12345678号-1")
private String icp;
@ApiModelProperty(value = "最大同时上传文件数", example = "5")
private Integer maxFileUploads;
}

View File

@@ -0,0 +1 @@
package im.zhaojun.zfile.admin.model.request.setting;

View File

@@ -0,0 +1,56 @@
package im.zhaojun.zfile.admin.model.request.setting;
import im.zhaojun.zfile.admin.model.enums.FileClickModeEnum;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
* 显示设置请求参数类
*
* @author zhaojun
*/
@Data
@ApiModel(description = "显示设置请求参数类")
public class UpdateViewSettingRequest {
@ApiModelProperty(value = "根目录是否显示所有存储源", notes = "根目录是否显示所有存储源, 如果为 true, 则根目录显示所有存储源列表, 如果为 false, 则会自动跳转到第一个存储源.", example = "true", required = true)
private Boolean rootShowStorage;
@ApiModelProperty(value = "页面布局", notes = "full:全屏,center:居中", example = "full", required = true)
private String layout;
@ApiModelProperty(value = "列表尺寸", notes = "large:大,default:中,small:小", example = "default", required = true)
private String tableSize;
@ApiModelProperty(value = "自定义视频文件后缀格式")
private String customVideoSuffix;
@ApiModelProperty(value = "自定义图像文件后缀格式")
private String customImageSuffix;
@ApiModelProperty(value = "自定义音频文件后缀格式")
private String customAudioSuffix;
@ApiModelProperty(value = "自定义文本文件后缀格式")
private String customTextSuffix;
@ApiModelProperty(value = "是否显示文档区", example = "true", required = true)
private Boolean showDocument;
@ApiModelProperty(value = "是否显示网站公告", example = "true", required = true)
private Boolean showAnnouncement;
@ApiModelProperty(value = "网站公告", example = "ZFile 网站公告")
private String announcement;
@ApiModelProperty(value = "自定义 CSS")
private String customCss;
@ApiModelProperty(value = "自定义 JS")
private String customJs;
@ApiModelProperty(value = "默认文件点击习惯", example = "click")
private FileClickModeEnum fileClickMode;
}

View File

@@ -0,0 +1,47 @@
package im.zhaojun.zfile.admin.model.result.link;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import im.zhaojun.zfile.home.model.enums.StorageTypeEnum;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.Date;
/**
* 下载日志结果类
*
* @author zhaojun
*/
@Data
public class DownloadLogResult {
@TableId(value = "id", type = IdType.INPUT)
@ApiModelProperty(value="")
private Integer id;
@ApiModelProperty(value="文件路径")
private String path;
@ApiModelProperty(value = "存储源名称", example = "我的本地存储")
private String storageName;
@ApiModelProperty(value = "存储源类型")
private StorageTypeEnum storageType;
@ApiModelProperty(value = "短链 Key")
private String shortKey;
@ApiModelProperty(value="访问时间")
private Date createTime;
@ApiModelProperty(value="访问 ip")
private String ip;
@ApiModelProperty(value="访问 user_agent")
private String userAgent;
@ApiModelProperty(value="访问 referer")
private String referer;
}

View File

@@ -0,0 +1,35 @@
package im.zhaojun.zfile.admin.model.result.link;
import im.zhaojun.zfile.home.model.enums.StorageTypeEnum;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.Date;
/**
* 短链结果类
*
* @author zhaojun
*/
@Data
public class ShortLinkResult {
@ApiModelProperty(value = "短链 id", example = "1")
private Integer id;
@ApiModelProperty(value = "存储源名称", example = "我的本地存储")
private String storageName;
@ApiModelProperty(value = "存储源类型")
private StorageTypeEnum storageType;
@ApiModelProperty(value = "短链 key", example = "voldd3")
private String shortKey;
@ApiModelProperty(value = "文件 url", example = "/directlink/1/test02.png")
private String url;
@ApiModelProperty(value = "创建时间", example = "2021-11-22 10:05")
private Date createDate;
}

View File

@@ -0,0 +1,24 @@
package im.zhaojun.zfile.admin.model.result.login;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
/**
* 登陆 2FA 认证生成返回结果
*
* @author zhaojun
*/
@Data
@AllArgsConstructor
@ApiModel(description = "生成二步验证结果")
public class Login2FAResult {
@ApiModelProperty(value = "二步验证二维码")
private String qrcode;
@ApiModelProperty(value = "二步验证密钥")
private String secret;
}

View File

@@ -0,0 +1,22 @@
package im.zhaojun.zfile.admin.model.result.login;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
* 生成图片验证码结果类
*
* @author zhaojun
*/
@Data
@ApiModel(description = "生成图片验证码结果类")
public class LoginVerifyImgResult {
@ApiModelProperty(value = "验证码图片", example = "data:image/png;base64,iajsiAAA...")
private String imgBase64;
@ApiModelProperty(value = "验证码 UUID", example = "c140a792-4ca2-4dac-8d4c-35750b78524f")
private String uuid;
}

View File

@@ -0,0 +1,26 @@
package im.zhaojun.zfile.admin.model.result.s3;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import java.util.Date;
/**
* S3 bucket 名称结果类
*
* @author zhaojun
*/
@Data
@AllArgsConstructor
@ApiModel(value="S3 bucket 名称结果类")
public class S3BucketNameResult {
@ApiModelProperty(value = "bucket 名称", example = "zfile")
private String name;
@ApiModelProperty(value = "bucket 创建时间", example = "2022-01-01 15:22")
private Date date;
}

View File

@@ -0,0 +1,25 @@
package im.zhaojun.zfile.admin.model.result.sharepoint;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
* Sharepoint 站点信息
*
* @author zhaojun
*/
@Data
@ApiModel(description = "SharePoint 站点结果类")
public class SharepointSite {
@ApiModelProperty(value="站点 id")
private String id;
@ApiModelProperty(value="站点名称")
private String displayName;
@ApiModelProperty(value="站点地址")
private String webUrl;
}

View File

@@ -0,0 +1,30 @@
package im.zhaojun.zfile.admin.model.result.sharepoint;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.Date;
/**
* Sharepoint 网站 list 列表
*
* @author zhaojun
*/
@Data
@ApiModel(description = "Sharepoint 网站 list 列表")
public class SharepointSiteList {
@ApiModelProperty(value="站点目录 id")
private String id;
@ApiModelProperty(value="站点目录名称")
private String displayName;
@ApiModelProperty(value="站点目录创建时间")
private Date createdDateTime;
@ApiModelProperty(value="站点目录地址")
private String webUrl;
}

View File

@@ -0,0 +1,85 @@
package im.zhaojun.zfile.admin.model.result.storage;
import im.zhaojun.zfile.admin.model.enums.SearchModeEnum;
import im.zhaojun.zfile.common.cache.RefreshTokenCache;
import im.zhaojun.zfile.home.model.enums.StorageTypeEnum;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
* 存储源设置后台管理 Result
*
* @author zhaojun
*/
@Data
@ApiModel(description = "存储源设置后台管理 Result")
public class StorageSourceAdminResult {
@ApiModelProperty(value = "ID, 新增无需填写", example = "1")
private Integer id;
@ApiModelProperty(value = "是否启用", example = "true")
private Boolean enable;
@ApiModelProperty(value = "是否启用文件操作功能", example = "true", notes = "是否启用文件上传,编辑,删除等操作.")
private Boolean enableFileOperator;
@ApiModelProperty(value = "是否允许匿名进行文件操作", example = "true", notes = "是否允许匿名进行文件上传,编辑,删除等操作.")
private Boolean enableFileAnnoOperator;
@ApiModelProperty(value = "是否开启缓存", example = "true")
private Boolean enableCache;
@ApiModelProperty(value = "存储源名称", example = "阿里云 OSS 存储")
private String name;
@ApiModelProperty(value = "存储源别名", example = "存储源别名,用于 URL 中展示, 如 http://ip:port/{存储源别名}")
private String key;
@ApiModelProperty(value = "存储源备注", example = "这是一个备注信息, 用于管理员区分不同的存储源, 此字段仅管理员可见")
private String remark;
@ApiModelProperty(value = "是否开启缓存自动刷新", example = "true")
private Boolean autoRefreshCache;
@ApiModelProperty(value = "存储源类型")
private StorageTypeEnum type;
@ApiModelProperty(value = "是否开启搜索", example = "true")
private Boolean searchEnable;
@ApiModelProperty(value = "搜索是否忽略大小写", example = "true")
private Boolean searchIgnoreCase;
@ApiModelProperty(value = "搜索模式", example = "SEARCH_CACHE", notes = "仅从缓存中搜索或直接全量搜索")
private SearchModeEnum searchMode;
@ApiModelProperty(value = "排序值", example = "1")
private Integer orderNum;
@ApiModelProperty(value = "是否默认开启图片模式", example = "true")
private Boolean defaultSwitchToImgMode;
@ApiModelProperty(value = "存储源刷新信息")
private RefreshTokenCache.RefreshTokenInfo refreshTokenInfo;
@ApiModelProperty(value = "兼容 readme 模式", example = "true", notes = "兼容模式, 目录文档读取 readme.md 文件")
private Boolean compatibilityReadme;
}

View File

@@ -1,9 +1,11 @@
package im.zhaojun.zfile.model.support;
package im.zhaojun.zfile.admin.model.verify;
import lombok.Data;
/**
* 用于表示校验结果的类
*
* @author zhaojun
*/
@Data
public class VerifyResult {
@@ -23,19 +25,26 @@ public class VerifyResult {
*/
private Integer code;
/**
* 表达式
*/
private String pattern;
public static VerifyResult success() {
VerifyResult verifyResult = new VerifyResult();
verifyResult.setPassed(true);
return verifyResult;
}
public static VerifyResult fail(String msg) {
public static VerifyResult success(String pattern) {
VerifyResult verifyResult = new VerifyResult();
verifyResult.setPassed(false);
verifyResult.setMsg(msg);
verifyResult.setPassed(true);
verifyResult.setPattern(pattern);
return verifyResult;
}
public static VerifyResult fail(String msg, Integer code) {
VerifyResult verifyResult = new VerifyResult();
verifyResult.setPassed(false);

View File

@@ -0,0 +1,17 @@
package im.zhaojun.zfile.admin.service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import im.zhaojun.zfile.admin.mapper.DownloadLogMapper;
import im.zhaojun.zfile.admin.model.entity.DownloadLog;
import org.springframework.stereotype.Service;
/**
* 下载日志 Service
*
* @author zhaojun
*/
@Service
public class DownloadLogService extends ServiceImpl<DownloadLogMapper, DownloadLog> {
}

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