mirror of
https://github.com/zfile-dev/zfile.git
synced 2025-04-19 05:34:52 +00:00
Compare commits
171 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
91a7092190 | ||
|
|
f82155f157 | ||
|
|
a99218dfa5 | ||
|
|
3e9fe27890 | ||
|
|
7524f58928 | ||
|
|
6499f2d220 | ||
|
|
40b1f1bc2d | ||
|
|
3bd859d705 | ||
|
|
6156d85ba3 | ||
|
|
e1df2f886b | ||
|
|
cea42a57bb | ||
|
|
c123d2a671 | ||
|
|
02e00b765b | ||
|
|
1992c1f52d | ||
|
|
4eb9a721fc | ||
|
|
f1bac40af4 | ||
|
|
0a7fb41e81 | ||
|
|
4fd0b8d442 | ||
|
|
28150b0c1a | ||
|
|
a7813ff7bc | ||
|
|
ae500ef9dc | ||
|
|
29d5b84df2 | ||
|
|
28882b198c | ||
|
|
d624c886fe | ||
|
|
e08654a59e | ||
|
|
8fa6a5c9b8 | ||
|
|
7620a578fb | ||
|
|
9c9bf93f00 | ||
|
|
912eb694cb | ||
|
|
78d5ba90cf | ||
|
|
056f9d4449 | ||
|
|
9a6020dcc8 | ||
|
|
6b3025f379 | ||
|
|
9dffaaee25 | ||
|
|
bda654a012 | ||
|
|
52271b5117 | ||
|
|
223a6c1970 | ||
|
|
60c272b714 | ||
|
|
3b6ed1c78d | ||
|
|
5d888bb68f | ||
|
|
082bb07213 | ||
|
|
803b8cdf71 | ||
|
|
eca5f7e48b | ||
|
|
b70c37f3f0 | ||
|
|
5cb2844141 | ||
|
|
4dd6cdb4b3 | ||
|
|
c6127c029f | ||
|
|
e149039ecb | ||
|
|
37688d83cf | ||
|
|
6692016642 | ||
|
|
3f41aeda9a | ||
|
|
de86d5c47d | ||
|
|
c89e072005 | ||
|
|
b533b5e959 | ||
|
|
d35cf27d47 | ||
|
|
796c4c1fb0 | ||
|
|
1033d6c1a9 | ||
|
|
e09c6b4e58 | ||
|
|
168b0b08f3 | ||
|
|
60a6a5348c | ||
|
|
2ec8a5df1f | ||
|
|
47b5f6ac12 | ||
|
|
c64c8465f2 | ||
|
|
f636681dd8 | ||
|
|
eadd2434e0 | ||
|
|
b84c0bff42 | ||
|
|
4cb5b84bfe | ||
|
|
0351b4401c | ||
|
|
48cb14be8a | ||
|
|
eea2ff11f9 | ||
|
|
325ec1a348 | ||
|
|
93205266d3 | ||
|
|
6849a4347f | ||
|
|
cb5c6a5945 | ||
|
|
5ed45c3bb3 | ||
|
|
4442ec3165 | ||
|
|
b268a24333 | ||
|
|
84f9354d4e | ||
|
|
8dfc4f8004 | ||
|
|
1158f5c2b9 | ||
|
|
c5f0e15207 | ||
|
|
68a842ce75 | ||
|
|
3bd4f74dae | ||
|
|
4a0bdc3baf | ||
|
|
603c1b4654 | ||
|
|
1136d582df | ||
|
|
187544fc06 | ||
|
|
aa3cde8f59 | ||
|
|
e29a702b6e | ||
|
|
e4f663c9f0 | ||
|
|
fb08ef6e78 | ||
|
|
10c465d159 | ||
|
|
d15d1203b7 | ||
|
|
de48ed3b61 | ||
|
|
d22e2e872a | ||
|
|
7da1b454dc | ||
|
|
463f311dd3 | ||
|
|
73b42cf654 | ||
|
|
1fac59c4cd | ||
|
|
6ed6b4a019 | ||
|
|
7bd02437f0 | ||
|
|
57aeb5771c | ||
|
|
695c03a530 | ||
|
|
6ebc403572 | ||
|
|
7ff6fe43b5 | ||
|
|
b34f141181 | ||
|
|
87dd7b58d1 | ||
|
|
2a949db5d2 | ||
|
|
b889e91fb5 | ||
|
|
b5c757f9f0 | ||
|
|
a465f48b94 | ||
|
|
797a0a0e4c | ||
|
|
e7ff159b6d | ||
|
|
a9fbf54bb2 | ||
|
|
81f9e262f5 | ||
|
|
23bb3960ab | ||
|
|
c4a17985a4 | ||
|
|
75ddcd47f4 | ||
|
|
2dd03ae490 | ||
|
|
5b383c8741 | ||
|
|
73198d7852 | ||
|
|
fb0d9721aa | ||
|
|
b24c663fd6 | ||
|
|
6e62cfc84d | ||
|
|
eee22e9dc9 | ||
|
|
5109c51ffc | ||
|
|
66d6d311ea | ||
|
|
ef7cbdcbd7 | ||
|
|
63bcbebb4b | ||
|
|
50ce1bb6db | ||
|
|
3c88659679 | ||
|
|
d79a993eea | ||
|
|
afafb311b8 | ||
|
|
2e280e4931 | ||
|
|
ed6efac8b7 | ||
|
|
7409df85d7 | ||
|
|
4d42529c4d | ||
|
|
65224685c8 | ||
|
|
080a84986e | ||
|
|
3f8beb2f0b | ||
|
|
410a87c426 | ||
|
|
c14b8343d2 | ||
|
|
bea440f6c3 | ||
|
|
6a5fe15121 | ||
|
|
e920ab0ec0 | ||
|
|
537e3e0563 | ||
|
|
e208dc7c4c | ||
|
|
ed64910a53 | ||
|
|
5b075c3505 | ||
|
|
a8e6d9af6a | ||
|
|
2b21d8a73c | ||
|
|
e30289d21b | ||
|
|
3b6e2be7fe | ||
|
|
43c12aa8a7 | ||
|
|
c03a7710c0 | ||
|
|
1833b23d84 | ||
|
|
f3e393972d | ||
|
|
4f46c13369 | ||
|
|
f181959218 | ||
|
|
11effc0ae7 | ||
|
|
c8397e17bf | ||
|
|
ed32b9f1d4 | ||
|
|
4e184936db | ||
|
|
fe6aebfdee | ||
|
|
d65e1a442d | ||
|
|
34647793c8 | ||
|
|
e8c249b9ea | ||
|
|
d1e613dc10 | ||
|
|
1adcfee96f | ||
|
|
75f5de6b9a | ||
|
|
499942ef70 |
2
.github/ISSUE_TEMPLATE/bug_report.md
vendored
2
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@@ -16,7 +16,7 @@ assignees: ''
|
||||
请确认你已经做了下面这些事情,若 bug 还是未解决,那么请尽可详细地描述你的问题。
|
||||
|
||||
- 我已经安装了最新版的 ZFile
|
||||
- 我已经阅读了 ZFile 的文档:http://docs.zhaojun.im/zfile
|
||||
- 我已经阅读了 ZFile 的文档:https://docs.zfile.vip
|
||||
- 我已经搜索了已有的 Issues 列表中有关的信息
|
||||
- 我已经清理过浏览器缓存并重试
|
||||
-->
|
||||
|
||||
15
.gitignore
vendored
15
.gitignore
vendored
@@ -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
181
API.md
@@ -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
|
||||
}
|
||||
}
|
||||
```
|
||||
234
README.md
234
README.md
@@ -1,38 +1,66 @@
|
||||
# Z-File
|
||||
<p 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">
|
||||
<img src="https://api.codacy.com/project/badge/Grade/70b793267f7941d58cbd93f50c9a8e0a">
|
||||
<img src="https://img.shields.io/github/last-commit/zhaojun1998/zfile.svg?style=flat-square">
|
||||
<img src="https://img.shields.io/github/downloads/zhaojun1998/zfile/total?style=flat-square">
|
||||
<img src="https://img.shields.io/github/v/release/zhaojun1998/zfile?style=flat-square">
|
||||
<img src="https://img.shields.io/github/commit-activity/y/zhaojun1998/zfile?style=flat-square">
|
||||
<br>
|
||||
<img src="https://img.shields.io/github/issues/zhaojun1998/zfile?style=flat-square">
|
||||
<img src="https://img.shields.io/github/issues-closed-raw/zhaojun1998/zfile?style=flat-square">
|
||||
<img src="https://img.shields.io/github/forks/zhaojun1998/zfile?style=flat-square">
|
||||
<img src="https://img.shields.io/github/stars/zhaojun1998/zfile?style=flat-square">
|
||||
<img src="https://img.shields.io/github/watchers/zhaojun1998/zfile?style=flat-square">
|
||||
</p>
|
||||
|
||||

|
||||
[](https://www.codacy.com/manual/zhaojun1998/zfile?utm_source=github.com&utm_medium=referral&utm_content=zhaojun1998/zfile&utm_campaign=Badge_Grade)
|
||||

|
||||

|
||||
## 相关地址
|
||||
|
||||
此项目是一个在线文件目录的程序, 支持各种对象存储和本地存储, 使用定位是个人放常用工具下载, 或做公共的文件库. 不会向多账户方向开发.
|
||||
预览地址: [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,62 +96,117 @@ chmod +x zfile/bin/*.sh
|
||||
~/zfile/bin/start.sh
|
||||
```
|
||||
|
||||
篇幅有限, 更详细的安装教程及介绍请参考: [ZFile 文档](http://zhaojun.im/zfile-install)
|
||||
|
||||
访问地址:
|
||||
</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'
|
||||
image: zhaojun1998/zfile
|
||||
```
|
||||
|
||||
|
||||
</details>
|
||||
|
||||
---
|
||||
|
||||
|
||||
篇幅有限, 更详细的安装教程及介绍请参考: [ZFile 文档](https://docs.zfile.vip)
|
||||
|
||||
## 预览
|
||||
|
||||

|
||||

|
||||

|
||||

|
||||

|
||||

|
||||

|
||||

|
||||

|
||||

|
||||

|
||||

|
||||

|
||||

|
||||
|
||||
## 常见问题
|
||||
|
||||
|
||||
### 默认路径
|
||||
|
||||
默认 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] 架构调整 - 支持多存储策略
|
||||
- [ ] 新功能 - 后台支持上传、编辑、删除等操作
|
||||
- [ ] 新功能 - WebDav 支持
|
||||
- [ ] 新功能 - 离线下载 (aria2)
|
||||
- [ ] 体验优化 - 忽略文件列表 (正则表达式)
|
||||
- [ ] 体验优化 - 自定义支持预览的文件后缀 (正则表达式)
|
||||
- [ ] 体验优化 - 一键安装脚本
|
||||
|
||||
## 支持作者
|
||||
|
||||
如果本项目对你有帮助,请作者喝杯咖啡吧。
|
||||
|
||||
<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
|
||||
|
||||
[](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>
|
||||
222
pom.xml
222
pom.xml
@@ -1,28 +1,28 @@
|
||||
<?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.6</version>
|
||||
<relativePath/> <!-- lookup parent from repository -->
|
||||
</parent>
|
||||
|
||||
<groupId>im.zhaojun</groupId>
|
||||
<artifactId>zfile</artifactId>
|
||||
<version>2.8</version>
|
||||
<version>4.0.5</version>
|
||||
<name>zfile</name>
|
||||
<packaging>war</packaging>
|
||||
<packaging>jar</packaging>
|
||||
<description>一个在线的文件浏览系统</description>
|
||||
|
||||
<properties>
|
||||
<java.version>1.8</java.version>
|
||||
<log4j2.version>2.17.0</log4j2.version>
|
||||
<org.mapstruct.version>1.5.1.Final</org.mapstruct.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
|
||||
<!-- spring boot 官方相关 -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
@@ -32,14 +32,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>
|
||||
@@ -50,20 +42,21 @@
|
||||
<artifactId>spring-boot-starter-cache</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.baomidou</groupId>
|
||||
<artifactId>mybatis-plus-boot-starter</artifactId>
|
||||
<version>3.5.2</version>
|
||||
</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>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>mysql</groupId>
|
||||
<artifactId>mysql-connector-java</artifactId>
|
||||
<version>8.0.29</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
|
||||
@@ -71,7 +64,7 @@
|
||||
<dependency>
|
||||
<groupId>cn.hutool</groupId>
|
||||
<artifactId>hutool-all</artifactId>
|
||||
<version>5.1.3</version>
|
||||
<version>5.8.3</version>
|
||||
</dependency>
|
||||
|
||||
<!-- 存储策略相关 API, 对象存储、FTP、 Rest API-->
|
||||
@@ -83,26 +76,36 @@
|
||||
<dependency>
|
||||
<groupId>com.amazonaws</groupId>
|
||||
<artifactId>aws-java-sdk-s3</artifactId>
|
||||
<version>1.11.699</version>
|
||||
<version>1.12.146</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.qiniu</groupId>
|
||||
<artifactId>qiniu-java-sdk</artifactId>
|
||||
<version>7.11.0</version>
|
||||
</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>
|
||||
<version>1.18.24</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.squareup.okhttp3</groupId>
|
||||
<artifactId>okhttp</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.mpatric</groupId>
|
||||
<artifactId>mp3agic</artifactId>
|
||||
@@ -112,7 +115,95 @@
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>fastjson</artifactId>
|
||||
<version>1.2.61</version>
|
||||
<version>1.2.83</version>
|
||||
</dependency>
|
||||
|
||||
<!-- https://mvnrepository.com/artifact/org.xerial/sqlite-jdbc -->
|
||||
<dependency>
|
||||
<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>cn.dev33</groupId>
|
||||
<artifactId>sa-token-spring-boot-starter</artifactId>
|
||||
<version>1.30.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.session</groupId>
|
||||
<artifactId>spring-session-core</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.github.xiaoymin</groupId>
|
||||
<artifactId>knife4j-spring-boot-starter</artifactId>
|
||||
<version>3.0.3</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
<version>30.1.1-jre</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-validation</artifactId>
|
||||
</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>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>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>
|
||||
|
||||
</dependencies>
|
||||
@@ -122,27 +213,68 @@
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>com.uyoqu.framework</groupId>
|
||||
<artifactId>maven-plugin-starter</artifactId>
|
||||
<version>1.0.0</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>bin</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
<jvms>
|
||||
<jvm>-Djava.security.egd=file:/dev/./urandom</jvm>
|
||||
<jvm>-Dfile.encoding=utf-8</jvm>
|
||||
</jvms>
|
||||
<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>-->
|
||||
<!-- <artifactId>maven-plugin-starter</artifactId>-->
|
||||
<!-- <version>1.0.0</version>-->
|
||||
<!-- <executions>-->
|
||||
<!-- <execution>-->
|
||||
<!-- <phase>package</phase>-->
|
||||
<!-- <goals>-->
|
||||
<!-- <goal>bin</goal>-->
|
||||
<!-- </goals>-->
|
||||
<!-- </execution>-->
|
||||
<!-- </executions>-->
|
||||
<!-- <configuration>-->
|
||||
<!-- <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>
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package im.zhaojun.zfile.admin.annoation;
|
||||
|
||||
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 {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
package im.zhaojun.zfile.admin.annoation;
|
||||
|
||||
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 "";
|
||||
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package im.zhaojun.zfile.admin.annoation;
|
||||
|
||||
import im.zhaojun.zfile.admin.model.param.IStorageParam;
|
||||
import im.zhaojun.zfile.admin.annoation.model.StorageSourceParamDef;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 存储源参数下拉值接口.
|
||||
*
|
||||
* @author zhaojun
|
||||
*/
|
||||
public interface StorageParamSelect {
|
||||
|
||||
/**
|
||||
* 获取存储源参数下拉选项列表.
|
||||
*
|
||||
* @param storageParamItem
|
||||
* 存储源下拉参数定义
|
||||
*
|
||||
* @param targetParam
|
||||
* 存储源参数
|
||||
*
|
||||
* @return 存储源参数下拉选项列表
|
||||
*/
|
||||
List<StorageSourceParamDef.Options> getOptions(StorageParamItem storageParamItem, IStorageParam targetParam);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package im.zhaojun.zfile.admin.annoation;
|
||||
|
||||
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();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
package im.zhaojun.zfile.admin.annoation.model;
|
||||
|
||||
import im.zhaojun.zfile.admin.annoation.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();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package im.zhaojun.zfile.admin.annoation.select.impl;
|
||||
|
||||
import im.zhaojun.zfile.admin.annoation.StorageParamItem;
|
||||
import im.zhaojun.zfile.admin.annoation.StorageParamSelect;
|
||||
import im.zhaojun.zfile.admin.model.param.IStorageParam;
|
||||
import im.zhaojun.zfile.admin.annoation.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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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";
|
||||
|
||||
}
|
||||
@@ -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";
|
||||
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,147 @@
|
||||
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.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.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.Arrays;
|
||||
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)
|
||||
@DeleteMapping("/delete/batch")
|
||||
@ResponseBody
|
||||
@ApiImplicitParam(paramType = "query", name = "ids", value = "直链 id", required = true)
|
||||
@ApiOperation(value = "批量删除直链")
|
||||
public AjaxJson<Void> batchDelete(@RequestParam("id[]") Integer[] ids) {
|
||||
downloadLogService.removeBatchByIds(Arrays.asList(ids));
|
||||
return AjaxJson.getSuccess();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,141 @@
|
||||
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.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.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.Arrays;
|
||||
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)
|
||||
@DeleteMapping("/link/delete/batch")
|
||||
@ResponseBody
|
||||
@ApiImplicitParam(paramType = "query", name = "ids", value = "短链 id", required = true)
|
||||
@ApiOperation(value = "批量删除短链")
|
||||
public AjaxJson<Void> batchDelete(@RequestParam("id[]") Integer[] ids) {
|
||||
shortLinkService.removeBatchByIds(Arrays.asList(ids));
|
||||
return AjaxJson.getSuccess();
|
||||
}
|
||||
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
@@ -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 = "获取站点相关信息,如站点名称,风格样式,是否显示公告,是否显示文档区,自定义 CSS,JS 等参数")
|
||||
@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();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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.annoation.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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,134 @@
|
||||
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.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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
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);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
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);
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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> {
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
}
|
||||
@@ -1,9 +1,11 @@
|
||||
package im.zhaojun.zfile.model.support;
|
||||
package im.zhaojun.zfile.admin.model.dto;
|
||||
|
||||
import com.alibaba.fastjson.annotation.JSONField;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* OneDrive Token DTO
|
||||
*
|
||||
* @author zhaojun
|
||||
*/
|
||||
@Data
|
||||
@@ -14,4 +16,5 @@ public class OneDriveToken {
|
||||
|
||||
@JSONField(name = "refresh_token")
|
||||
private String refreshToken;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
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
|
||||
*
|
||||
* @author zhaojun
|
||||
*/
|
||||
@Data
|
||||
@ApiModel(value="文件下载日志")
|
||||
@TableName(value = "`download_log`")
|
||||
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;
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
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;
|
||||
|
||||
public boolean allowOperator() {
|
||||
// 允许文件操作,且允许匿名操作或者当前登录用户是管理员
|
||||
return BooleanUtil.isTrue(enableFileOperator) && (BooleanUtil.isTrue(enableFileAnnoOperator) || StpUtil.isLogin());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
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"),
|
||||
|
||||
/**
|
||||
* 搜索操作
|
||||
*/
|
||||
SEARCH("搜索", "search");
|
||||
|
||||
private final String name;
|
||||
|
||||
@EnumValue
|
||||
@JsonValue
|
||||
private final String value;
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package im.zhaojun.zfile.admin.model.param;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* 阿里云初始化参数
|
||||
*
|
||||
* @author zhaojun
|
||||
*/
|
||||
@Getter
|
||||
public class AliyunParam extends S3BaseParam {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package im.zhaojun.zfile.admin.model.param;
|
||||
|
||||
import im.zhaojun.zfile.admin.annoation.StorageParamItem;
|
||||
import im.zhaojun.zfile.admin.annoation.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;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package im.zhaojun.zfile.admin.model.param;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* 华为云初始化参数
|
||||
*
|
||||
* @author zhaojun
|
||||
*/
|
||||
@Getter
|
||||
public class HuaweiParam extends S3BaseParam {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
package im.zhaojun.zfile.admin.model.param;
|
||||
|
||||
|
||||
public interface IStorageParam {
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package im.zhaojun.zfile.admin.model.param;
|
||||
|
||||
import im.zhaojun.zfile.admin.annoation.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;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package im.zhaojun.zfile.admin.model.param;
|
||||
|
||||
import im.zhaojun.zfile.admin.annoation.StorageParamItem;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* 微软云初始化参数
|
||||
*
|
||||
* @author zhaojun
|
||||
*/
|
||||
@Getter
|
||||
public class MicrosoftDriveParam implements IStorageParam {
|
||||
|
||||
@StorageParamItem(name = "clientId", defaultValue = "${zfile.onedrive.clientId}", order = 1,
|
||||
description = "可自行更改,但修改后,下方获取访问令牌的地址不可用,需自行获取访问令牌和刷新令牌.")
|
||||
private String clientId;
|
||||
|
||||
@StorageParamItem(name = "SecretKey", defaultValue = "${zfile.onedrive.clientSecret}", order = 2)
|
||||
private String clientSecret;
|
||||
|
||||
@StorageParamItem(name = "访问令牌", link = "/onedrive/authorize", linkName = "前往获取令牌", order = 3)
|
||||
private String accessToken;
|
||||
|
||||
@StorageParamItem(name = "刷新令牌", order = 4)
|
||||
private String refreshToken;
|
||||
|
||||
@StorageParamItem(name = "反代域名", required = false, order = 7,
|
||||
link = "https://docs.zfile.vip/#/advanced?id=onedrive-cf", linkName = "配置文档")
|
||||
private String proxyDomain;
|
||||
|
||||
@StorageParamItem(name = "基路径", defaultValue = "/", order = 8, description = "基路径表示读取的根文件夹,不填写表示允许读取所有。如: '/','/文件夹1'")
|
||||
private String basePath;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package im.zhaojun.zfile.admin.model.param;
|
||||
|
||||
import im.zhaojun.zfile.admin.annoation.StorageParamItem;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* MinIO 初始化参数
|
||||
*
|
||||
* @author zhaojun
|
||||
*/
|
||||
@Getter
|
||||
public class MinIOParam extends S3BaseParam {
|
||||
|
||||
@StorageParamItem(name = "地域")
|
||||
private String region;
|
||||
|
||||
@StorageParamItem(name = "服务地址", description = "为 minio 的服务地址,非 web 访问地址,一般为 http://ip:9000")
|
||||
private String endPoint;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package im.zhaojun.zfile.admin.model.param;
|
||||
|
||||
import im.zhaojun.zfile.admin.annoation.StorageParamItem;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* OneDrive 初始化参数
|
||||
*
|
||||
* @author zhaojun
|
||||
*/
|
||||
@Getter
|
||||
public class OneDriveChinaParam extends OneDriveParam {
|
||||
|
||||
@StorageParamItem(name = "clientId", defaultValue = "${zfile.onedrive-china.clientId}",
|
||||
description = "可自行更改,但修改后,则下方获取访问令牌的地址不可用,需自行获取访问令牌和刷新令牌.", order = 1)
|
||||
private String clientId;
|
||||
|
||||
@StorageParamItem(name = "SecretKey", defaultValue = "${zfile.onedrive-china.clientSecret}", order = 2)
|
||||
private String clientSecret;
|
||||
|
||||
@StorageParamItem(name = "访问令牌", link = "/onedrive/china-authorize", linkName = "前往获取令牌", order = 3)
|
||||
private String accessToken;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package im.zhaojun.zfile.admin.model.param;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* OneDrive 初始化参数
|
||||
*
|
||||
* @author zhaojun
|
||||
*/
|
||||
@Getter
|
||||
public class OneDriveParam extends MicrosoftDriveParam {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package im.zhaojun.zfile.admin.model.param;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* 代理下载参数
|
||||
*
|
||||
* @author zhaojun
|
||||
*/
|
||||
@Getter
|
||||
public class ProxyDownloadParam extends ProxyTransferParam {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package im.zhaojun.zfile.admin.model.param;
|
||||
|
||||
import im.zhaojun.zfile.admin.annoation.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;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package im.zhaojun.zfile.admin.model.param;
|
||||
|
||||
/**
|
||||
* 代理上传参数
|
||||
*
|
||||
* @author zhaojun
|
||||
*/
|
||||
public class ProxyUploadParam extends ProxyTransferParam {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package im.zhaojun.zfile.admin.model.param;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* 七牛云初始化参数
|
||||
*
|
||||
* @author zhaojun
|
||||
*/
|
||||
@Getter
|
||||
public class QiniuParam extends S3BaseParam {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package im.zhaojun.zfile.admin.model.param;
|
||||
|
||||
import im.zhaojun.zfile.admin.annoation.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 = "如不配置跨域设置,可能会无法导致无法上传,或上传后看不到文件 <br> 此配置会覆盖之前的跨域配置,如您已经配置过,可忽略此选项")
|
||||
private boolean autoConfigCors;
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package im.zhaojun.zfile.admin.model.param;
|
||||
|
||||
import im.zhaojun.zfile.admin.annoation.StorageParamItem;
|
||||
import im.zhaojun.zfile.admin.annoation.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;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package im.zhaojun.zfile.admin.model.param;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* SFTP 初始化参数
|
||||
*
|
||||
* @author zhaojun
|
||||
*/
|
||||
@Getter
|
||||
public class SftpParam extends FtpParam {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package im.zhaojun.zfile.admin.model.param;
|
||||
|
||||
import im.zhaojun.zfile.admin.annoation.StorageParamItem;
|
||||
|
||||
/**
|
||||
* SharePoint 世纪互联初始化参数
|
||||
*
|
||||
* @author zhaojun
|
||||
*/
|
||||
public class SharePointChinaParam extends SharePointParam {
|
||||
|
||||
@StorageParamItem(name = "clientId", defaultValue = "${zfile.onedrive-china.clientId}", order = 1,
|
||||
description = "可自行更改,但修改后,则下方获取访问令牌的地址不可用,需自行获取访问令牌和刷新令牌.")
|
||||
private String clientId;
|
||||
|
||||
@StorageParamItem(name = "SecretKey", defaultValue = "${zfile.onedrive-china.clientSecret}", order = 2)
|
||||
private String clientSecret;
|
||||
|
||||
@StorageParamItem(name = "访问令牌", link = "/onedrive/china-authorize", linkName = "前往获取令牌", order = 3)
|
||||
private String accessToken;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package im.zhaojun.zfile.admin.model.param;
|
||||
|
||||
import im.zhaojun.zfile.admin.annoation.StorageParamItem;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* SharePoint 初始化参数
|
||||
*
|
||||
* @author zhaojun
|
||||
*/
|
||||
@Getter
|
||||
public class SharePointParam extends MicrosoftDriveParam {
|
||||
|
||||
@StorageParamItem(name = "clientId", defaultValue = "${zfile.onedrive.clientId}", order = 1,
|
||||
description = "可自行更改,但修改后,下方获取访问令牌的地址不可用,需自行获取访问令牌和刷新令牌.")
|
||||
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;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package im.zhaojun.zfile.admin.model.param;
|
||||
|
||||
import im.zhaojun.zfile.admin.annoation.StorageParamItem;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* 腾讯云初始化参数
|
||||
*
|
||||
* @author zhaojun
|
||||
*/
|
||||
@Getter
|
||||
public class TencentParam extends S3BaseParam {
|
||||
|
||||
@StorageParamItem(key = "secretId", name = "SecretId", order = 1)
|
||||
private String accessKey;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package im.zhaojun.zfile.admin.model.param;
|
||||
|
||||
import im.zhaojun.zfile.admin.annoation.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;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package im.zhaojun.zfile.admin.model.param;
|
||||
|
||||
import im.zhaojun.zfile.admin.annoation.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;
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
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;
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
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;
|
||||
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
package im.zhaojun.zfile.admin.model.request.setting;
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
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;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
package im.zhaojun.zfile.admin.model.verify;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 用于表示校验结果的类
|
||||
*
|
||||
* @author zhaojun
|
||||
*/
|
||||
@Data
|
||||
public class VerifyResult {
|
||||
|
||||
/**
|
||||
* 是否成功
|
||||
*/
|
||||
private boolean passed;
|
||||
|
||||
/**
|
||||
* 消息
|
||||
*/
|
||||
private String msg;
|
||||
|
||||
/**
|
||||
* 代码
|
||||
*/
|
||||
private Integer code;
|
||||
|
||||
/**
|
||||
* 表达式
|
||||
*/
|
||||
private String pattern;
|
||||
|
||||
public static VerifyResult success() {
|
||||
VerifyResult verifyResult = new VerifyResult();
|
||||
verifyResult.setPassed(true);
|
||||
return verifyResult;
|
||||
}
|
||||
|
||||
|
||||
public static VerifyResult success(String pattern) {
|
||||
VerifyResult verifyResult = new VerifyResult();
|
||||
verifyResult.setPassed(true);
|
||||
verifyResult.setPattern(pattern);
|
||||
return verifyResult;
|
||||
}
|
||||
|
||||
|
||||
public static VerifyResult fail(String msg, Integer code) {
|
||||
VerifyResult verifyResult = new VerifyResult();
|
||||
verifyResult.setPassed(false);
|
||||
verifyResult.setMsg(msg);
|
||||
verifyResult.setCode(code);
|
||||
return verifyResult;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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> {
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,219 @@
|
||||
package im.zhaojun.zfile.admin.service;
|
||||
|
||||
import cn.hutool.core.io.FileUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import im.zhaojun.zfile.admin.mapper.FilterConfigMapper;
|
||||
import im.zhaojun.zfile.admin.model.entity.FilterConfig;
|
||||
import im.zhaojun.zfile.common.exception.FileAccessException;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.nio.file.FileSystems;
|
||||
import java.nio.file.PathMatcher;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 存储源过滤器 Service
|
||||
*
|
||||
* @author zhaojun
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
public class FilterConfigService extends ServiceImpl<FilterConfigMapper, FilterConfig> {
|
||||
|
||||
@Resource
|
||||
private FilterConfigMapper filterConfigMapper;
|
||||
|
||||
|
||||
/**
|
||||
* 存储源 ID -> 过滤器列表(全部)缓存.
|
||||
*/
|
||||
private final Map<Integer, List<FilterConfig>> baseCache = new HashMap<>();
|
||||
|
||||
/**
|
||||
* 存储源 ID -> 过滤器列表(禁止访问)缓存.
|
||||
*/
|
||||
private final Map<Integer, List<FilterConfig>> inaccessibleCache = new HashMap<>();
|
||||
|
||||
/**
|
||||
* 存储源 ID -> 过滤器列表(禁止下载)缓存.
|
||||
*/
|
||||
private final Map<Integer, List<FilterConfig>> disableDownloadCache = new HashMap<>();
|
||||
|
||||
|
||||
/**
|
||||
* 根据存储源 ID 获取存储源配置列表
|
||||
*
|
||||
* @param storageId
|
||||
* 存储源 ID
|
||||
*
|
||||
* @return 存储源过滤器配置列表
|
||||
*/
|
||||
public List<FilterConfig> findByStorageId(Integer storageId){
|
||||
if (baseCache.get(storageId) != null) {
|
||||
return baseCache.get(storageId);
|
||||
} else {
|
||||
List<FilterConfig> dbResult = filterConfigMapper.findByStorageId(storageId);
|
||||
baseCache.put(storageId, dbResult);
|
||||
return dbResult;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 批量保存存储源过滤器配置, 会先删除之前的所有配置(在事务中运行)
|
||||
*
|
||||
* @param storageId
|
||||
* 存储源 ID
|
||||
*
|
||||
* @param filterConfigList
|
||||
* 存储源过滤器配置列表
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void batchSave(Integer storageId, List<FilterConfig> filterConfigList) {
|
||||
filterConfigMapper.deleteByStorageId(storageId);
|
||||
super.saveBatch(filterConfigList);
|
||||
baseCache.put(storageId, filterConfigList);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 判断访问的路径是否是不允许访问的
|
||||
*
|
||||
* @param storageId
|
||||
* 存储源 ID
|
||||
*
|
||||
* @param path
|
||||
* 请求路径
|
||||
*
|
||||
* @throws FileAccessException 如果没权限访问此目录, 则抛出异常
|
||||
*
|
||||
*/
|
||||
public void checkPathPermission(Integer storageId, String path) {
|
||||
List<FilterConfig> filterConfigList = findByStorageIdAndInaccessible(storageId);
|
||||
if (testPattern(filterConfigList, path)) {
|
||||
throw new FileAccessException("您没有权限访问该路径");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取所有类型为禁止访问的过滤规则
|
||||
*
|
||||
* @param storageId
|
||||
* 存储 ID
|
||||
*
|
||||
* @return 禁止访问的过滤规则列表
|
||||
*/
|
||||
public List<FilterConfig> findByStorageIdAndInaccessible(Integer storageId){
|
||||
if (inaccessibleCache.get(storageId) != null) {
|
||||
return inaccessibleCache.get(storageId);
|
||||
} else {
|
||||
List<FilterConfig> dbResult = filterConfigMapper.findByStorageIdAndInaccessible(storageId);
|
||||
inaccessibleCache.put(storageId, dbResult);
|
||||
return dbResult;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取所有类型为禁止下载的过滤规则
|
||||
*
|
||||
* @param storageId
|
||||
* 存储 ID
|
||||
*
|
||||
* @return 禁止下载的过滤规则列表
|
||||
*/
|
||||
public List<FilterConfig> findByStorageIdAndDisableDownload(Integer storageId){
|
||||
if (disableDownloadCache.get(storageId) != null) {
|
||||
return disableDownloadCache.get(storageId);
|
||||
} else {
|
||||
List<FilterConfig> dbResult = filterConfigMapper.findByStorageIdAndDisableDownload(storageId);
|
||||
disableDownloadCache.put(storageId, dbResult);
|
||||
return dbResult;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 指定存储源下的文件名称, 根据过滤表达式判断是否会显示, 如果符合任意一条表达式, 则返回 true, 反之则返回 false.
|
||||
*
|
||||
* @param storageId
|
||||
* 存储源 ID
|
||||
*
|
||||
* @param fileName
|
||||
* 文件名
|
||||
*
|
||||
* @return 是否显示
|
||||
*/
|
||||
public boolean filterResultIsHidden(Integer storageId, String fileName) {
|
||||
List<FilterConfig> filterConfigList = findByStorageId(storageId);
|
||||
return testPattern(filterConfigList, fileName);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 指定存储源下的文件名称, 根据过滤表达式判断文件名和所在路径是否禁止下载, 如果符合任意一条表达式, 则返回 true, 反之则返回 false.
|
||||
*
|
||||
* @param storageId
|
||||
* 存储源 ID
|
||||
*
|
||||
* @param fileName
|
||||
* 文件名
|
||||
*
|
||||
* @return 是否显示
|
||||
*/
|
||||
public boolean filterResultIsDisableDownload(Integer storageId, String fileName) {
|
||||
List<FilterConfig> filterConfigList = findByStorageIdAndDisableDownload(storageId);
|
||||
String filePath = FileUtil.getParent(fileName, 1);
|
||||
if (StrUtil.isEmpty(filePath)) {
|
||||
return testPattern(filterConfigList, fileName);
|
||||
} else {
|
||||
return testPattern(filterConfigList, fileName) || testPattern(filterConfigList, filePath);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 根据规则表达式和测试字符串进行匹配,如测试字符串和其中一个规则匹配上,则返回 true,反之返回 false。
|
||||
*
|
||||
* @param patternList
|
||||
* 规则列表
|
||||
*
|
||||
* @param test
|
||||
*
|
||||
* 测试字符串
|
||||
*
|
||||
* @return 是否显示
|
||||
*/
|
||||
private boolean testPattern(List<FilterConfig> patternList, String test) {
|
||||
for (FilterConfig filterConfig : patternList) {
|
||||
String expression = filterConfig.getExpression();
|
||||
|
||||
if (StrUtil.isEmpty(expression)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
PathMatcher pathMatcher = FileSystems.getDefault().getPathMatcher("glob:" + expression);
|
||||
boolean match = pathMatcher.matches(Paths.get(test));
|
||||
if (match) {
|
||||
return true;
|
||||
}
|
||||
log.debug("regex: {}, name {}, contains: {}", expression, test, match);
|
||||
} catch (Exception e) {
|
||||
log.debug("regex: {}, name {}, parse error, skip expression", expression, test);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,159 @@
|
||||
package im.zhaojun.zfile.admin.service;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import im.zhaojun.zfile.admin.mapper.PasswordConfigMapper;
|
||||
import im.zhaojun.zfile.admin.model.entity.PasswordConfig;
|
||||
import im.zhaojun.zfile.admin.model.verify.VerifyResult;
|
||||
import im.zhaojun.zfile.common.util.AjaxJson;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.nio.file.FileSystems;
|
||||
import java.nio.file.PathMatcher;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* 存储源密码配置 Service
|
||||
*
|
||||
* @author zhaojun
|
||||
*/
|
||||
@Service
|
||||
@Slf4j
|
||||
public class PasswordConfigService extends ServiceImpl<PasswordConfigMapper, PasswordConfig> {
|
||||
|
||||
@Resource
|
||||
private PasswordConfigMapper passwordConfigMapper;
|
||||
|
||||
|
||||
/**
|
||||
* 存储源 ID -> 密码规则列表(全部)缓存.
|
||||
*/
|
||||
private final Map<Integer, List<PasswordConfig>> baseCache = new HashMap<>();
|
||||
|
||||
|
||||
/**
|
||||
* 根据存储源 ID 查询密码规则列表
|
||||
*
|
||||
* @param storageId
|
||||
* 存储源 ID
|
||||
*
|
||||
* @return 密码规则列表
|
||||
*/
|
||||
public List<PasswordConfig> findByStorageId(Integer storageId) {
|
||||
if (baseCache.get(storageId) != null) {
|
||||
return baseCache.get(storageId);
|
||||
} else {
|
||||
List<PasswordConfig> dbResult = passwordConfigMapper.findByStorageId(storageId);
|
||||
baseCache.put(storageId, dbResult);
|
||||
return dbResult;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 批量保存指定存储源 ID 的密码规则列表
|
||||
*
|
||||
* @param storageId
|
||||
* 存储源 ID
|
||||
*
|
||||
* @param passwordConfigList
|
||||
* 存储源类别
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void batchSave(Integer storageId, List<PasswordConfig> passwordConfigList) {
|
||||
passwordConfigMapper.deleteByStorageId(storageId);
|
||||
super.saveBatch(passwordConfigList);
|
||||
baseCache.put(storageId, passwordConfigList);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 校验密码
|
||||
*
|
||||
* @param storageId
|
||||
* 存储源 ID
|
||||
*
|
||||
* @param path
|
||||
* 请求路径
|
||||
*
|
||||
* @param inputPassword
|
||||
* 用户输入的密码
|
||||
*
|
||||
* @return 是否校验通过
|
||||
*/
|
||||
public VerifyResult verifyPassword(Integer storageId, String path, String inputPassword) {
|
||||
List<PasswordConfig> passwordConfigList = findByStorageId(storageId);
|
||||
|
||||
for (PasswordConfig passwordConfig : passwordConfigList) {
|
||||
String expression = passwordConfig.getExpression();
|
||||
if (StrUtil.isEmpty(expression)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
PathMatcher pathMatcher = FileSystems.getDefault()
|
||||
.getPathMatcher("glob:" + expression);
|
||||
// 判断当前请求路径是否和规则路径表达式匹配
|
||||
boolean match = pathMatcher.matches(Paths.get(path));
|
||||
// 如果匹配且输入了密码则校验
|
||||
if (match) {
|
||||
if (StrUtil.isEmpty(inputPassword)) {
|
||||
return VerifyResult.fail("此文件夹需要密码.", AjaxJson.REQUIRED_PASSWORD);
|
||||
}
|
||||
|
||||
String expectedPassword = passwordConfig.getPassword();
|
||||
if (matchPassword(expectedPassword, inputPassword)) {
|
||||
log.debug("匹配文件夹密码 path: {}, expression: {}, 用户输入: {}, 匹配成功", path, expression, inputPassword);
|
||||
return VerifyResult.success(expression);
|
||||
}
|
||||
log.debug("匹配文件夹密码 path: {}, expression: {}, 用户输入: {}, 不匹配.", path, expression, inputPassword);
|
||||
return VerifyResult.fail("此文件夹密码错误.", AjaxJson.INVALID_PASSWORD);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.warn("匹配文件夹密码 path: {}, expression: {}, 用户输入: {}, 解析错误, 跳过此规则.",
|
||||
path, expression, inputPassword, e);
|
||||
}
|
||||
}
|
||||
|
||||
log.debug("校验文件夹密码 path: {}, 没有匹配的表达式, 不进行密码校验.", path);
|
||||
return VerifyResult.success();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 校验两个密码是否相同, 忽略空白字符
|
||||
*
|
||||
* @param expectedPasswordContent
|
||||
* 预期密码
|
||||
*
|
||||
* @param password
|
||||
* 实际输入密码
|
||||
*
|
||||
* @return 是否匹配
|
||||
*/
|
||||
private boolean matchPassword(String expectedPasswordContent, String password) {
|
||||
if (Objects.equals(expectedPasswordContent, password)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (expectedPasswordContent == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (password == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
expectedPasswordContent = expectedPasswordContent.replace("\n", "").trim();
|
||||
password = password.replace("\n", "").trim();
|
||||
return Objects.equals(expectedPasswordContent, password);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
package im.zhaojun.zfile.admin.service;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import im.zhaojun.zfile.admin.mapper.ReadmeConfigMapper;
|
||||
import im.zhaojun.zfile.admin.model.entity.ReadmeConfig;
|
||||
import im.zhaojun.zfile.common.constant.ZFileConstant;
|
||||
import im.zhaojun.zfile.common.util.StringUtils;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.nio.file.FileSystems;
|
||||
import java.nio.file.PathMatcher;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 存储源 readme 配置 Service
|
||||
*
|
||||
* @author zhaojun
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
public class ReadmeConfigService extends ServiceImpl<ReadmeConfigMapper, ReadmeConfig> {
|
||||
|
||||
@Resource
|
||||
private ReadmeConfigMapper readmeConfigMapper;
|
||||
|
||||
|
||||
/**
|
||||
* 根据存储源 ID 查询文档配置
|
||||
*
|
||||
* @param storageId
|
||||
* 存储源ID
|
||||
*
|
||||
* @return 存储源文档配置列表
|
||||
*/
|
||||
public List<ReadmeConfig> findByStorageId(Integer storageId){
|
||||
return readmeConfigMapper.findByStorageId(storageId);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 批量保存存储源 readme 配置, 会先删除之前的所有配置(在事务中运行)
|
||||
*
|
||||
* @param storageId
|
||||
* 存储源 ID
|
||||
*
|
||||
* @param filterConfigList
|
||||
* 存储源 readme 配置列表
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void batchSave(Integer storageId, List<ReadmeConfig> filterConfigList) {
|
||||
readmeConfigMapper.deleteByStorageId(storageId);
|
||||
super.saveBatch(filterConfigList);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 根据存储源指定路径下的 readme 配置
|
||||
*
|
||||
* @param storageId
|
||||
* 存储源ID
|
||||
*
|
||||
* @param path
|
||||
* 文件夹路径
|
||||
*
|
||||
* @return 存储源 readme 配置列表
|
||||
*/
|
||||
public ReadmeConfig findReadmeByPath(Integer storageId, String path) {
|
||||
List<ReadmeConfig> readmeConfigList = readmeConfigMapper.findByStorageId(storageId);
|
||||
return getReadmeByTestPattern(readmeConfigList, path);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 根据规则表达式和测试字符串进行匹配,如测试字符串和其中一个规则匹配上,则返回 true,反之返回 false。
|
||||
*
|
||||
* @param patternList
|
||||
* 规则列表
|
||||
*
|
||||
* @param test
|
||||
* 测试字符串
|
||||
*
|
||||
* @return 是否显示
|
||||
*/
|
||||
private ReadmeConfig getReadmeByTestPattern(List<ReadmeConfig> patternList, String test) {
|
||||
test = StringUtils.concat(test, ZFileConstant.PATH_SEPARATOR);
|
||||
|
||||
for (ReadmeConfig filterConfig : patternList) {
|
||||
String expression = filterConfig.getExpression();
|
||||
if (StrUtil.isEmpty(expression)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
PathMatcher pathMatcher = FileSystems.getDefault().getPathMatcher("glob:" + expression);
|
||||
boolean match = pathMatcher.matches(Paths.get(test));
|
||||
if (match) {
|
||||
return filterConfig;
|
||||
}
|
||||
log.debug("regex: {}, name {}, contains: {}", expression, test, match);
|
||||
} catch (Exception e) {
|
||||
log.debug("regex: {}, name {}, parse error, skip expression", expression, test);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user