mirror of
https://github.com/zfile-dev/zfile.git
synced 2025-04-19 05:34:52 +00:00
Compare commits
40 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e30289d21b | ||
|
|
3b6e2be7fe | ||
|
|
43c12aa8a7 | ||
|
|
c03a7710c0 | ||
|
|
1833b23d84 | ||
|
|
f3e393972d | ||
|
|
4f46c13369 | ||
|
|
f181959218 | ||
|
|
11effc0ae7 | ||
|
|
c8397e17bf | ||
|
|
ed32b9f1d4 | ||
|
|
4e184936db | ||
|
|
fe6aebfdee | ||
|
|
d65e1a442d | ||
|
|
34647793c8 | ||
|
|
e8c249b9ea | ||
|
|
1adcfee96f | ||
|
|
75f5de6b9a | ||
|
|
499942ef70 | ||
|
|
e11277ce26 | ||
|
|
5edd9e38a7 | ||
|
|
f4ffee706b | ||
|
|
bb65750278 | ||
|
|
e09167c0d0 | ||
|
|
ee6c04fa11 | ||
|
|
b31982b788 | ||
|
|
544a3d3eb2 | ||
|
|
1987bc97a9 | ||
|
|
7e878af06c | ||
|
|
766a047ee1 | ||
|
|
c1d29a46f5 | ||
|
|
08e39b3d15 | ||
|
|
e7790ac256 | ||
|
|
499f3e108c | ||
|
|
19144b653e | ||
|
|
17a87648fa | ||
|
|
ac4cef0980 | ||
|
|
71978f8003 | ||
|
|
0b3a67ec6e | ||
|
|
ee5fb54ebb |
115
API.md
115
API.md
@@ -10,22 +10,14 @@
|
||||
|
||||
当 `code == 0` 时, `data` 中为请求所需数据.
|
||||
|
||||
当 `code != 0` 时, 应当将 `msg` 中的属性作为参考值.
|
||||
当 `code != 0` 时, 应当将 `msg` 中的内容作为参考值.
|
||||
|
||||
|
||||
## 获取文件列表
|
||||
## 驱动器列表
|
||||
|
||||
### 请求 URL
|
||||
|
||||
`/api/list` `GET`
|
||||
|
||||
### 参数
|
||||
|
||||
| 参数名 | 描述 | 是否必填 | 参考值 |
|
||||
| :------: | :--------: | :------: | :--------------------------: |
|
||||
| path | 路径 | 是 | `/`, `/文件夹名称` |
|
||||
| password | 文件夹密码 | 否 | 当文件夹需要密码时, |
|
||||
| page | 页数 | 否 | 默认取第一页, 每页固定 30 条 |
|
||||
`/api/drive/list` `GET`
|
||||
|
||||
### 响应
|
||||
|
||||
@@ -35,41 +27,52 @@
|
||||
"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"
|
||||
"id": 3, --- 此 ID 是驱动器 ID, 用来唯一区分驱动器
|
||||
"name": "演示 A 盘", --- 驱动器名称
|
||||
"enableCache": true, --- 是否开启了缓存
|
||||
"autoRefreshCache": false, --- 是否开启了缓存自动刷新
|
||||
"type": { --- 存储源类型
|
||||
"key": "upyun",
|
||||
"description": "又拍云 USS"
|
||||
},
|
||||
"searchEnable": false, --- 是否开启搜索
|
||||
"searchIgnoreCase": false, --- 搜索是否忽略大小写
|
||||
"searchContainEncryptedFile": false --- 搜索是否包含加密文件夹
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## 搜索
|
||||
|
||||
|
||||
## 获取文件列表
|
||||
|
||||
### 请求 URL
|
||||
|
||||
`/api/search` `GET`
|
||||
`/api/list/{driveId}` `GET`
|
||||
|
||||
### 参数
|
||||
|
||||
| 参数名 | 描述 | 是否必填 | 参考值 |
|
||||
| :----: | :----: | :------: | :--------------------------: |
|
||||
| name | 搜索值 | 是 | 模糊匹配 |
|
||||
| page | 页数 | 否 | 默认取第一页, 每页固定 30 条 |
|
||||
### URL 参数
|
||||
|
||||
|
||||
| 参数名 | 描述 | 是否必填 | 参考值 |
|
||||
| :-----: | :-------------------: | :------: | :------------------------------------: |
|
||||
| driveId | 驱动器 ID | 是 | 参考 `获取驱动器列表` 接口返回的 id 值 |
|
||||
|
||||
|
||||
### 请求参数
|
||||
|
||||
|
||||
| 参数名 | 描述 | 是否必填 | 参考值 |
|
||||
| :------: | :--------: | :------: | :--------------------------: |
|
||||
| path | 路径 | 是 | `/`, `/文件夹名称` |
|
||||
| password | 文件夹密码 | 否 | 当文件夹需要密码时, |
|
||||
| page | 页数 | 否 | 默认取第一页, 每页固定 30 条 |
|
||||
|
||||
|
||||
### 响应
|
||||
|
||||
|
||||
```json
|
||||
{
|
||||
"msg": "操作成功",
|
||||
@@ -100,7 +103,14 @@
|
||||
|
||||
### 请求 URL
|
||||
|
||||
`/api/directlink` `GET`
|
||||
`/api/directlink/{driveId}` `GET`
|
||||
|
||||
|
||||
### URL 参数
|
||||
|
||||
| 参数名 | 描述 | 是否必填 | 参考值 |
|
||||
| :-----: | :-------------------: | :------: | :------------------------------------: |
|
||||
| driveId | 驱动器 ID | 是 | 参考 `获取驱动器列表` 接口返回的 id 值 |
|
||||
|
||||
### 参数
|
||||
|
||||
@@ -130,7 +140,15 @@
|
||||
|
||||
### 请求 URL
|
||||
|
||||
`/api/config` `GET`
|
||||
`/api/config/{driveId}` `GET`
|
||||
|
||||
|
||||
### URL 参数
|
||||
|
||||
| 参数名 | 描述 | 是否必填 | 参考值 |
|
||||
| :-----: | :-------------------: | :------: | :------------------------------------: |
|
||||
| driveId | 驱动器 ID | 是 | 参考 `获取驱动器列表` 接口返回的 id 值 |
|
||||
|
||||
|
||||
### 参数
|
||||
|
||||
@@ -145,20 +163,19 @@
|
||||
"msg": "操作成功",
|
||||
"code": 0,
|
||||
"data": {
|
||||
"readme": null, # 文档文件名称
|
||||
"viewConfig": {
|
||||
"siteName": "站点名称", # 站点名称
|
||||
"infoEnable": false, # 是否开启右侧信息框
|
||||
"searchEnable": false, # 是否开启搜索
|
||||
"searchIgnoreCase": true, # 搜索是否忽略大小写
|
||||
"storageStrategy": "local", # 当前启用存储引擎
|
||||
"username": "2", # 用户名
|
||||
"domain": "http://127.0.0.1:8080", # 域名
|
||||
"enableCache": false, # 是否开启缓存
|
||||
"searchContainEncryptedFile": false, # 搜索是否包含加密文件夹
|
||||
"customJs": "", # 自定义 js 片段
|
||||
"customCss": "" # 自定义 css 片段
|
||||
}
|
||||
"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
|
||||
}
|
||||
}
|
||||
```
|
||||
```
|
||||
@@ -83,7 +83,7 @@ chmod +x zfile/bin/*.sh
|
||||
~/zfile/bin/start.sh
|
||||
```
|
||||
|
||||
篇幅有限, 更详细的安装教程及介绍请参考: [ZFile 文档](http://zhaojun.im/zfile-install)
|
||||
篇幅有限, 更详细的安装教程及介绍请参考: [ZFile 文档](http://docs.zhaojun.im/zfile)
|
||||
|
||||
访问地址:
|
||||
|
||||
@@ -129,10 +129,8 @@ linux 为 `/home/用户名/`, root 用户为 `/root/`
|
||||
- [x] 体验优化 - 文本预览更换 vscode 同款编辑器 monaco editor
|
||||
- [x] 新功能 - Docker 支持
|
||||
- [x] 架构调整 - 支持多存储策略
|
||||
- [x] 体验优化 - 忽略文件列表 (正则表达式)
|
||||
- [ ] 新功能 - 后台支持上传、编辑、删除等操作
|
||||
- [ ] 新功能 - WebDav 支持
|
||||
- [ ] 新功能 - 离线下载 (aria2)
|
||||
- [ ] 体验优化 - 忽略文件列表 (正则表达式)
|
||||
- [ ] 体验优化 - 自定义支持预览的文件后缀 (正则表达式)
|
||||
- [ ] 体验优化 - 一键安装脚本
|
||||
|
||||
|
||||
2
pom.xml
2
pom.xml
@@ -12,7 +12,7 @@
|
||||
|
||||
<groupId>im.zhaojun</groupId>
|
||||
<artifactId>zfile</artifactId>
|
||||
<version>2.7</version>
|
||||
<version>2.9.0</version>
|
||||
<name>zfile</name>
|
||||
<packaging>war</packaging>
|
||||
<description>一个在线的文件浏览系统</description>
|
||||
|
||||
@@ -19,7 +19,7 @@ import java.util.List;
|
||||
*/
|
||||
@Aspect
|
||||
@Component
|
||||
public class FileListCacheAop {
|
||||
public class FileListCacheAspect {
|
||||
|
||||
@Resource
|
||||
private ZFileCache zFileCache;
|
||||
@@ -16,4 +16,4 @@ public class DriveCacheKey {
|
||||
|
||||
private String key;
|
||||
|
||||
}
|
||||
}
|
||||
@@ -27,17 +27,29 @@ public class MyTimedCache<K, V> extends TimedCache<K, V> {
|
||||
|
||||
@Override
|
||||
protected void onRemove(K key, V cachedObject) {
|
||||
log.debug("尝试刷新缓存: " + key);
|
||||
if (driveContext == null) {
|
||||
driveContext = SpringContextHolder.getBean(DriveContext.class);
|
||||
}
|
||||
|
||||
DriveCacheKey cacheKey = (DriveCacheKey) key;
|
||||
AbstractBaseFileService baseFileService = driveContext.getDriveService(cacheKey.getDriveId());
|
||||
AbstractBaseFileService baseFileService = driveContext.get(cacheKey.getDriveId());
|
||||
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("尝试刷新缓存: {}", cacheKey);
|
||||
}
|
||||
|
||||
if (baseFileService == null) {
|
||||
log.error("尝试刷新缓存: {}, 时出现异常, 驱动器已不存在", cacheKey);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
baseFileService.fileList(cacheKey.getKey());
|
||||
} catch (Exception e) {
|
||||
log.error("尝试刷新驱动器 {} 的 {} 失败, ", cacheKey.getDriveId(), cacheKey.getKey());
|
||||
log.error("尝试刷新缓存 {} 失败", cacheKey);
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -7,6 +7,7 @@ import im.zhaojun.zfile.model.dto.FileItemDTO;
|
||||
import im.zhaojun.zfile.model.dto.SystemConfigDTO;
|
||||
import im.zhaojun.zfile.model.entity.DriveConfig;
|
||||
import im.zhaojun.zfile.repository.DriverConfigRepository;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@@ -26,17 +27,26 @@ import java.util.concurrent.ConcurrentMap;
|
||||
* @author zhaojun
|
||||
*/
|
||||
@Component
|
||||
@Slf4j
|
||||
public class ZFileCache {
|
||||
|
||||
@Resource
|
||||
private DriverConfigRepository driverConfigRepository;
|
||||
|
||||
/**
|
||||
* 缓存过期时间
|
||||
*/
|
||||
@Value("${zfile.cache.timeout}")
|
||||
private long timeout;
|
||||
|
||||
/**
|
||||
* 缓存自动刷新间隔
|
||||
*/
|
||||
@Value("${zfile.cache.auto-refresh.interval}")
|
||||
private long autoRefreshInterval;
|
||||
|
||||
|
||||
/**
|
||||
* 缓存 map 对象.
|
||||
* 文件/文件对象缓存.
|
||||
*
|
||||
* ConcurrentMap<Integer, ConcurrentHashMap<String, List<FileItemDTO>>>
|
||||
* ConcurrentMap<driveId, ConcurrentHashMap<key, value>>
|
||||
@@ -52,9 +62,6 @@ public class ZFileCache {
|
||||
*/
|
||||
private SystemConfigDTO systemConfigCache;
|
||||
|
||||
@Resource
|
||||
private DriverConfigRepository driverConfigRepository;
|
||||
|
||||
|
||||
/**
|
||||
* 写入缓存
|
||||
@@ -96,6 +103,9 @@ public class ZFileCache {
|
||||
* 驱动器 ID
|
||||
*/
|
||||
public void clear(Integer driveId) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("清空驱动器所有缓存, driveId: {}", driveId);
|
||||
}
|
||||
getCacheByDriveId(driveId).clear();
|
||||
}
|
||||
|
||||
@@ -172,7 +182,7 @@ public class ZFileCache {
|
||||
|
||||
|
||||
/**
|
||||
* 从缓存中删除指定存储器的某个路径的缓存
|
||||
* 从缓存中删除指定驱动器的某个路径的缓存
|
||||
*
|
||||
* @param driveId
|
||||
* 驱动器 ID
|
||||
@@ -280,12 +290,15 @@ public class ZFileCache {
|
||||
|
||||
|
||||
/**
|
||||
* 开启缓存自动刷新, 仅当数据库设置为开启时, 才会真正开启缓存自动刷新.
|
||||
* 开启缓存自动刷新
|
||||
*
|
||||
* @param driveId
|
||||
* 驱动器 ID
|
||||
*/
|
||||
public void startAutoCacheRefresh(Integer driveId) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("开启缓存自动刷新 driveId: {}", driveId);
|
||||
}
|
||||
DriveConfig driveConfig = driverConfigRepository.findById(driveId).get();
|
||||
Boolean autoRefreshCache = driveConfig.getAutoRefreshCache();
|
||||
if (autoRefreshCache != null && autoRefreshCache) {
|
||||
@@ -306,6 +319,9 @@ public class ZFileCache {
|
||||
* 驱动器 ID
|
||||
*/
|
||||
public void stopAutoCacheRefresh(Integer driveId) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("停止缓存自动刷新 driveId: {}", driveId);
|
||||
}
|
||||
MyTimedCache<DriveCacheKey, List<FileItemDTO>> driveCache = drivesCache.get(driveId);
|
||||
if (driveCache != null) {
|
||||
driveCache.cancelPruneSchedule();
|
||||
|
||||
@@ -3,8 +3,6 @@ package im.zhaojun.zfile.config;
|
||||
import im.zhaojun.zfile.model.constant.StorageConfigConstant;
|
||||
import im.zhaojun.zfile.model.entity.StorageConfig;
|
||||
import im.zhaojun.zfile.service.StorageConfigService;
|
||||
import im.zhaojun.zfile.service.impl.OneDriveChinaServiceImpl;
|
||||
import im.zhaojun.zfile.service.impl.OneDriveServiceImpl;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
@@ -24,13 +22,6 @@ public class OneDriveConfig {
|
||||
@Resource
|
||||
private StorageConfigService storageConfigService;
|
||||
|
||||
@Resource
|
||||
private OneDriveServiceImpl oneDriveServiceImpl;
|
||||
|
||||
@Resource
|
||||
private OneDriveChinaServiceImpl oneDriveChinaServiceImpl;
|
||||
|
||||
|
||||
/**
|
||||
* OneDrive 请求 RestTemplate, 会在请求头中添加 Bearer: Authorization {token} 信息, 用于 API 认证.
|
||||
*/
|
||||
|
||||
@@ -31,4 +31,4 @@ public class ZFileConfiguration {
|
||||
return restTemplate;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,13 @@
|
||||
package im.zhaojun.zfile.context;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import im.zhaojun.zfile.exception.InvalidDriveException;
|
||||
import im.zhaojun.zfile.model.entity.DriveConfig;
|
||||
import im.zhaojun.zfile.model.enums.StorageTypeEnum;
|
||||
import im.zhaojun.zfile.service.DriveConfigService;
|
||||
import im.zhaojun.zfile.service.base.AbstractBaseFileService;
|
||||
import im.zhaojun.zfile.util.SpringContextHolder;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
@@ -12,38 +15,64 @@ import org.springframework.context.annotation.DependsOn;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* 驱动器上下文环境
|
||||
* 每个驱动器对应一个 Service, 其中初始化好了与对象存储的连接信息.
|
||||
* 此驱动器上下文环境用户缓存每个 Service, 避免重复创建连接.
|
||||
* @author zhaojun
|
||||
*/
|
||||
@Component
|
||||
@DependsOn("springContextHolder")
|
||||
@Slf4j
|
||||
public class DriveContext implements ApplicationContextAware {
|
||||
|
||||
/**
|
||||
* Map<Integer, AbstractBaseFileService>
|
||||
* Map<驱动器 ID, 驱动器连接 Service>
|
||||
*/
|
||||
private static Map<Integer, AbstractBaseFileService> drivesServiceMap = new ConcurrentHashMap<>();
|
||||
|
||||
private static Map<StorageTypeEnum, Class<AbstractBaseFileService>> storageTypeEnumClassMap = new ConcurrentHashMap<>();
|
||||
|
||||
@Resource
|
||||
private DriveConfigService driveConfigService;
|
||||
|
||||
|
||||
/**
|
||||
* 项目启动时, 自动调用数据库已存储的所有驱动器进行初始化.
|
||||
*/
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
|
||||
List<DriveConfig> list = driveConfigService.list();
|
||||
for (DriveConfig driveConfig : list) {
|
||||
try {
|
||||
init(driveConfig.getId());
|
||||
log.info("启动时初始化驱动器成功, 驱动器信息: {}", JSON.toJSONString(driveConfig));
|
||||
} catch (Exception e) {
|
||||
log.error("启动时初始化驱动器失败, 驱动器信息: {}", JSON.toJSONString(driveConfig), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 初始化指定驱动器的 Service, 添加到上下文环境中.
|
||||
*
|
||||
* @param driveId
|
||||
* 驱动器 ID.
|
||||
*/
|
||||
public void initDrive(Integer driveId) {
|
||||
public void init(Integer driveId) {
|
||||
AbstractBaseFileService baseFileService = getBeanByDriveId(driveId);
|
||||
if (baseFileService != null) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("尝试初始化驱动器, driveId: {}", driveId);
|
||||
}
|
||||
baseFileService.init(driveId);
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("初始化驱动器成功, driveId: {}", driveId);
|
||||
}
|
||||
drivesServiceMap.put(driveId, baseFileService);
|
||||
}
|
||||
}
|
||||
@@ -57,8 +86,12 @@ public class DriveContext implements ApplicationContextAware {
|
||||
*
|
||||
* @return 驱动器对应的 Service
|
||||
*/
|
||||
public AbstractBaseFileService getDriveService(Integer driveId) {
|
||||
return drivesServiceMap.get(driveId);
|
||||
public AbstractBaseFileService get(Integer driveId) {
|
||||
AbstractBaseFileService abstractBaseFileService = drivesServiceMap.get(driveId);
|
||||
if (abstractBaseFileService == null) {
|
||||
throw new InvalidDriveException("此驱动器不存在或初始化失败, 请检查后台参数配置");
|
||||
}
|
||||
return abstractBaseFileService;
|
||||
}
|
||||
|
||||
|
||||
@@ -68,7 +101,10 @@ public class DriveContext implements ApplicationContextAware {
|
||||
* @param driveId
|
||||
* 驱动器 ID
|
||||
*/
|
||||
public void destroyDrive(Integer driveId) {
|
||||
public void destroy(Integer driveId) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("清理驱动器上下文对象, driveId: {}", driveId);
|
||||
}
|
||||
drivesServiceMap.remove(driveId);
|
||||
}
|
||||
|
||||
@@ -94,14 +130,18 @@ public class DriveContext implements ApplicationContextAware {
|
||||
|
||||
|
||||
/**
|
||||
* 项目启动时, 自动调用所有驱动器进行初始化.
|
||||
* 更新上下文环境中的驱动器 ID
|
||||
*
|
||||
* @param updateId
|
||||
* 驱动器原 ID
|
||||
*
|
||||
* @param newId
|
||||
* 驱动器新 ID
|
||||
*/
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
|
||||
List<DriveConfig> list = driveConfigService.list();
|
||||
for (DriveConfig driveConfig : list) {
|
||||
initDrive(driveConfig.getId());
|
||||
}
|
||||
public void updateDriveId(Integer updateId, Integer newId) {
|
||||
AbstractBaseFileService fileService = drivesServiceMap.remove(updateId);
|
||||
fileService.setDriveId(newId);
|
||||
drivesServiceMap.put(newId, fileService);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -6,6 +6,7 @@ import org.springframework.beans.BeansException;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
|
||||
@@ -1,220 +0,0 @@
|
||||
package im.zhaojun.zfile.controller;
|
||||
|
||||
import im.zhaojun.zfile.model.constant.ZFileConstant;
|
||||
import im.zhaojun.zfile.model.dto.FileItemDTO;
|
||||
import im.zhaojun.zfile.model.dto.ResultBean;
|
||||
import im.zhaojun.zfile.model.dto.SystemFrontConfigDTO;
|
||||
import im.zhaojun.zfile.model.support.FilePageModel;
|
||||
import im.zhaojun.zfile.service.DriveConfigService;
|
||||
import im.zhaojun.zfile.service.SystemConfigService;
|
||||
import im.zhaojun.zfile.service.base.AbstractBaseFileService;
|
||||
import im.zhaojun.zfile.context.DriveContext;
|
||||
import im.zhaojun.zfile.util.FileComparator;
|
||||
import im.zhaojun.zfile.util.HttpUtil;
|
||||
import im.zhaojun.zfile.util.StringUtils;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
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.RestController;
|
||||
import org.springframework.web.client.HttpClientErrorException;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* 前台文件管理
|
||||
* @author zhaojun
|
||||
*/
|
||||
@Slf4j
|
||||
@RequestMapping("/api")
|
||||
@RestController
|
||||
public class FileController {
|
||||
|
||||
@Resource
|
||||
private SystemConfigService systemConfigService;
|
||||
|
||||
@Resource
|
||||
private DriveContext driveContext;
|
||||
|
||||
@Resource
|
||||
private DriveConfigService driveConfigService;
|
||||
|
||||
/**
|
||||
* 滚动加载每页条数.
|
||||
*/
|
||||
private static final Integer PAGE_SIZE = 30;
|
||||
|
||||
|
||||
/**
|
||||
* 获取所有驱动器
|
||||
*
|
||||
* @return 所有驱动器
|
||||
*/
|
||||
@GetMapping("/drive/list")
|
||||
public ResultBean drives() {
|
||||
return ResultBean.success(driveConfigService.list());
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取某个驱动器下, 指定路径的数据, 每页固定 {@link #PAGE_SIZE} 条数据.
|
||||
*
|
||||
* @param driveId
|
||||
* 驱动器 ID
|
||||
*
|
||||
* @param path
|
||||
* 路径
|
||||
*
|
||||
* @param password
|
||||
* 文件夹密码, 某些文件夹需要密码才能访问, 当不需要密码时, 此参数可以为空
|
||||
*
|
||||
* @param page
|
||||
* 页数
|
||||
*
|
||||
* @return 当前路径下所有文件及文件夹
|
||||
*/
|
||||
@GetMapping("/list/{driveId}")
|
||||
public ResultBean list(@PathVariable(name = "driveId") Integer driveId,
|
||||
@RequestParam(defaultValue = "/") String path,
|
||||
@RequestParam(required = false) String password,
|
||||
@RequestParam(defaultValue = "1") Integer page) throws Exception {
|
||||
AbstractBaseFileService fileService = driveContext.getDriveService(driveId);
|
||||
List<FileItemDTO> fileItemList = fileService.fileList(StringUtils.removeDuplicateSeparator("/" + path + "/"));
|
||||
|
||||
for (FileItemDTO fileItemDTO : fileItemList) {
|
||||
if (ZFileConstant.PASSWORD_FILE_NAME.equals(fileItemDTO.getName())) {
|
||||
String expectedPasswordContent;
|
||||
try {
|
||||
expectedPasswordContent = HttpUtil.getTextContent(fileItemDTO.getUrl());
|
||||
} catch (HttpClientErrorException httpClientErrorException) {
|
||||
log.debug("尝试重新获取密码文件缓存中链接后仍失败", httpClientErrorException);
|
||||
try {
|
||||
String fullPath = StringUtils.removeDuplicateSeparator(fileItemDTO.getPath() + "/" + fileItemDTO.getName());
|
||||
FileItemDTO fileItem = fileService.getFileItem(fullPath);
|
||||
expectedPasswordContent = HttpUtil.getTextContent(fileItem.getUrl());
|
||||
} catch (Exception e) {
|
||||
log.debug("尝试重新获取密码文件链接后仍失败, 已暂时取消密码", e);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (Objects.equals(expectedPasswordContent, password)) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (password != null && !"".equals(password)) {
|
||||
return ResultBean.error("密码错误.", ResultBean.INVALID_PASSWORD);
|
||||
}
|
||||
return ResultBean.error("此文件夹需要密码.", ResultBean.REQUIRED_PASSWORD);
|
||||
}
|
||||
}
|
||||
return ResultBean.successData(getSortedPagingData(fileItemList, page));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取系统配置信息和当前页的标题, 页面文档信息
|
||||
*
|
||||
* @param driveId
|
||||
* 驱动器 ID
|
||||
*
|
||||
* @return 返回指定存储器的系统配置信息
|
||||
*/
|
||||
@GetMapping("/config/{driveId}")
|
||||
public ResultBean getConfig(@PathVariable(name = "driveId") Integer driveId, String path) {
|
||||
SystemFrontConfigDTO systemConfig = systemConfigService.getSystemFrontConfig(driveId);
|
||||
|
||||
AbstractBaseFileService fileService = driveContext.getDriveService(driveId);
|
||||
String fullPath = StringUtils.removeDuplicateSeparator(path + "/" + ZFileConstant.README_FILE_NAME);
|
||||
try {
|
||||
FileItemDTO fileItem = fileService.getFileItem(fullPath);
|
||||
String readme = HttpUtil.getTextContent(fileItem.getUrl());
|
||||
systemConfig.setReadme(readme);
|
||||
} catch (Exception e) {
|
||||
// ignore
|
||||
}
|
||||
|
||||
return ResultBean.successData(systemConfig);
|
||||
}
|
||||
|
||||
|
||||
@GetMapping("/search/{driveId}")
|
||||
public ResultBean search(@RequestParam(value = "name", defaultValue = "/") String name,
|
||||
@RequestParam(defaultValue = "name") String sortBy,
|
||||
@RequestParam(defaultValue = "asc") String order,
|
||||
@RequestParam(defaultValue = "1") Integer page,
|
||||
@PathVariable("driveId") Integer driveId) {
|
||||
return ResultBean.error("暂不支持搜索功能");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 过滤文件列表, 去除密码, 文档文件.
|
||||
*
|
||||
* @param fileItemList
|
||||
* 文件列表
|
||||
*/
|
||||
private void filterFileList(List<FileItemDTO> fileItemList) {
|
||||
if (fileItemList == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
fileItemList.removeIf(fileItem -> ZFileConstant.PASSWORD_FILE_NAME.equals(fileItem.getName())
|
||||
|| ZFileConstant.README_FILE_NAME.equals(fileItem.getName()));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 对传入的文件列表, 按照文件名进行排序, 然后取相应页数的文件
|
||||
*
|
||||
* @param fileItemList
|
||||
* 文件列表
|
||||
*
|
||||
* @param page
|
||||
* 要取的页数
|
||||
*
|
||||
* @return 排序及分页后的那段数据
|
||||
*/
|
||||
private FilePageModel getSortedPagingData(List<FileItemDTO> fileItemList, Integer page) {
|
||||
ArrayList<FileItemDTO> copy = new ArrayList<>(Arrays.asList(new FileItemDTO[fileItemList.size()]));
|
||||
Collections.copy(copy, fileItemList);
|
||||
|
||||
// 排序, 先按照文件类型比较, 文件夹在前, 文件在后, 然后根据 sortBy 字段排序, 默认为升序;
|
||||
copy.sort(new FileComparator());
|
||||
filterFileList(copy);
|
||||
|
||||
int total = copy.size();
|
||||
int totalPage = (total + PAGE_SIZE - 1) / PAGE_SIZE;
|
||||
|
||||
if (page > totalPage) {
|
||||
return new FilePageModel(totalPage, Collections.emptyList());
|
||||
}
|
||||
|
||||
int start = (page - 1) * PAGE_SIZE;
|
||||
int end = page * PAGE_SIZE;
|
||||
end = Math.min(end, total);
|
||||
return new FilePageModel(totalPage, copy.subList(start, end));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取指定路径下的文件信息内容
|
||||
*
|
||||
* @param driveId
|
||||
* 驱动器 ID
|
||||
*
|
||||
* @param path
|
||||
* 文件全路径
|
||||
*
|
||||
* @return 该文件的名称, 路径, 大小, 下载地址等信息.
|
||||
*/
|
||||
@GetMapping("/directlink/{driveId}")
|
||||
public ResultBean directlink(@PathVariable(name = "driveId") Integer driveId, String path) {
|
||||
AbstractBaseFileService fileService = driveContext.getDriveService(driveId);
|
||||
return ResultBean.successData(fileService.getFileItem(path));
|
||||
}
|
||||
}
|
||||
@@ -1,30 +1,14 @@
|
||||
package im.zhaojun.zfile.controller.admin;
|
||||
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.hutool.core.util.ZipUtil;
|
||||
import im.zhaojun.zfile.context.StorageTypeContext;
|
||||
import im.zhaojun.zfile.model.dto.ResultBean;
|
||||
import im.zhaojun.zfile.model.dto.StorageStrategyDTO;
|
||||
import im.zhaojun.zfile.model.dto.SystemConfigDTO;
|
||||
import im.zhaojun.zfile.model.entity.StorageConfig;
|
||||
import im.zhaojun.zfile.model.enums.StorageTypeEnum;
|
||||
import im.zhaojun.zfile.model.support.SystemMonitorInfo;
|
||||
import im.zhaojun.zfile.model.support.ResultBean;
|
||||
import im.zhaojun.zfile.service.SystemConfigService;
|
||||
import im.zhaojun.zfile.service.base.AbstractBaseFileService;
|
||||
import im.zhaojun.zfile.util.FileUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 管理后台接口
|
||||
@@ -32,7 +16,6 @@ import java.util.List;
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/admin")
|
||||
@Slf4j
|
||||
public class AdminController {
|
||||
|
||||
@Resource
|
||||
@@ -52,7 +35,7 @@ public class AdminController {
|
||||
* 更新系统配置
|
||||
*/
|
||||
@PostMapping("/config")
|
||||
public ResultBean updateConfig(SystemConfigDTO systemConfigDTO) throws Exception {
|
||||
public ResultBean updateConfig(SystemConfigDTO systemConfigDTO) {
|
||||
systemConfigDTO.setId(1);
|
||||
systemConfigService.updateSystemConfig(systemConfigDTO);
|
||||
return ResultBean.success();
|
||||
@@ -68,52 +51,4 @@ public class AdminController {
|
||||
return ResultBean.success();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取指定存储策略的表单域
|
||||
*
|
||||
* @param storageType
|
||||
* 存储策略
|
||||
*
|
||||
* @return 所有表单域
|
||||
*/
|
||||
@GetMapping("/strategy-form")
|
||||
public ResultBean getFormByStorageType(StorageTypeEnum storageType) {
|
||||
AbstractBaseFileService storageTypeService = StorageTypeContext.getStorageTypeService(storageType);
|
||||
List<StorageConfig> storageConfigList = storageTypeService.storageStrategyConfigList();
|
||||
return ResultBean.success(storageConfigList);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 返回支持的存储引擎.
|
||||
*/
|
||||
@GetMapping("/support-strategy")
|
||||
public ResultBean supportStrategy() {
|
||||
List<StorageStrategyDTO> result = new ArrayList<>();
|
||||
StorageTypeEnum[] values = StorageTypeEnum.values();
|
||||
return ResultBean.successData(values);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 系统日志下载
|
||||
*/
|
||||
@GetMapping("/log")
|
||||
public ResponseEntity<Object> downloadLog(HttpServletResponse response) {
|
||||
String userHome = System.getProperty("user.home");
|
||||
File fileZip = ZipUtil.zip(userHome + "/.zfile/logs");
|
||||
String currentDate = DateUtil.format(new Date(), "yyyy-MM-dd HH:mm:ss");
|
||||
return FileUtil.export(fileZip, "ZFile 诊断日志 - " + currentDate + ".zip");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取系统监控信息
|
||||
*/
|
||||
@GetMapping("monitor")
|
||||
public ResultBean monitor() {
|
||||
return ResultBean.success(new SystemMonitorInfo());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
package im.zhaojun.zfile.controller.admin;
|
||||
|
||||
import im.zhaojun.zfile.model.dto.CacheInfoDTO;
|
||||
import im.zhaojun.zfile.model.dto.ResultBean;
|
||||
import im.zhaojun.zfile.model.support.ResultBean;
|
||||
import im.zhaojun.zfile.service.DriveConfigService;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
package im.zhaojun.zfile.controller.admin;
|
||||
|
||||
|
||||
import im.zhaojun.zfile.model.support.ResultBean;
|
||||
import im.zhaojun.zfile.service.SystemConfigService;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
@Controller
|
||||
public class DebugController {
|
||||
|
||||
@Value("${zfile.debug}")
|
||||
private Boolean debug;
|
||||
|
||||
@Resource
|
||||
private SystemConfigService systemConfigService;
|
||||
|
||||
@GetMapping("/debug/resetPwd")
|
||||
public ResultBean resetPwd() {
|
||||
if (debug) {
|
||||
systemConfigService.updateUsernameAndPwd("admin", "123456");
|
||||
return ResultBean.success();
|
||||
} else {
|
||||
return ResultBean.error("未开启 DEBUG 模式,不允许进行此操作。");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,10 +1,12 @@
|
||||
package im.zhaojun.zfile.controller.admin;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import im.zhaojun.zfile.model.dto.DriveConfigDTO;
|
||||
import im.zhaojun.zfile.model.dto.ResultBean;
|
||||
import im.zhaojun.zfile.model.entity.DriveConfig;
|
||||
import im.zhaojun.zfile.model.entity.FilterConfig;
|
||||
import im.zhaojun.zfile.model.support.ResultBean;
|
||||
import im.zhaojun.zfile.service.DriveConfigService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import im.zhaojun.zfile.service.FilterConfigService;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
@@ -17,24 +19,26 @@ import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 驱动器 Controller
|
||||
* 驱动器相关操作 Controller
|
||||
* @author zhaojun
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/admin")
|
||||
@Slf4j
|
||||
public class DriveController {
|
||||
|
||||
@Resource
|
||||
private DriveConfigService driveConfigService;
|
||||
|
||||
@Resource
|
||||
private FilterConfigService filterConfigService;
|
||||
|
||||
|
||||
/**
|
||||
* 获取所有驱动器列表
|
||||
*
|
||||
* @return 驱动器列表
|
||||
*/
|
||||
@GetMapping("drives")
|
||||
@GetMapping("/drives")
|
||||
public ResultBean driveList() {
|
||||
List<DriveConfig> list = driveConfigService.list();
|
||||
return ResultBean.success(list);
|
||||
@@ -44,14 +48,14 @@ public class DriveController {
|
||||
/**
|
||||
* 获取指定驱动器基本信息及其参数
|
||||
*
|
||||
* @param id
|
||||
* @param driveId
|
||||
* 驱动器 ID
|
||||
*
|
||||
* @return 驱动器基本信息信息
|
||||
* @return 驱动器基本信息
|
||||
*/
|
||||
@GetMapping("drive/{id}")
|
||||
public ResultBean driveItem(@PathVariable Integer id) {
|
||||
DriveConfigDTO driveConfig = driveConfigService.findDriveConfigDTOById(id);
|
||||
@GetMapping("/drive/{driveId}")
|
||||
public ResultBean driveItem(@PathVariable Integer driveId) {
|
||||
DriveConfigDTO driveConfig = driveConfigService.findDriveConfigDTOById(driveId);
|
||||
return ResultBean.success(driveConfig);
|
||||
}
|
||||
|
||||
@@ -59,9 +63,9 @@ public class DriveController {
|
||||
/**
|
||||
* 保存驱动器设置
|
||||
*/
|
||||
@PostMapping("drive")
|
||||
@PostMapping("/drive")
|
||||
public ResultBean saveDriveItem(@RequestBody DriveConfigDTO driveConfigDTO) {
|
||||
driveConfigService.save(driveConfigDTO);
|
||||
driveConfigService.saveDriveConfigDTO(driveConfigDTO);
|
||||
return ResultBean.success();
|
||||
}
|
||||
|
||||
@@ -69,12 +73,100 @@ public class DriveController {
|
||||
/**
|
||||
* 删除驱动器设置
|
||||
*
|
||||
* @param id
|
||||
* @param driveId
|
||||
* 驱动器 ID
|
||||
*/
|
||||
@DeleteMapping("drive/{id}")
|
||||
public ResultBean deleteDriveItem(@PathVariable Integer id) {
|
||||
driveConfigService.deleteById(id);
|
||||
@DeleteMapping("/drive/{driveId}")
|
||||
public ResultBean deleteDriveItem(@PathVariable Integer driveId) {
|
||||
driveConfigService.deleteById(driveId);
|
||||
return ResultBean.success();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 启用驱动器
|
||||
*
|
||||
* @param driveId
|
||||
* 驱动器 ID
|
||||
*/
|
||||
@PostMapping("/drive/{driveId}/enable")
|
||||
public ResultBean enable(@PathVariable Integer driveId) {
|
||||
DriveConfig driveConfig = driveConfigService.findById(driveId);
|
||||
driveConfig.setEnable(true);
|
||||
driveConfigService.updateDriveConfig(driveConfig);
|
||||
return ResultBean.success();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 停止驱动器
|
||||
*
|
||||
* @param driveId
|
||||
* 驱动器 ID
|
||||
*/
|
||||
@PostMapping("/drive/{driveId}/disable")
|
||||
public ResultBean disable(@PathVariable Integer driveId) {
|
||||
DriveConfig driveConfig = driveConfigService.findById(driveId);
|
||||
driveConfig.setEnable(false);
|
||||
driveConfigService.updateDriveConfig(driveConfig);
|
||||
return ResultBean.success();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 根据驱动器 ID 获取过滤文件列表
|
||||
*
|
||||
* @param driveId
|
||||
* 驱动器 ID
|
||||
*/
|
||||
@GetMapping("/drive/{driveId}/filters")
|
||||
public ResultBean getFilters(@PathVariable Integer driveId) {
|
||||
return ResultBean.success(filterConfigService.findByDriveId(driveId));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 停止驱动器
|
||||
*
|
||||
* @param driveId
|
||||
* 驱动器 ID
|
||||
*/
|
||||
@PostMapping("/drive/{driveId}/filters")
|
||||
public ResultBean saveFilters(@RequestBody List<FilterConfig> filter, @PathVariable Integer driveId) {
|
||||
filterConfigService.batchSave(filter, driveId);
|
||||
return ResultBean.success();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 保存拖拽排序信息
|
||||
*
|
||||
* @param driveConfigs
|
||||
* 拖拽排序信息
|
||||
*/
|
||||
@PostMapping("/drive/drag")
|
||||
public ResultBean saveDriveDrag(@RequestBody List<JSONObject> driveConfigs) {
|
||||
driveConfigService.saveDriveDrag(driveConfigs);
|
||||
return ResultBean.success();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 更新驱动器 ID
|
||||
*
|
||||
* @param updateId
|
||||
* 驱动器原 ID
|
||||
*
|
||||
* @param newId
|
||||
* 驱动器新 ID
|
||||
*/
|
||||
@PostMapping("/drive/updateId")
|
||||
public ResultBean updateDriveId(Integer updateId, Integer newId) {
|
||||
DriveConfig driveConfig = driveConfigService.findById(newId);
|
||||
if (driveConfig != null) {
|
||||
return ResultBean.error("已存在的 ID,请更换 ID 后重试。");
|
||||
}
|
||||
driveConfigService.updateId(updateId, newId);
|
||||
return ResultBean.success();
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
package im.zhaojun.zfile.controller.admin;
|
||||
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.hutool.core.util.ZipUtil;
|
||||
import im.zhaojun.zfile.util.FileUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
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 javax.servlet.http.HttpServletResponse;
|
||||
import java.io.File;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 日志相关 Controller
|
||||
* @author zhaojun
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/admin")
|
||||
@Slf4j
|
||||
public class LogController {
|
||||
|
||||
/**
|
||||
* 系统日志下载
|
||||
*/
|
||||
@GetMapping("/log")
|
||||
public ResponseEntity<Object> downloadLog(HttpServletResponse response) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("下载诊断日志");
|
||||
}
|
||||
String userHome = System.getProperty("user.home");
|
||||
File fileZip = ZipUtil.zip(userHome + "/.zfile/logs");
|
||||
String currentDate = DateUtil.format(new Date(), "yyyy-MM-dd HH:mm:ss");
|
||||
return FileUtil.export(fileZip, "ZFile 诊断日志 - " + currentDate + ".zip");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
package im.zhaojun.zfile.controller.admin;
|
||||
|
||||
import im.zhaojun.zfile.context.StorageTypeContext;
|
||||
import im.zhaojun.zfile.model.entity.StorageConfig;
|
||||
import im.zhaojun.zfile.model.enums.StorageTypeEnum;
|
||||
import im.zhaojun.zfile.model.support.ResultBean;
|
||||
import im.zhaojun.zfile.service.base.AbstractBaseFileService;
|
||||
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;
|
||||
|
||||
/**
|
||||
* 系统元数据 Controller
|
||||
* @author zhaojun
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/admin")
|
||||
public class MateDataController {
|
||||
|
||||
/**
|
||||
* 返回支持的存储引擎.
|
||||
*/
|
||||
@GetMapping("/support-strategy")
|
||||
public ResultBean supportStrategy() {
|
||||
StorageTypeEnum[] values = StorageTypeEnum.values();
|
||||
return ResultBean.successData(values);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取指定存储策略的表单域
|
||||
*
|
||||
* @param storageType
|
||||
* 存储策略
|
||||
*
|
||||
* @return 所有表单域
|
||||
*/
|
||||
@GetMapping("/strategy-form")
|
||||
public ResultBean getFormByStorageType(StorageTypeEnum storageType) {
|
||||
AbstractBaseFileService storageTypeService = StorageTypeContext.getStorageTypeService(storageType);
|
||||
List<StorageConfig> storageConfigList = storageTypeService.storageStrategyConfigList();
|
||||
return ResultBean.success(storageConfigList);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
package im.zhaojun.zfile.controller.admin;
|
||||
|
||||
import im.zhaojun.zfile.model.support.ResultBean;
|
||||
import im.zhaojun.zfile.service.ShortLinkConfigService;
|
||||
import org.springframework.stereotype.Controller;
|
||||
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;
|
||||
|
||||
/**
|
||||
* 直链管理 Controller
|
||||
*
|
||||
* @author zhaojun
|
||||
*/
|
||||
@Controller
|
||||
@RequestMapping("/admin")
|
||||
public class ShortLinkManagerController {
|
||||
|
||||
@Resource
|
||||
private ShortLinkConfigService shortLinkConfigService;
|
||||
|
||||
@GetMapping("/link/list")
|
||||
@ResponseBody
|
||||
public ResultBean list(String key,
|
||||
String url,
|
||||
String dateFrom,
|
||||
String dateTo,
|
||||
Integer page,
|
||||
Integer limit,
|
||||
@RequestParam(required = false, defaultValue = "createDate") String orderBy,
|
||||
@RequestParam(required = false, defaultValue = "desc") String orderDirection) {
|
||||
return ResultBean.success(shortLinkConfigService.find(key, url, dateFrom, dateTo, page, limit, orderBy, orderDirection));
|
||||
}
|
||||
|
||||
@GetMapping("/link/delete/{id}")
|
||||
@ResponseBody
|
||||
public ResultBean deleteById(@PathVariable Integer id) {
|
||||
shortLinkConfigService.deleteById(id);
|
||||
return ResultBean.success();
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,13 @@
|
||||
package im.zhaojun.zfile.controller;
|
||||
package im.zhaojun.zfile.controller.home;
|
||||
|
||||
import cn.hutool.core.io.FileUtil;
|
||||
import cn.hutool.core.util.URLUtil;
|
||||
import im.zhaojun.zfile.context.DriveContext;
|
||||
import im.zhaojun.zfile.exception.NotAllowedDownloadException;
|
||||
import im.zhaojun.zfile.model.constant.ZFileConstant;
|
||||
import im.zhaojun.zfile.model.dto.FileItemDTO;
|
||||
import im.zhaojun.zfile.model.enums.FileTypeEnum;
|
||||
import im.zhaojun.zfile.service.base.AbstractBaseFileService;
|
||||
import im.zhaojun.zfile.context.DriveContext;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.util.AntPathMatcher;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
@@ -17,10 +19,11 @@ import javax.servlet.http.HttpServletRequest;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* 直链 Controller
|
||||
* @author Zhao Jun
|
||||
*/
|
||||
@Controller
|
||||
public class PageController {
|
||||
public class DirectLinkController {
|
||||
|
||||
@Resource
|
||||
private DriveContext driveContext;
|
||||
@@ -33,7 +36,8 @@ public class PageController {
|
||||
* @return 重定向至文件直链
|
||||
*/
|
||||
@GetMapping("/directlink/{driveId}/**")
|
||||
public String directlink(@PathVariable("driveId") Integer driveId, final HttpServletRequest request) {
|
||||
public String directlink(@PathVariable("driveId") Integer driveId,
|
||||
final HttpServletRequest request) {
|
||||
String path = (String) request.getAttribute(
|
||||
HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE);
|
||||
String bestMatchPattern = (String) request.getAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE);
|
||||
@@ -44,7 +48,11 @@ public class PageController {
|
||||
filePath = "/" + filePath;
|
||||
}
|
||||
|
||||
AbstractBaseFileService fileService = driveContext.getDriveService(driveId);
|
||||
if (Objects.equals(FileUtil.getName(filePath), ZFileConstant.PASSWORD_FILE_NAME)) {
|
||||
throw new NotAllowedDownloadException("不允许下载此文件");
|
||||
}
|
||||
|
||||
AbstractBaseFileService fileService = driveContext.get(driveId);
|
||||
FileItemDTO fileItem = fileService.getFileItem(filePath);
|
||||
|
||||
String url = fileItem.getUrl();
|
||||
@@ -67,4 +75,5 @@ public class PageController {
|
||||
return "redirect:" + url;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,251 @@
|
||||
package im.zhaojun.zfile.controller.home;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import im.zhaojun.zfile.context.DriveContext;
|
||||
import im.zhaojun.zfile.exception.NotExistFileException;
|
||||
import im.zhaojun.zfile.exception.PasswordVerifyException;
|
||||
import im.zhaojun.zfile.model.constant.ZFileConstant;
|
||||
import im.zhaojun.zfile.model.dto.FileItemDTO;
|
||||
import im.zhaojun.zfile.model.dto.SystemFrontConfigDTO;
|
||||
import im.zhaojun.zfile.model.entity.DriveConfig;
|
||||
import im.zhaojun.zfile.model.enums.StorageTypeEnum;
|
||||
import im.zhaojun.zfile.model.support.ResultBean;
|
||||
import im.zhaojun.zfile.model.support.VerifyResult;
|
||||
import im.zhaojun.zfile.service.DriveConfigService;
|
||||
import im.zhaojun.zfile.service.FilterConfigService;
|
||||
import im.zhaojun.zfile.service.SystemConfigService;
|
||||
import im.zhaojun.zfile.service.base.AbstractBaseFileService;
|
||||
import im.zhaojun.zfile.util.FileComparator;
|
||||
import im.zhaojun.zfile.util.HttpUtil;
|
||||
import im.zhaojun.zfile.util.StringUtils;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
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.RestController;
|
||||
import org.springframework.web.client.HttpClientErrorException;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* 前台文件管理
|
||||
* @author zhaojun
|
||||
*/
|
||||
@Slf4j
|
||||
@RequestMapping("/api")
|
||||
@RestController
|
||||
public class FileController {
|
||||
|
||||
@Resource
|
||||
private SystemConfigService systemConfigService;
|
||||
|
||||
@Resource
|
||||
private DriveContext driveContext;
|
||||
|
||||
@Resource
|
||||
private DriveConfigService driveConfigService;
|
||||
|
||||
@Resource
|
||||
private FilterConfigService filterConfigService;
|
||||
|
||||
|
||||
/**
|
||||
* 获取所有已启用的驱动器
|
||||
*
|
||||
* @return 所有已启用驱动器
|
||||
*/
|
||||
@GetMapping("/drive/list")
|
||||
public ResultBean drives() {
|
||||
return ResultBean.success(driveConfigService.listOnlyEnable());
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取某个驱动器下, 指定路径的数据
|
||||
*
|
||||
* @param driveId
|
||||
* 驱动器 ID
|
||||
*
|
||||
* @param path
|
||||
* 路径
|
||||
*
|
||||
* @param password
|
||||
* 文件夹密码, 某些文件夹需要密码才能访问, 当不需要密码时, 此参数可以为空
|
||||
*
|
||||
* @return 当前路径下所有文件及文件夹
|
||||
*/
|
||||
@GetMapping("/list/{driveId}")
|
||||
public ResultBean list(@PathVariable(name = "driveId") Integer driveId,
|
||||
@RequestParam(defaultValue = "/") String path,
|
||||
@RequestParam(required = false) String password,
|
||||
@RequestParam(required = false) String orderBy,
|
||||
@RequestParam(required = false, defaultValue = "asc") String orderDirection) throws Exception {
|
||||
AbstractBaseFileService fileService = driveContext.get(driveId);
|
||||
List<FileItemDTO> fileItemList = fileService.fileList(StringUtils.removeDuplicateSeparator(ZFileConstant.PATH_SEPARATOR + path + ZFileConstant.PATH_SEPARATOR));
|
||||
|
||||
// 校验密码, 如果校验不通过, 则返回错误消息
|
||||
VerifyResult verifyResult = verifyPassword(fileItemList, driveId, path, password);
|
||||
if (!verifyResult.isPassed()) {
|
||||
return ResultBean.error(verifyResult.getMsg(), verifyResult.getCode());
|
||||
}
|
||||
|
||||
// 过滤掉驱动器配置的表达式中要隐藏的数据
|
||||
filterFileList(fileItemList, driveId);
|
||||
|
||||
// 按照自然排序
|
||||
fileItemList.sort(new FileComparator(orderBy, orderDirection));
|
||||
return ResultBean.successData(fileItemList);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取系统配置信息和当前页的标题, 页面文档信息
|
||||
*
|
||||
* @param driveId
|
||||
* 驱动器 ID
|
||||
*
|
||||
* @return 返回指定驱动器的系统配置信息
|
||||
*/
|
||||
@GetMapping("/config/{driveId}")
|
||||
public ResultBean getConfig(@PathVariable(name = "driveId") Integer driveId, String path) {
|
||||
SystemFrontConfigDTO systemConfig = systemConfigService.getSystemFrontConfig(driveId);
|
||||
|
||||
AbstractBaseFileService fileService = driveContext.get(driveId);
|
||||
DriveConfig driveConfig = driveConfigService.findById(driveId);
|
||||
String fullPath = StringUtils.removeDuplicateSeparator(path + ZFileConstant.PATH_SEPARATOR + ZFileConstant.README_FILE_NAME);
|
||||
FileItemDTO fileItem = null;
|
||||
try {
|
||||
fileItem = fileService.getFileItem(fullPath);
|
||||
|
||||
if (!Objects.equals(driveConfig.getType(), StorageTypeEnum.FTP)) {
|
||||
String readme = HttpUtil.getTextContent(fileItem.getUrl());
|
||||
systemConfig.setReadme(readme);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
if (e instanceof NotExistFileException) {
|
||||
log.trace("不存在 README 文件, 已跳过, fullPath: {}, fileItem: {}", fullPath, JSON.toJSONString(fileItem));
|
||||
} else {
|
||||
log.trace("获取 README 文件异常, fullPath: {}, fileItem: {}", fullPath, JSON.toJSONString(fileItem), e);
|
||||
}
|
||||
}
|
||||
|
||||
return ResultBean.successData(systemConfig);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取指定路径下的文件信息内容
|
||||
*
|
||||
* @param driveId
|
||||
* 驱动器 ID
|
||||
*
|
||||
* @param path
|
||||
* 文件全路径
|
||||
*
|
||||
* @return 该文件的名称, 路径, 大小, 下载地址等信息.
|
||||
*/
|
||||
@GetMapping("/directlink/{driveId}")
|
||||
public ResultBean directlink(@PathVariable(name = "driveId") Integer driveId, String path) {
|
||||
AbstractBaseFileService fileService = driveContext.get(driveId);
|
||||
return ResultBean.successData(fileService.getFileItem(path));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 校验密码
|
||||
* @param fileItemList
|
||||
* 文件列表
|
||||
* @param driveId
|
||||
* 驱动器 ID
|
||||
* @param path
|
||||
* 请求路径
|
||||
* @param inputPassword
|
||||
* 用户输入的密码
|
||||
* @return 是否校验通过
|
||||
*/
|
||||
private VerifyResult verifyPassword(List<FileItemDTO> fileItemList, Integer driveId, String path, String inputPassword) {
|
||||
AbstractBaseFileService fileService = driveContext.get(driveId);
|
||||
|
||||
for (FileItemDTO fileItemDTO : fileItemList) {
|
||||
if (ZFileConstant.PASSWORD_FILE_NAME.equals(fileItemDTO.getName())) {
|
||||
String expectedPasswordContent;
|
||||
try {
|
||||
expectedPasswordContent = HttpUtil.getTextContent(fileItemDTO.getUrl());
|
||||
} catch (HttpClientErrorException httpClientErrorException) {
|
||||
log.trace("尝试重新获取密码文件缓存中链接后仍失败, driveId: {}, path: {}, inputPassword: {}, passwordFile:{} ",
|
||||
driveId, path, inputPassword, JSON.toJSONString(fileItemDTO), httpClientErrorException);
|
||||
try {
|
||||
String pwdFileFullPath = StringUtils.removeDuplicateSeparator(fileItemDTO.getPath() + ZFileConstant.PATH_SEPARATOR + fileItemDTO.getName());
|
||||
FileItemDTO pwdFileItem = fileService.getFileItem(pwdFileFullPath);
|
||||
expectedPasswordContent = HttpUtil.getTextContent(pwdFileItem.getUrl());
|
||||
} catch (Exception e) {
|
||||
throw new PasswordVerifyException("此文件夹未加密文件夹, 但密码检查异常, 请联系管理员检查密码设置", e);
|
||||
}
|
||||
}
|
||||
|
||||
if (matchPassword(expectedPasswordContent, inputPassword)) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (inputPassword != null && !"".equals(inputPassword)) {
|
||||
return VerifyResult.fail("密码错误.", ResultBean.INVALID_PASSWORD);
|
||||
}
|
||||
return VerifyResult.fail("此文件夹需要密码.", ResultBean.INVALID_PASSWORD);
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 过滤文件列表, 去除密码, 文档文件和此驱动器通过规则过滤的文件.
|
||||
*
|
||||
* @param fileItemList
|
||||
* 文件列表
|
||||
* @param driveId
|
||||
* 驱动器 ID
|
||||
*/
|
||||
private void filterFileList(List<FileItemDTO> fileItemList, Integer driveId) {
|
||||
if (fileItemList == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
fileItemList.removeIf(
|
||||
fileItem -> ZFileConstant.PASSWORD_FILE_NAME.equals(fileItem.getName())
|
||||
|| ZFileConstant.README_FILE_NAME.equals(fileItem.getName())
|
||||
|| filterConfigService.filterResultIsHidden(driveId, StringUtils.concatUrl(fileItem.getPath(), fileItem.getName()))
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,32 +1,19 @@
|
||||
package im.zhaojun.zfile.controller;
|
||||
package im.zhaojun.zfile.controller.home;
|
||||
|
||||
import im.zhaojun.zfile.model.dto.ResultBean;
|
||||
import im.zhaojun.zfile.model.enums.StorageTypeEnum;
|
||||
import im.zhaojun.zfile.util.AudioHelper;
|
||||
import im.zhaojun.zfile.model.support.ResultBean;
|
||||
import im.zhaojun.zfile.util.AudioUtil;
|
||||
import im.zhaojun.zfile.util.HttpUtil;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
/**
|
||||
* 公共 Controller
|
||||
* 文件解析 Controller
|
||||
* @author zhaojun
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/common")
|
||||
public class CommonController {
|
||||
|
||||
|
||||
/**
|
||||
* 返回系统支持的所有存储策略
|
||||
*
|
||||
* @return 存储策略
|
||||
*/
|
||||
@GetMapping("/support-strategy")
|
||||
public ResultBean supportStrategy() {
|
||||
return ResultBean.successData(StorageTypeEnum.values());
|
||||
}
|
||||
|
||||
public class FileParseController {
|
||||
|
||||
/**
|
||||
* 获取文件内容, 仅限用于 txt, md, ini 等普通文本文件.
|
||||
@@ -52,7 +39,7 @@ public class CommonController {
|
||||
*/
|
||||
@GetMapping("/audio-info")
|
||||
public ResultBean getAudioInfo(String url) throws Exception {
|
||||
return ResultBean.success(AudioHelper.getAudioInfo(url));
|
||||
return ResultBean.success(AudioUtil.getAudioInfo(url));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,7 +1,8 @@
|
||||
package im.zhaojun.zfile.controller;
|
||||
package im.zhaojun.zfile.controller.home;
|
||||
|
||||
import im.zhaojun.zfile.service.impl.LocalServiceImpl;
|
||||
import im.zhaojun.zfile.context.DriveContext;
|
||||
import im.zhaojun.zfile.model.constant.ZFileConstant;
|
||||
import im.zhaojun.zfile.service.impl.LocalServiceImpl;
|
||||
import im.zhaojun.zfile.util.FileUtil;
|
||||
import im.zhaojun.zfile.util.StringUtils;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
@@ -37,13 +38,12 @@ public class LocalController {
|
||||
@GetMapping("/file/{driveId}/**")
|
||||
@ResponseBody
|
||||
public ResponseEntity<Object> downAttachment(@PathVariable("driveId") Integer driveId, final HttpServletRequest request) {
|
||||
String path = (String) request.getAttribute(
|
||||
HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE);
|
||||
String path = (String) request.getAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE);
|
||||
String bestMatchPattern = (String) request.getAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE);
|
||||
AntPathMatcher apm = new AntPathMatcher();
|
||||
String filePath = apm.extractPathWithinPattern(bestMatchPattern, path);
|
||||
LocalServiceImpl localService = (LocalServiceImpl) driveContext.getDriveService(driveId);
|
||||
return FileUtil.export(new File(StringUtils.concatPath(localService.getFilePath(), filePath)));
|
||||
LocalServiceImpl localService = (LocalServiceImpl) driveContext.get(driveId);
|
||||
return FileUtil.export(new File(StringUtils.removeDuplicateSeparator(localService.getFilePath() + ZFileConstant.PATH_SEPARATOR + filePath)));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
package im.zhaojun.zfile.controller.home;
|
||||
|
||||
import cn.hutool.core.util.RandomUtil;
|
||||
import cn.hutool.core.util.URLUtil;
|
||||
import im.zhaojun.zfile.model.dto.SystemConfigDTO;
|
||||
import im.zhaojun.zfile.model.entity.ShortLinkConfig;
|
||||
import im.zhaojun.zfile.model.support.ResultBean;
|
||||
import im.zhaojun.zfile.service.ShortLinkConfigService;
|
||||
import im.zhaojun.zfile.service.SystemConfigService;
|
||||
import im.zhaojun.zfile.util.StringUtils;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
/**
|
||||
* 短链 Controller
|
||||
* @author zhao
|
||||
*/
|
||||
@Controller
|
||||
public class ShortLinkController {
|
||||
|
||||
@Resource
|
||||
private SystemConfigService systemConfigService;
|
||||
|
||||
@Resource
|
||||
private ShortLinkConfigService shortLinkConfigService;
|
||||
|
||||
@GetMapping("/api/short-link")
|
||||
@ResponseBody
|
||||
public ResultBean shortLink(String driveId, String path) {
|
||||
SystemConfigDTO systemConfig = systemConfigService.getSystemConfig();
|
||||
String domain = systemConfig.getDomain();
|
||||
|
||||
// 拼接直链地址.
|
||||
String fullPath = StringUtils.removeDuplicateSeparator("/directlink/" + driveId + path);
|
||||
|
||||
ShortLinkConfig shortLinkConfig;
|
||||
String randomKey;
|
||||
do {
|
||||
// 获取短链
|
||||
randomKey = RandomUtil.randomString(6);
|
||||
shortLinkConfig = shortLinkConfigService.findByKey(randomKey);
|
||||
} while (shortLinkConfig != null);
|
||||
|
||||
|
||||
shortLinkConfig = new ShortLinkConfig();
|
||||
shortLinkConfig.setKey(randomKey);
|
||||
shortLinkConfig.setUrl(fullPath);
|
||||
shortLinkConfigService.save(shortLinkConfig);
|
||||
|
||||
String shortUrl = StringUtils.removeDuplicateSeparator(domain + "/s/" + randomKey);
|
||||
return ResultBean.successData(shortUrl);
|
||||
}
|
||||
|
||||
@GetMapping("/s/{key}")
|
||||
public String parseShortKey(@PathVariable String key) {
|
||||
ShortLinkConfig shortLinkConfig = shortLinkConfigService.findByKey(key);
|
||||
if (shortLinkConfig == null) {
|
||||
throw new RuntimeException("此直链不存在或已失效.");
|
||||
}
|
||||
|
||||
SystemConfigDTO systemConfig = systemConfigService.getSystemConfig();
|
||||
String domain = systemConfig.getDomain();
|
||||
|
||||
String url = URLUtil.encode(StringUtils.removeDuplicateSeparator(domain + shortLinkConfig.getUrl()));
|
||||
return "redirect:" + url;
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,8 @@
|
||||
package im.zhaojun.zfile.controller;
|
||||
package im.zhaojun.zfile.controller.install;
|
||||
|
||||
import cn.hutool.crypto.SecureUtil;
|
||||
import im.zhaojun.zfile.controller.admin.AdminController;
|
||||
import im.zhaojun.zfile.model.dto.ResultBean;
|
||||
import im.zhaojun.zfile.model.dto.SystemConfigDTO;
|
||||
import im.zhaojun.zfile.service.StorageConfigService;
|
||||
import im.zhaojun.zfile.model.support.ResultBean;
|
||||
import im.zhaojun.zfile.service.SystemConfigService;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
@@ -23,12 +21,6 @@ public class InstallController {
|
||||
@Resource
|
||||
private SystemConfigService systemConfigService;
|
||||
|
||||
@Resource
|
||||
private StorageConfigService storageConfigService;
|
||||
|
||||
@Resource
|
||||
private AdminController adminController;
|
||||
|
||||
@GetMapping("/is-installed")
|
||||
public ResultBean isInstall() {
|
||||
if (!StringUtils.isEmpty(systemConfigService.getAdminUsername())) {
|
||||
@@ -1,4 +1,4 @@
|
||||
package im.zhaojun.zfile.controller;
|
||||
package im.zhaojun.zfile.controller.onedrive;
|
||||
|
||||
import im.zhaojun.zfile.model.support.OneDriveToken;
|
||||
import im.zhaojun.zfile.service.impl.OneDriveChinaServiceImpl;
|
||||
@@ -15,7 +15,7 @@ import javax.annotation.Resource;
|
||||
*/
|
||||
@Controller
|
||||
@RequestMapping("/onedrive")
|
||||
public class OneDriveController {
|
||||
public class OneDriveCallbackController {
|
||||
|
||||
@Resource
|
||||
private OneDriveServiceImpl oneDriveServiceImpl;
|
||||
@@ -31,6 +31,13 @@ public class OneDriveController {
|
||||
return "callback";
|
||||
}
|
||||
|
||||
@GetMapping("/authorize")
|
||||
public String authorize() {
|
||||
return "redirect:https://login.microsoftonline.com/common/oauth2/v2.0/authorize?client_id=" + oneDriveServiceImpl.getClientId() +
|
||||
"&response_type=code&redirect_uri=" + oneDriveServiceImpl.getRedirectUri() +
|
||||
"&scope=" + oneDriveServiceImpl.getScope();
|
||||
}
|
||||
|
||||
|
||||
@GetMapping("/china-callback")
|
||||
public String oneDriveChinaCallback(String code, Model model) {
|
||||
@@ -40,4 +47,11 @@ public class OneDriveController {
|
||||
return "callback";
|
||||
}
|
||||
|
||||
@GetMapping("/china-authorize")
|
||||
public String authorizeChina() {
|
||||
return "redirect:https://login.chinacloudapi.cn/common/oauth2/v2.0/authorize?client_id=" + oneDriveChinaServiceImpl.getClientId() +
|
||||
"&response_type=code&redirect_uri=" + oneDriveChinaServiceImpl.getRedirectUri() +
|
||||
"&scope=" + oneDriveChinaServiceImpl.getScope();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,125 @@
|
||||
package im.zhaojun.zfile.controller.onedrive;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.http.HttpRequest;
|
||||
import cn.hutool.http.HttpResponse;
|
||||
import cn.hutool.http.HttpUtil;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import im.zhaojun.zfile.model.dto.SharePointInfoVO;
|
||||
import im.zhaojun.zfile.model.support.ResultBean;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.stereotype.Controller;
|
||||
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.ResponseBody;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* @author zhaojun
|
||||
* SharePoint 工具类
|
||||
*/
|
||||
@Controller
|
||||
@RequestMapping("/sharepoint")
|
||||
public class SharePointHelperController {
|
||||
|
||||
|
||||
/**
|
||||
* 根据 AccessToken 获取域名前缀
|
||||
*/
|
||||
@PostMapping("/getDomainPrefix")
|
||||
@ResponseBody
|
||||
public ResultBean getDomainPrefix(@RequestBody SharePointInfoVO sharePointInfoVO) {
|
||||
|
||||
String host = "";
|
||||
|
||||
// 判断是标准版还是世纪互联版
|
||||
if (Objects.equals(sharePointInfoVO.getType(), "Standard")) {
|
||||
host = "graph.microsoft.com";
|
||||
} else if (Objects.equals(sharePointInfoVO.getType(), "China")) {
|
||||
host = "microsoftgraph.chinacloudapi.cn";
|
||||
}
|
||||
|
||||
// 请求 URL
|
||||
String requestUrl = StrUtil.format("https://{}/v1.0/sites/root", host);
|
||||
|
||||
// 构建请求认证 Token 信息
|
||||
String tokenValue = String.format("%s %s", "Bearer", sharePointInfoVO.getAccessToken());
|
||||
HashMap<String, String> headers = new HashMap<>();
|
||||
headers.put("Authorization", tokenValue);
|
||||
|
||||
// 请求接口
|
||||
HttpRequest getRequest = HttpUtil.createGet(requestUrl);
|
||||
HttpResponse execute = getRequest.addHeaders(headers).execute();
|
||||
String body = execute.body();
|
||||
if (execute.getStatus() != HttpStatus.OK.value()) {
|
||||
return ResultBean.error(body);
|
||||
}
|
||||
|
||||
// 解析前缀
|
||||
JSONObject jsonObject = JSONObject.parseObject(body);
|
||||
String hostname = jsonObject.getJSONObject("siteCollection").getString("hostname");
|
||||
String domainPrefix = StrUtil.subBefore(hostname, ".sharepoint", false);
|
||||
return ResultBean.successData(domainPrefix);
|
||||
}
|
||||
|
||||
@PostMapping("/getSiteId")
|
||||
@ResponseBody
|
||||
public ResultBean getSiteId(@RequestBody SharePointInfoVO sharePointInfoVO) {
|
||||
|
||||
// 判断必填参数
|
||||
if (sharePointInfoVO == null || sharePointInfoVO.getAccessToken() == null || sharePointInfoVO.getSiteName() == null) {
|
||||
return ResultBean.error("参数不全");
|
||||
}
|
||||
|
||||
String host = "";
|
||||
|
||||
// 判断是标准版还是世纪互联版
|
||||
if (Objects.equals(sharePointInfoVO.getType(), "Standard")) {
|
||||
host = "graph.microsoft.com";
|
||||
sharePointInfoVO.setDomainType("com");
|
||||
} else if (Objects.equals(sharePointInfoVO.getType(), "China")) {
|
||||
host = "microsoftgraph.chinacloudapi.cn";
|
||||
sharePointInfoVO.setDomainType("cn");
|
||||
} else {
|
||||
return ResultBean.error("参数不全");
|
||||
}
|
||||
|
||||
// 构建请求认证 Token 信息
|
||||
String tokenValue = String.format("%s %s", "Bearer", sharePointInfoVO.getAccessToken());
|
||||
HashMap<String, String> authorizationHeaders = new HashMap<>();
|
||||
authorizationHeaders.put("Authorization", tokenValue);
|
||||
|
||||
|
||||
// 如果没有域名前缀, 则先获取
|
||||
if (sharePointInfoVO.getDomainPrefix() == null || sharePointInfoVO.getDomainType() == null) {
|
||||
String requestUrl = StrUtil.format("https://{}/v1.0/sites/root", host);
|
||||
HttpRequest getRequest = HttpUtil.createGet(requestUrl);
|
||||
HttpResponse execute = getRequest.addHeaders(authorizationHeaders).execute();
|
||||
String body = execute.body();
|
||||
if (execute.getStatus() != HttpStatus.OK.value()) {
|
||||
return ResultBean.error(body);
|
||||
}
|
||||
JSONObject jsonObject = JSONObject.parseObject(body);
|
||||
String hostname = jsonObject.getJSONObject("siteCollection").getString("hostname");
|
||||
String domainPrefix = StrUtil.subBefore(hostname, ".sharepoint", false);
|
||||
sharePointInfoVO.setDomainPrefix(domainPrefix);
|
||||
}
|
||||
|
||||
// 请求接口
|
||||
String requestUrl = StrUtil.format("https://{}/v1.0/sites/{}.sharepoint.{}:/{}", host, sharePointInfoVO.getDomainPrefix(), sharePointInfoVO.getDomainType(), sharePointInfoVO.getSiteName());
|
||||
HttpRequest getRequest = HttpUtil.createGet(requestUrl);
|
||||
HttpResponse execute = getRequest.addHeaders(authorizationHeaders).execute();
|
||||
String body = execute.body();
|
||||
|
||||
// 解析数据
|
||||
if (execute.getStatus() != HttpStatus.OK.value()) {
|
||||
return ResultBean.error(body);
|
||||
}
|
||||
JSONObject jsonObject = JSONObject.parseObject(body);
|
||||
return ResultBean.successData(jsonObject.getString("id"));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,10 +1,9 @@
|
||||
package im.zhaojun.zfile.exception;
|
||||
|
||||
import im.zhaojun.zfile.model.dto.ResultBean;
|
||||
import im.zhaojun.zfile.model.support.ResultBean;
|
||||
import org.apache.catalina.connector.ClientAbortException;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.web.HttpMediaTypeNotAcceptableException;
|
||||
import org.springframework.web.bind.annotation.ControllerAdvice;
|
||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||
@@ -20,28 +19,6 @@ public class GlobleExceptionHandler {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(GlobleExceptionHandler.class);
|
||||
|
||||
@ExceptionHandler(SearchDisableException.class)
|
||||
@ResponseBody
|
||||
@ResponseStatus(code= HttpStatus.INTERNAL_SERVER_ERROR)
|
||||
public ResultBean searchDisableExceptionHandler(SearchDisableException e) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug(e.getMessage(), e);
|
||||
}
|
||||
return ResultBean.error(e.getMessage());
|
||||
}
|
||||
|
||||
|
||||
@ExceptionHandler
|
||||
@ResponseBody
|
||||
@ResponseStatus
|
||||
public ResultBean searchDisableExceptionHandler(StorageStrategyUninitializedException e) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug(e.getMessage(), e);
|
||||
}
|
||||
return ResultBean.error(e.getMessage());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 不存在的文件异常
|
||||
*/
|
||||
@@ -51,6 +28,7 @@ public class GlobleExceptionHandler {
|
||||
return ResultBean.error("文件不存在");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 捕获 ClientAbortException 异常, 不做任何处理, 防止出现大量堆栈日志输出, 此异常不影响功能.
|
||||
*/
|
||||
@@ -63,6 +41,17 @@ public class GlobleExceptionHandler {
|
||||
// }
|
||||
}
|
||||
|
||||
/**
|
||||
* 文件预览异常
|
||||
*/
|
||||
@ExceptionHandler({PasswordVerifyException.class})
|
||||
@ResponseBody
|
||||
@ResponseStatus
|
||||
public ResultBean passwordVerifyException(PasswordVerifyException ex) {
|
||||
return ResultBean.error(ex.getMessage());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 文件预览异常
|
||||
*/
|
||||
@@ -77,24 +66,25 @@ public class GlobleExceptionHandler {
|
||||
/**
|
||||
* 初始化异常
|
||||
*/
|
||||
@ExceptionHandler({InitializeException.class})
|
||||
@ExceptionHandler({InitializeDriveException.class})
|
||||
@ResponseBody
|
||||
@ResponseStatus
|
||||
public ResultBean initializeException(InitializeException ex) {
|
||||
public ResultBean initializeException(InitializeDriveException ex) {
|
||||
return ResultBean.error(ex.getMessage());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@ExceptionHandler
|
||||
@ResponseBody
|
||||
@ResponseStatus(code= HttpStatus.INTERNAL_SERVER_ERROR)
|
||||
@ResponseStatus
|
||||
public ResultBean searchDisableExceptionHandler(Exception e) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug(e.getMessage(), e);
|
||||
log.error(e.getMessage(), e);
|
||||
|
||||
if (e.getClass() == Exception.class) {
|
||||
return ResultBean.error("系统异常, 请联系管理员");
|
||||
} else {
|
||||
return ResultBean.error(e.getMessage());
|
||||
}
|
||||
return ResultBean.error("系统异常, 请联系管理员");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
package im.zhaojun.zfile.exception;
|
||||
|
||||
/**
|
||||
* 对象存储初始化异常
|
||||
* @author zhaojun
|
||||
*/
|
||||
public class InitializeDriveException extends RuntimeException {
|
||||
|
||||
private static final long serialVersionUID = -1920550904063819880L;
|
||||
|
||||
public InitializeDriveException() {
|
||||
}
|
||||
|
||||
public InitializeDriveException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public InitializeDriveException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
public InitializeDriveException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
public InitializeDriveException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
|
||||
super(message, cause, enableSuppression, writableStackTrace);
|
||||
}
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
package im.zhaojun.zfile.exception;
|
||||
|
||||
/**
|
||||
* 对象存储初始化异常
|
||||
* @author zhaojun
|
||||
*/
|
||||
public class InitializeException extends RuntimeException {
|
||||
|
||||
private static final long serialVersionUID = -1920550904063819880L;
|
||||
|
||||
public InitializeException() {
|
||||
}
|
||||
|
||||
public InitializeException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public InitializeException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
public InitializeException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
public InitializeException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
|
||||
super(message, cause, enableSuppression, writableStackTrace);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package im.zhaojun.zfile.exception;
|
||||
|
||||
/**
|
||||
* 无效的驱动器异常
|
||||
* @author zhaojun
|
||||
*/
|
||||
public class InvalidDriveException extends RuntimeException {
|
||||
|
||||
public InvalidDriveException() {
|
||||
}
|
||||
|
||||
public InvalidDriveException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public InvalidDriveException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
public InvalidDriveException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
public InvalidDriveException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
|
||||
super(message, cause, enableSuppression, writableStackTrace);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package im.zhaojun.zfile.exception;
|
||||
|
||||
/**
|
||||
* 无效的直链异常
|
||||
* @author zhaojun
|
||||
*/
|
||||
public class InvalidShortLinkException extends RuntimeException {
|
||||
public InvalidShortLinkException() {
|
||||
}
|
||||
|
||||
public InvalidShortLinkException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public InvalidShortLinkException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
public InvalidShortLinkException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
public InvalidShortLinkException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
|
||||
super(message, cause, enableSuppression, writableStackTrace);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package im.zhaojun.zfile.exception;
|
||||
|
||||
/**
|
||||
* 文件不允许下载异常
|
||||
* @author zhaojun
|
||||
*/
|
||||
public class NotAllowedDownloadException extends RuntimeException {
|
||||
public NotAllowedDownloadException() {
|
||||
}
|
||||
|
||||
public NotAllowedDownloadException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public NotAllowedDownloadException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
public NotAllowedDownloadException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
public NotAllowedDownloadException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
|
||||
super(message, cause, enableSuppression, writableStackTrace);
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
package im.zhaojun.zfile.exception;
|
||||
|
||||
/**
|
||||
* 不存在的文件异常
|
||||
* @author zhaojun
|
||||
*/
|
||||
public class NotExistFileException extends RuntimeException {
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
package im.zhaojun.zfile.exception;
|
||||
|
||||
/**
|
||||
* 密码校验失败异常
|
||||
* @author zhaojun
|
||||
*/
|
||||
public class PasswordVerifyException extends RuntimeException {
|
||||
|
||||
public PasswordVerifyException() {
|
||||
}
|
||||
|
||||
public PasswordVerifyException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public PasswordVerifyException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
public PasswordVerifyException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
public PasswordVerifyException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
|
||||
super(message, cause, enableSuppression, writableStackTrace);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package im.zhaojun.zfile.exception;
|
||||
|
||||
/**
|
||||
* 刷新缓存时出现的异常信息
|
||||
*
|
||||
* @author zhaojun
|
||||
*/
|
||||
public class RefreshCacheException extends RuntimeException {
|
||||
|
||||
public RefreshCacheException() {
|
||||
}
|
||||
|
||||
public RefreshCacheException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public RefreshCacheException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
public RefreshCacheException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
public RefreshCacheException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
|
||||
super(message, cause, enableSuppression, writableStackTrace);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
package im.zhaojun.zfile.exception;
|
||||
|
||||
/**
|
||||
* @author zhaojun
|
||||
*/
|
||||
public class SearchDisableException extends RuntimeException {
|
||||
|
||||
public SearchDisableException() {
|
||||
}
|
||||
|
||||
public SearchDisableException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public SearchDisableException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
public SearchDisableException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
public SearchDisableException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
|
||||
super(message, cause, enableSuppression, writableStackTrace);
|
||||
}
|
||||
}
|
||||
@@ -26,4 +26,5 @@ public class StorageStrategyUninitializedException extends RuntimeException {
|
||||
public StorageStrategyUninitializedException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
|
||||
super(message, cause, enableSuppression, writableStackTrace);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
package im.zhaojun.zfile.exception;
|
||||
|
||||
/**
|
||||
* 未知的存储类型异常
|
||||
* @author zhaojun
|
||||
*/
|
||||
public class UnknownStorageTypeException extends RuntimeException {
|
||||
|
||||
private static final long serialVersionUID = -4853756482605773655L;
|
||||
|
||||
public UnknownStorageTypeException() {
|
||||
}
|
||||
|
||||
public UnknownStorageTypeException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public UnknownStorageTypeException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
public UnknownStorageTypeException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
public UnknownStorageTypeException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
|
||||
super(message, cause, enableSuppression, writableStackTrace);
|
||||
}
|
||||
}
|
||||
@@ -23,4 +23,5 @@ public class MyCorsFilter {
|
||||
urlBasedCorsConfigurationSource.registerCorsConfiguration("/**", corsConfiguration);
|
||||
return new CorsFilter(urlBasedCorsConfigurationSource);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -33,6 +33,10 @@ public class StorageConfigConstant {
|
||||
|
||||
public static final String REFRESH_TOKEN_KEY = "refreshToken";
|
||||
|
||||
public static final String SHAREPOINT_SITE_ID = "siteId";
|
||||
|
||||
public static final String SHAREPOINT_SITE_NAME = "siteName";
|
||||
|
||||
public static final String PATH_STYLE = "pathStyle";
|
||||
|
||||
public static final String IS_PRIVATE = "isPrivate";
|
||||
|
||||
@@ -12,12 +12,16 @@ public class ZFileConstant {
|
||||
|
||||
public final static String USER_HOME = System.getProperty("user.home");
|
||||
|
||||
public static final String AUDIO_TMP_PATH = "/.zfile/tmp/audio/";
|
||||
|
||||
public static final Character PATH_SEPARATOR_CHAR = '/';
|
||||
|
||||
public static final String PATH_SEPARATOR = "/";
|
||||
|
||||
|
||||
/**
|
||||
* 系统产生的临时文件路径
|
||||
*/
|
||||
public static String TMP_FILE_PATH = "/.zfile/tmp2/";
|
||||
|
||||
/**
|
||||
* 页面文档文件
|
||||
*/
|
||||
@@ -38,6 +42,11 @@ public class ZFileConstant {
|
||||
*/
|
||||
public static Long TEXT_MAX_FILE_SIZE_KB = 100L;
|
||||
|
||||
@Autowired(required = false)
|
||||
public void setTmpFilePath(@Value("${zfile.tmp.path}") String tmpFilePath) {
|
||||
ZFileConstant.TMP_FILE_PATH = tmpFilePath;
|
||||
}
|
||||
|
||||
|
||||
@Autowired(required = false)
|
||||
public void setHeaderFileName(@Value("${zfile.constant.readme}") String headerFileName) {
|
||||
@@ -60,4 +69,4 @@ public class ZFileConstant {
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -24,4 +24,4 @@ public class AudioInfoDTO {
|
||||
return audioInfoDTO;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
package im.zhaojun.zfile.model.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author zhaojun
|
||||
*/
|
||||
@Data
|
||||
public class CacheConfigDTO {
|
||||
private Boolean enableCache;
|
||||
private Boolean cacheFinish;
|
||||
private Set<String> cacheKeys;
|
||||
private Integer cacheDirectoryCount;
|
||||
private Integer cacheFileCount;
|
||||
private Date lastCacheAutoRefreshDate;
|
||||
}
|
||||
@@ -18,6 +18,8 @@ public class DriveConfigDTO {
|
||||
@JsonDeserialize(using = StorageTypeEnumJsonDeSerializerConvert.class)
|
||||
private StorageTypeEnum type;
|
||||
|
||||
private Boolean enable;
|
||||
|
||||
private boolean enableCache;
|
||||
|
||||
private boolean autoRefreshCache;
|
||||
@@ -28,6 +30,8 @@ public class DriveConfigDTO {
|
||||
|
||||
private boolean searchContainEncryptedFile;
|
||||
|
||||
private Integer orderNum;
|
||||
|
||||
private StorageStrategyConfig storageStrategyConfig;
|
||||
|
||||
}
|
||||
@@ -1,77 +0,0 @@
|
||||
package im.zhaojun.zfile.model.dto;
|
||||
|
||||
import im.zhaojun.zfile.model.enums.StorageTypeEnum;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author zhaojun
|
||||
*/
|
||||
public class InstallModelDTO {
|
||||
private String siteName;
|
||||
private StorageTypeEnum storageStrategy;
|
||||
private String username;
|
||||
private String password;
|
||||
private String domain;
|
||||
private Map<String, String> storageStrategyConfig;
|
||||
|
||||
public String getSiteName() {
|
||||
return siteName;
|
||||
}
|
||||
|
||||
public void setSiteName(String siteName) {
|
||||
this.siteName = siteName;
|
||||
}
|
||||
|
||||
public StorageTypeEnum getStorageStrategy() {
|
||||
return storageStrategy;
|
||||
}
|
||||
|
||||
public void setStorageStrategy(StorageTypeEnum storageStrategy) {
|
||||
this.storageStrategy = storageStrategy;
|
||||
}
|
||||
|
||||
public Map<String, String> getStorageStrategyConfig() {
|
||||
return storageStrategyConfig;
|
||||
}
|
||||
|
||||
public void setStorageStrategyConfig(Map<String, String> storageStrategyConfig) {
|
||||
this.storageStrategyConfig = storageStrategyConfig;
|
||||
}
|
||||
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
||||
public void setUsername(String username) {
|
||||
this.username = username;
|
||||
}
|
||||
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
public void setPassword(String password) {
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
public String getDomain() {
|
||||
return domain;
|
||||
}
|
||||
|
||||
public void setDomain(String domain) {
|
||||
this.domain = domain;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "InstallModelDTO{" +
|
||||
"siteName='" + siteName + '\'' +
|
||||
", storageStrategy=" + storageStrategy +
|
||||
", username='" + username + '\'' +
|
||||
", password='" + password + '\'' +
|
||||
", domain='" + domain + '\'' +
|
||||
", storageStrategyConfig=" + storageStrategyConfig +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package im.zhaojun.zfile.model.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class SharePointInfoVO {
|
||||
|
||||
private String type;
|
||||
|
||||
private String accessToken;
|
||||
|
||||
private String domainPrefix;
|
||||
|
||||
private String siteName;
|
||||
|
||||
private String domainType;
|
||||
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
// package im.zhaojun.zfile.model.dto;
|
||||
//
|
||||
// import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
// import lombok.Data;
|
||||
// import lombok.ToString;
|
||||
//
|
||||
// import java.io.Serializable;
|
||||
//
|
||||
// /**
|
||||
// * @author zhaojun
|
||||
// */
|
||||
// @Data
|
||||
// @ToString
|
||||
// public class SiteConfigDTO implements Serializable {
|
||||
//
|
||||
// private static final long serialVersionUID = 8811196207046121740L;
|
||||
//
|
||||
// private String readme;
|
||||
//
|
||||
// @JsonProperty("viewConfig")
|
||||
// private SystemConfigDTO systemConfigDTO;
|
||||
//
|
||||
// }
|
||||
@@ -40,4 +40,10 @@ public class StorageStrategyConfig {
|
||||
|
||||
private String basePath;
|
||||
|
||||
private String siteId;
|
||||
|
||||
private String siteName;
|
||||
|
||||
private String siteType;
|
||||
|
||||
}
|
||||
@@ -19,9 +19,6 @@ public class SystemFrontConfigDTO {
|
||||
|
||||
private Boolean searchEnable;
|
||||
|
||||
// @JsonSerialize(using = StorageTypeEnumSerializerConvert.class)
|
||||
// private StorageTypeEnum storageStrategy;
|
||||
|
||||
private String username;
|
||||
|
||||
private String domain;
|
||||
|
||||
@@ -4,8 +4,6 @@ import im.zhaojun.zfile.model.enums.StorageTypeEnum;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
|
||||
/**
|
||||
@@ -18,9 +16,10 @@ import javax.persistence.Id;
|
||||
public class DriveConfig {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private Integer id;
|
||||
|
||||
private Boolean enable;
|
||||
|
||||
private String name;
|
||||
|
||||
private Boolean enableCache;
|
||||
@@ -35,4 +34,6 @@ public class DriveConfig {
|
||||
|
||||
private Boolean searchContainEncryptedFile;
|
||||
|
||||
private Integer orderNum;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package im.zhaojun.zfile.model.entity;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
|
||||
/**
|
||||
* @author zhaojun
|
||||
*/
|
||||
@Entity(name = "FILTER_CONFIG")
|
||||
@Data
|
||||
public class FilterConfig {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private Integer id;
|
||||
|
||||
private Integer driveId;
|
||||
|
||||
private String expression;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package im.zhaojun.zfile.model.entity;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
import java.util.Date;
|
||||
|
||||
@Entity(name = "SHORT_LINK")
|
||||
@Data
|
||||
public class ShortLinkConfig {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private Integer id;
|
||||
|
||||
private String key;
|
||||
|
||||
private String url;
|
||||
|
||||
private Date createDate;
|
||||
|
||||
}
|
||||
@@ -38,43 +38,4 @@ public class StorageConfig {
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
public Integer getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Integer id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public StorageTypeEnum getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(StorageTypeEnum type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public String getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
public void setKey(String key) {
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
public void setTitle(String title) {
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void setValue(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
@@ -28,35 +28,4 @@ public class SystemConfig {
|
||||
|
||||
private String remark;
|
||||
|
||||
public Integer getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Integer id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
public void setKey(String key) {
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void setValue(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public String getRemark() {
|
||||
return remark;
|
||||
}
|
||||
|
||||
public void setRemark(String remark) {
|
||||
this.remark = remark;
|
||||
}
|
||||
}
|
||||
@@ -28,4 +28,5 @@ public enum FileTypeEnum {
|
||||
public void setValue(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -25,6 +25,8 @@ public enum StorageTypeEnum {
|
||||
S3("s3", "S3通用协议"),
|
||||
ONE_DRIVE("onedrive", "OneDrive"),
|
||||
ONE_DRIVE_CHINA("onedrive-china", "OneDrive 世纪互联"),
|
||||
SHAREPOINT_DRIVE("sharepoint", "SharePoint"),
|
||||
SHAREPOINT_DRIVE_CHINA("sharepoint-china", "SharePoint 世纪互联"),
|
||||
QINIU("qiniu", "七牛云 KODO");
|
||||
|
||||
private String key;
|
||||
@@ -63,4 +65,4 @@ public enum StorageTypeEnum {
|
||||
return enumMap.get(value.toLowerCase());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
package im.zhaojun.zfile.model.support;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @author zhaojun
|
||||
*/
|
||||
@Data
|
||||
public class Jvm {
|
||||
|
||||
/**
|
||||
* 当前 JVM 占用的内存总数 (M)
|
||||
*/
|
||||
private double total;
|
||||
|
||||
/**
|
||||
* JVM 最大可用内存总数 (M)
|
||||
*/
|
||||
private double max;
|
||||
|
||||
/**
|
||||
* JVM 空闲内存 (M)
|
||||
*/
|
||||
private double free;
|
||||
|
||||
/**
|
||||
* JDK 版本
|
||||
*/
|
||||
private String version;
|
||||
|
||||
public Jvm() {
|
||||
Runtime runtime = Runtime.getRuntime();
|
||||
this.total = runtime.totalMemory();
|
||||
this.free = runtime.freeMemory();
|
||||
this.max = runtime.maxMemory();
|
||||
this.version = System.getProperty("java.version");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
package im.zhaojun.zfile.model.support;
|
||||
|
||||
import com.sun.management.OperatingSystemMXBean;
|
||||
import lombok.Data;
|
||||
|
||||
import java.lang.management.ManagementFactory;
|
||||
|
||||
/**
|
||||
* @author zhaojun
|
||||
*/
|
||||
@Data
|
||||
public class Mem {
|
||||
|
||||
/**
|
||||
* 内存总量
|
||||
*/
|
||||
private double total;
|
||||
|
||||
/**
|
||||
* 已用内存
|
||||
*/
|
||||
private double used;
|
||||
|
||||
/**
|
||||
* 剩余内存
|
||||
*/
|
||||
private double free;
|
||||
|
||||
public Mem() {
|
||||
OperatingSystemMXBean osb = (OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean();
|
||||
// 总的物理内存+虚拟内存
|
||||
long totalVirtualMemory = osb.getTotalSwapSpaceSize();
|
||||
// 剩余的物理内存
|
||||
long freePhysicalMemorySize = osb.getFreePhysicalMemorySize();
|
||||
this.total = totalVirtualMemory;
|
||||
this.free = freePhysicalMemorySize;
|
||||
this.used = totalVirtualMemory - freePhysicalMemorySize;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package im.zhaojun.zfile.model.dto;
|
||||
package im.zhaojun.zfile.model.support;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
@@ -1,58 +0,0 @@
|
||||
package im.zhaojun.zfile.model.support;
|
||||
|
||||
import cn.hutool.core.date.BetweenFormater;
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import lombok.Data;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.core.io.Resource;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.management.ManagementFactory;
|
||||
|
||||
/**
|
||||
* @author zhaojun
|
||||
*/
|
||||
@Data
|
||||
public class Sys {
|
||||
|
||||
/**
|
||||
* 项目路径
|
||||
*/
|
||||
private String projectDir;
|
||||
|
||||
/**
|
||||
* 操作系统
|
||||
*/
|
||||
private String osName;
|
||||
|
||||
/**
|
||||
* 系统架构
|
||||
*/
|
||||
private String osArch;
|
||||
|
||||
/**
|
||||
* 系统版本
|
||||
*/
|
||||
private String osVersion;
|
||||
|
||||
/**
|
||||
* 启动时间
|
||||
*/
|
||||
private String upTime;
|
||||
|
||||
public Sys() {
|
||||
this.osName = System.getProperty("os.name");
|
||||
this.osArch = System.getProperty("os.arch");
|
||||
this.osVersion = System.getProperty("os.version");
|
||||
Resource resource = new ClassPathResource("");
|
||||
try {
|
||||
this.projectDir = resource.getFile().getAbsolutePath();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
long uptime = ManagementFactory.getRuntimeMXBean().getUptime();
|
||||
this.upTime = DateUtil.formatBetween(uptime, BetweenFormater.Level.SECOND);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
package im.zhaojun.zfile.model.support;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* @author zhaojun
|
||||
*/
|
||||
@Data
|
||||
public class SystemMonitorInfo implements Serializable {
|
||||
|
||||
/**
|
||||
* 服务器基本信息
|
||||
*/
|
||||
private Sys sys;
|
||||
|
||||
/**
|
||||
* JVM 信息
|
||||
*/
|
||||
private Jvm jvm;
|
||||
|
||||
/**
|
||||
* 系统内存
|
||||
*/
|
||||
private Mem mem;
|
||||
|
||||
public SystemMonitorInfo() {
|
||||
this.jvm = new Jvm();
|
||||
this.sys = new Sys();
|
||||
this.mem = new Mem();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
package im.zhaojun.zfile.model.support;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 用于表示校验结果的类
|
||||
*/
|
||||
@Data
|
||||
public class VerifyResult {
|
||||
|
||||
/**
|
||||
* 是否成功
|
||||
*/
|
||||
private boolean passed;
|
||||
|
||||
/**
|
||||
* 消息
|
||||
*/
|
||||
private String msg;
|
||||
|
||||
/**
|
||||
* 代码
|
||||
*/
|
||||
private Integer code;
|
||||
|
||||
public static VerifyResult success() {
|
||||
VerifyResult verifyResult = new VerifyResult();
|
||||
verifyResult.setPassed(true);
|
||||
return verifyResult;
|
||||
}
|
||||
|
||||
public static VerifyResult fail(String msg) {
|
||||
VerifyResult verifyResult = new VerifyResult();
|
||||
verifyResult.setPassed(false);
|
||||
verifyResult.setMsg(msg);
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -3,6 +3,8 @@ package im.zhaojun.zfile.repository;
|
||||
import im.zhaojun.zfile.model.entity.DriveConfig;
|
||||
import im.zhaojun.zfile.model.enums.StorageTypeEnum;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.Modifying;
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.List;
|
||||
@@ -19,8 +21,45 @@ public interface DriverConfigRepository extends JpaRepository<DriveConfig, Integ
|
||||
* @param type
|
||||
* 存储类型
|
||||
*
|
||||
* @return 指定存储类型的存储器
|
||||
* @return 指定存储类型的驱动器
|
||||
*/
|
||||
List<DriveConfig> findByType(StorageTypeEnum type);
|
||||
|
||||
|
||||
/**
|
||||
* 更新驱动器 ID 的排序值
|
||||
*
|
||||
* @param orderNum
|
||||
* 排序值
|
||||
*
|
||||
* @param id
|
||||
* 驱动器 ID
|
||||
*/
|
||||
@Modifying
|
||||
@Query(value="update DRIVER_CONFIG set orderNum = :orderNum where id = :id")
|
||||
void updateSetOrderNumById(Integer orderNum, Integer id);
|
||||
|
||||
|
||||
/**
|
||||
* 查询驱动器最大的 ID
|
||||
*
|
||||
* @return 驱动器最大 ID
|
||||
*/
|
||||
@Query(nativeQuery = true, value = "select max(id) max from DRIVER_CONFIG")
|
||||
Integer selectMaxId();
|
||||
|
||||
|
||||
/**
|
||||
* 更新驱动器 ID
|
||||
*
|
||||
* @param updateId
|
||||
* 驱动器原 ID
|
||||
*
|
||||
* @param newId
|
||||
* 驱动器新 ID
|
||||
*/
|
||||
@Modifying
|
||||
@Query(value="update DRIVER_CONFIG set id = :newId where id = :updateId")
|
||||
void updateId(Integer updateId, Integer newId);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package im.zhaojun.zfile.repository;
|
||||
|
||||
import im.zhaojun.zfile.model.entity.FilterConfig;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author zhaojun
|
||||
*/
|
||||
@Repository
|
||||
public interface FilterConfigRepository extends JpaRepository<FilterConfig, Integer> {
|
||||
|
||||
/**
|
||||
* 获取驱动器下的所有规则
|
||||
* @param driveId
|
||||
* 驱动器 ID
|
||||
*/
|
||||
List<FilterConfig> findByDriveId(Integer driveId);
|
||||
|
||||
/**
|
||||
* 根据驱动器 ID 删除其所有的规则
|
||||
* @param driveId
|
||||
* 驱动器 ID
|
||||
*/
|
||||
void deleteByDriveId(Integer driveId);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
package im.zhaojun.zfile.repository;
|
||||
|
||||
import im.zhaojun.zfile.model.entity.ShortLinkConfig;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* @author zhaojun
|
||||
*/
|
||||
@Repository
|
||||
public interface ShortLinkConfigRepository extends JpaRepository<ShortLinkConfig, Integer>, JpaSpecificationExecutor<ShortLinkConfig> {
|
||||
|
||||
/**
|
||||
* 获取驱动器下的所有规则
|
||||
*
|
||||
* @param key
|
||||
* 驱动器 ID
|
||||
*/
|
||||
ShortLinkConfig findByKey(String key);
|
||||
|
||||
@Query(nativeQuery = true,
|
||||
value = " select * from SHORT_LINK where " +
|
||||
" key like concat('%', :key,'%') " +
|
||||
" and url like concat('%', :url,'%') " +
|
||||
" and (:dateFrom is null or create_date >= :dateFrom" +
|
||||
" and (:dateTo is null or create_date <= :dateTo) ",
|
||||
countQuery = " select count(1) from SHORT_LINK where " +
|
||||
" key like concat('%', :key,'%') " +
|
||||
" and url like concat('%', :url,'%') " +
|
||||
" and (:dateFrom is null or create_date >= :dateFrom" +
|
||||
" and (:dateTo is null or create_date <= :dateTo) "
|
||||
)
|
||||
// @Query(nativeQuery = true,
|
||||
// value = " select * from SHORT_LINK where " +
|
||||
// " key like concat('%', :key,'%') " +
|
||||
// " and url like concat('%', :url,'%') " +
|
||||
// " and (:dateFrom is null or date_format(create_date, '%Y-%m-%d') >= date_format(:dateFrom, '%Y-%m-%d'))" +
|
||||
// " and (:dateTo is null or date_format(create_date, '%Y-%m-%d') <= date_format(:dateTo, '%Y-%m-%d')) ) ",
|
||||
// countQuery = " select count(1) from SHORT_LINK where " +
|
||||
// " key like concat('%', :key,'%') " +
|
||||
// " and url like concat('%', :url,'%') " +
|
||||
// " and (:dateFrom is null or date_format(create_date, '%Y-%m-%d') >= date_format(:dateFrom, '%Y-%m-%d'))" +
|
||||
// " and (:dateTo is null or date_format(create_date, '%Y-%m-%d') <= date_format(:dateTo, '%Y-%m-%d')) ) "
|
||||
// )
|
||||
Page<ShortLinkConfig> findByPage(String key, String url, Date dateFrom, Date dateTo, Pageable pageable);
|
||||
}
|
||||
@@ -3,6 +3,8 @@ package im.zhaojun.zfile.repository;
|
||||
import im.zhaojun.zfile.model.entity.StorageConfig;
|
||||
import im.zhaojun.zfile.model.enums.StorageTypeEnum;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.Modifying;
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.List;
|
||||
@@ -68,4 +70,18 @@ public interface StorageConfigRepository extends JpaRepository<StorageConfig, In
|
||||
*/
|
||||
StorageConfig findByDriveIdAndKey(Integer driveId, String key);
|
||||
|
||||
|
||||
/**
|
||||
* 更新驱动器 ID 对应的参数设置为新的驱动器 ID
|
||||
*
|
||||
* @param updateId
|
||||
* 驱动器原 ID
|
||||
*
|
||||
* @param newId
|
||||
* 驱动器新 ID
|
||||
*/
|
||||
@Modifying
|
||||
@Query(value="update STORAGE_CONFIG set driveId = :newId where driveId = :updateId")
|
||||
void updateDriveId(Integer updateId, Integer newId);
|
||||
|
||||
}
|
||||
@@ -1,19 +1,17 @@
|
||||
package im.zhaojun.zfile.schedule;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import im.zhaojun.zfile.context.DriveContext;
|
||||
import im.zhaojun.zfile.model.entity.DriveConfig;
|
||||
import im.zhaojun.zfile.model.enums.StorageTypeEnum;
|
||||
import im.zhaojun.zfile.service.DriveConfigService;
|
||||
import im.zhaojun.zfile.service.base.AbstractOneDriveServiceBase;
|
||||
import im.zhaojun.zfile.service.impl.OneDriveChinaServiceImpl;
|
||||
import im.zhaojun.zfile.service.impl.OneDriveServiceImpl;
|
||||
import im.zhaojun.zfile.context.DriveContext;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.scheduling.annotation.EnableScheduling;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@@ -25,12 +23,6 @@ import java.util.List;
|
||||
@Slf4j
|
||||
public class OneDriveTokenRefreshSchedule {
|
||||
|
||||
@Resource
|
||||
private OneDriveServiceImpl oneDriveServiceImpl;
|
||||
|
||||
@Resource
|
||||
private OneDriveChinaServiceImpl oneDriveChinaServiceImpl;
|
||||
|
||||
@Resource
|
||||
private DriveConfigService driveConfigService;
|
||||
|
||||
@@ -54,17 +46,17 @@ public class OneDriveTokenRefreshSchedule {
|
||||
String name = driveConfig.getName();
|
||||
|
||||
try {
|
||||
AbstractOneDriveServiceBase driveService = (AbstractOneDriveServiceBase) driveContext.getDriveService(driveConfig.getId());
|
||||
AbstractOneDriveServiceBase driveService = (AbstractOneDriveServiceBase) driveContext.get(driveConfig.getId());
|
||||
driveService.refreshOneDriveToken();
|
||||
log.info("刷新驱动器 {}, {} key 时间: {}", name, storageType.getDescription(), LocalDateTime.now());
|
||||
log.info("尝试刷新 OneDrive Token, DriveInfo: {}", JSON.toJSONString(driveConfig));
|
||||
} catch (Exception e) {
|
||||
log.debug("刷新驱动器 " + name + " Token 失败.", e);
|
||||
log.error("刷新 OneDrive Token 失败, DriveInfo: {}", JSON.toJSONString(driveConfig), e);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
} catch (Throwable e) {
|
||||
log.debug("尝试调用 OneDrive 自动刷新 AccessToken 定时任务出现未知异常", e);
|
||||
log.error("尝试调用 OneDrive 自动刷新 AccessToken 定时任务出现未知异常", e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package im.zhaojun.zfile.security;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import im.zhaojun.zfile.model.dto.ResultBean;
|
||||
import im.zhaojun.zfile.model.support.ResultBean;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.security.authentication.BadCredentialsException;
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
package im.zhaojun.zfile.service;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import im.zhaojun.zfile.cache.ZFileCache;
|
||||
import im.zhaojun.zfile.context.DriveContext;
|
||||
import im.zhaojun.zfile.context.StorageTypeContext;
|
||||
import im.zhaojun.zfile.exception.InitializeException;
|
||||
import im.zhaojun.zfile.exception.InitializeDriveException;
|
||||
import im.zhaojun.zfile.model.constant.StorageConfigConstant;
|
||||
import im.zhaojun.zfile.model.dto.CacheInfoDTO;
|
||||
import im.zhaojun.zfile.model.dto.DriveConfigDTO;
|
||||
@@ -16,6 +17,8 @@ import im.zhaojun.zfile.repository.StorageConfigRepository;
|
||||
import im.zhaojun.zfile.service.base.AbstractBaseFileService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.data.domain.Example;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@@ -47,13 +50,29 @@ public class DriveConfigService {
|
||||
|
||||
public static final Class<StorageStrategyConfig> STORAGE_STRATEGY_CONFIG_CLASS = StorageStrategyConfig.class;
|
||||
|
||||
|
||||
/**
|
||||
* 获取所有驱动器列表
|
||||
*
|
||||
* @return 驱动器列表
|
||||
*/
|
||||
public List<DriveConfig> list() {
|
||||
return driverConfigRepository.findAll();
|
||||
Sort sort = new Sort(Sort.Direction.ASC,"orderNum");
|
||||
return driverConfigRepository.findAll(sort);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取所有已启用的驱动器列表
|
||||
*
|
||||
* @return 已启用的驱动器列表
|
||||
*/
|
||||
public List<DriveConfig> listOnlyEnable() {
|
||||
DriveConfig driveConfig = new DriveConfig();
|
||||
driveConfig.setEnable(true);
|
||||
Example<DriveConfig> example = Example.of(driveConfig);
|
||||
Sort sort = new Sort(Sort.Direction.ASC,"orderNum");
|
||||
return driverConfigRepository.findAll(example, sort);
|
||||
}
|
||||
|
||||
|
||||
@@ -66,7 +85,7 @@ public class DriveConfigService {
|
||||
* @return 驱动器设置
|
||||
*/
|
||||
public DriveConfig findById(Integer id) {
|
||||
return driverConfigRepository.findById(id).get();
|
||||
return driverConfigRepository.findById(id).orElse(null);
|
||||
}
|
||||
|
||||
|
||||
@@ -101,9 +120,7 @@ public class DriveConfigService {
|
||||
declaredField.set(storageStrategyConfig, value);
|
||||
}
|
||||
} catch (NoSuchFieldException | IllegalAccessException e) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("通过反射, 将字段 {" + key + "}注入 DriveConfigDTO 时出现异常:", e);
|
||||
}
|
||||
log.error("通过反射, 将字段 {} 注入 DriveConfigDTO 时出现异常:", key, e);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -112,6 +129,7 @@ public class DriveConfigService {
|
||||
return driveConfigDTO;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取指定驱动器的存储策略.
|
||||
*
|
||||
@@ -121,18 +139,26 @@ public class DriveConfigService {
|
||||
* @return 驱动器对应的存储策略.
|
||||
*/
|
||||
public StorageTypeEnum findStorageTypeById(Integer id) {
|
||||
// return findById(id).getType();
|
||||
return driverConfigRepository.findById(id).get().getType();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 更新驱动器设置
|
||||
* @param driveConfig 驱动器设置
|
||||
*/
|
||||
public void updateDriveConfig(DriveConfig driveConfig) {
|
||||
driverConfigRepository.save(driveConfig);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 保存驱动器基本信息及其对应的参数设置
|
||||
*
|
||||
* @param driveConfigDTO 驱动器 DTO 对象
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void save(DriveConfigDTO driveConfigDTO) {
|
||||
public void saveDriveConfigDTO(DriveConfigDTO driveConfigDTO) {
|
||||
|
||||
// 判断是新增还是修改
|
||||
boolean updateFlag = driveConfigDTO.getId() != null;
|
||||
@@ -141,13 +167,12 @@ public class DriveConfigService {
|
||||
DriveConfig driveConfig = new DriveConfig();
|
||||
StorageTypeEnum storageType = driveConfigDTO.getType();
|
||||
BeanUtils.copyProperties(driveConfigDTO, driveConfig);
|
||||
driverConfigRepository.save(driveConfig);
|
||||
|
||||
if (driveConfig.getAutoRefreshCache()) {
|
||||
startAutoCacheRefresh(driveConfig.getId());
|
||||
} else {
|
||||
stopAutoCacheRefresh(driveConfig.getId());
|
||||
if (driveConfig.getId() == null) {
|
||||
Integer nextId = selectNextId();
|
||||
driveConfig.setId(nextId);
|
||||
}
|
||||
driverConfigRepository.save(driveConfig);
|
||||
|
||||
// 保存存储策略设置.
|
||||
StorageStrategyConfig storageStrategyConfig = driveConfigDTO.getStorageStrategyConfig();
|
||||
@@ -173,20 +198,57 @@ public class DriveConfigService {
|
||||
storageConfig.setType(storageType);
|
||||
storageConfig.setDriveId(driveConfig.getId());
|
||||
} catch (IllegalAccessException | NoSuchFieldException e) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("通过反射, 从 StorageStrategyConfig 中获取字段 {" + key + "} 时出现异常:", e);
|
||||
}
|
||||
log.error("通过反射, 从 StorageStrategyConfig 中获取字段 {} 时出现异常:", key, e);
|
||||
}
|
||||
|
||||
}
|
||||
storageConfigRepository.saveAll(storageConfigList);
|
||||
|
||||
driveContext.initDrive(driveConfig.getId());
|
||||
driveContext.init(driveConfig.getId());
|
||||
|
||||
AbstractBaseFileService driveService = driveContext.getDriveService(driveConfig.getId());
|
||||
AbstractBaseFileService driveService = driveContext.get(driveConfig.getId());
|
||||
if (driveService.getIsUnInitialized()) {
|
||||
throw new InitializeException("初始化异常, 请检查配置是否正确.");
|
||||
throw new InitializeDriveException("初始化异常, 请检查配置是否正确.");
|
||||
}
|
||||
|
||||
if (driveConfig.getAutoRefreshCache()) {
|
||||
startAutoCacheRefresh(driveConfig.getId());
|
||||
} else if (updateFlag){
|
||||
stopAutoCacheRefresh(driveConfig.getId());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 查询驱动器最大的 ID
|
||||
*
|
||||
* @return 驱动器最大 ID
|
||||
*/
|
||||
public Integer selectNextId() {
|
||||
Integer maxId = driverConfigRepository.selectMaxId();
|
||||
if (maxId == null) {
|
||||
maxId = 1;
|
||||
}
|
||||
|
||||
return maxId + 1;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 更新驱动器 ID
|
||||
*
|
||||
* @param updateId
|
||||
* 驱动器原 ID
|
||||
*
|
||||
* @param newId
|
||||
* 驱动器新 ID
|
||||
*/
|
||||
@Transactional
|
||||
public void updateId(Integer updateId, Integer newId) {
|
||||
driverConfigRepository.updateId(updateId, newId);
|
||||
storageConfigRepository.updateDriveId(updateId, newId);
|
||||
driveContext.updateDriveId(updateId, newId);
|
||||
}
|
||||
|
||||
|
||||
@@ -198,9 +260,20 @@ public class DriveConfigService {
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void deleteById(Integer id) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("尝试删除驱动器, driveId: {}", id);
|
||||
}
|
||||
DriveConfig driveConfig = driverConfigRepository.getOne(id);
|
||||
driverConfigRepository.deleteById(id);
|
||||
storageConfigRepository.deleteByDriveId(id);
|
||||
driveContext.destroyDrive(id);
|
||||
if (driveConfig.getEnableCache()) {
|
||||
zFileCache.stopAutoCacheRefresh(id);
|
||||
zFileCache.clear(id);
|
||||
}
|
||||
driveContext.destroy(id);
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("尝试删除驱动器成功, 已清理相关数据, driveId: {}", id);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -210,7 +283,7 @@ public class DriveConfigService {
|
||||
* @param type
|
||||
* 存储类型
|
||||
*
|
||||
* @return 指定存储类型的存储器
|
||||
* @return 指定存储类型的驱动器
|
||||
*/
|
||||
public List<DriveConfig> findByType(StorageTypeEnum type) {
|
||||
return driverConfigRepository.findByType(type);
|
||||
@@ -235,24 +308,6 @@ public class DriveConfigService {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 更新指定驱动器的缓存启用状态
|
||||
*
|
||||
* @param driveId
|
||||
* 驱动器 ID
|
||||
*
|
||||
* @param autoRefreshCache
|
||||
* 是否启用缓存自动刷新
|
||||
*/
|
||||
public void updateAutoRefreshCacheStatus(Integer driveId, Boolean autoRefreshCache) {
|
||||
DriveConfig driveConfig = findById(driveId);
|
||||
if (driveConfig != null) {
|
||||
driveConfig.setAutoRefreshCache(autoRefreshCache);
|
||||
driverConfigRepository.save(driveConfig);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取指定驱动器的缓存信息
|
||||
* @param driveId
|
||||
@@ -268,7 +323,6 @@ public class DriveConfigService {
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 刷新指定 key 的缓存:
|
||||
* 1. 清空此 key 的缓存.
|
||||
@@ -281,15 +335,17 @@ public class DriveConfigService {
|
||||
* 缓存 key (文件夹名称)
|
||||
*/
|
||||
public void refreshCache(Integer driveId, String key) throws Exception {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("手动刷新缓存 driveId: {}, key: {}", driveId, key);
|
||||
}
|
||||
zFileCache.remove(driveId, key);
|
||||
AbstractBaseFileService baseFileService = driveContext.getDriveService(driveId);
|
||||
AbstractBaseFileService baseFileService = driveContext.get(driveId);
|
||||
baseFileService.fileList(key);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 开启缓存自动刷新, 仅当数据库设置为开启时, 才会真正开启缓存自动刷新.
|
||||
* 开启缓存自动刷新
|
||||
*
|
||||
* @param driveId
|
||||
* 驱动器 ID
|
||||
@@ -326,4 +382,15 @@ public class DriveConfigService {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 交换驱动器排序
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void saveDriveDrag(List<JSONObject> driveConfigs) {
|
||||
for (int i = 0; i < driveConfigs.size(); i++) {
|
||||
JSONObject item = driveConfigs.get(i);
|
||||
driverConfigRepository.updateSetOrderNumById(i, item.getInteger("id"));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
package im.zhaojun.zfile.service;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import im.zhaojun.zfile.model.entity.FilterConfig;
|
||||
import im.zhaojun.zfile.repository.FilterConfigRepository;
|
||||
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;
|
||||
|
||||
/**
|
||||
* @author zhaojun
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
public class FilterConfigService {
|
||||
|
||||
@Resource
|
||||
private FilterConfigRepository filterConfigRepository;
|
||||
|
||||
public List<FilterConfig> findByDriveId(Integer driveId) {
|
||||
return filterConfigRepository.findByDriveId(driveId);
|
||||
}
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void batchSave(List<FilterConfig> filterConfigList, Integer driveId) {
|
||||
filterConfigRepository.deleteByDriveId(driveId);
|
||||
filterConfigRepository.saveAll(filterConfigList);
|
||||
}
|
||||
|
||||
/**
|
||||
* 指定驱动器下的文件名称, 根据过滤表达式判断是否会显示, 如果符合任意一条表达式, 则不显示, 反之则显示.
|
||||
* @param driveId
|
||||
* 驱动器 ID
|
||||
* @param fileName
|
||||
* 文件名
|
||||
* @return 是否显示
|
||||
*/
|
||||
public boolean filterResultIsHidden(Integer driveId, String fileName) {
|
||||
List<FilterConfig> filterConfigList = findByDriveId(driveId);
|
||||
|
||||
for (FilterConfig filterConfig : filterConfigList) {
|
||||
String expression = filterConfig.getExpression();
|
||||
if (StrUtil.isEmpty(expression)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
PathMatcher pathMatcher = FileSystems.getDefault().getPathMatcher("glob:" + expression);
|
||||
boolean match = pathMatcher.matches(Paths.get(fileName));
|
||||
if (match) {
|
||||
return true;
|
||||
}
|
||||
log.debug("regex: {}, name {}, contains: {}", expression, fileName, match);
|
||||
} catch (Exception e) {
|
||||
log.debug("regex: {}, name {}, parse error, skip expression", expression, fileName);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
package im.zhaojun.zfile.service;
|
||||
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import im.zhaojun.zfile.model.entity.ShortLinkConfig;
|
||||
import im.zhaojun.zfile.repository.ShortLinkConfigRepository;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.jpa.domain.Specification;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.persistence.criteria.Predicate;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
@Service
|
||||
public class ShortLinkConfigService {
|
||||
|
||||
@Resource
|
||||
private ShortLinkConfigRepository shortLinkConfigRepository;
|
||||
|
||||
public ShortLinkConfig findByKey(String key) {
|
||||
return shortLinkConfigRepository.findByKey(key);
|
||||
}
|
||||
|
||||
public void save(ShortLinkConfig shortLinkConfig) {
|
||||
shortLinkConfig.setCreateDate(new Date());
|
||||
shortLinkConfigRepository.save(shortLinkConfig);
|
||||
}
|
||||
|
||||
public Page<ShortLinkConfig> find(String key,
|
||||
String url,
|
||||
String dateFrom,
|
||||
String dateTo,
|
||||
Integer page,
|
||||
Integer limit,
|
||||
String orderBy,
|
||||
String orderDirection) {
|
||||
|
||||
Sort sort = Sort.by("desc".equals(orderDirection) ? Sort.Direction.DESC : Sort.Direction.ASC, orderBy);
|
||||
Pageable pageable = PageRequest.of(page - 1, limit, sort);
|
||||
|
||||
Specification<ShortLinkConfig> specification = (root, criteriaQuery, criteriaBuilder) -> {
|
||||
List<Predicate> predicates = new ArrayList<>();
|
||||
|
||||
if (StrUtil.isNotEmpty(dateFrom) && StrUtil.isNotEmpty(dateTo)) {
|
||||
predicates.add(criteriaBuilder.between(root.get("createDate"),
|
||||
DateUtil.parseDateTime(dateFrom + " 00:00:00"),
|
||||
DateUtil.parseDateTime(dateTo + " 23:59:59")));
|
||||
}
|
||||
|
||||
if (StrUtil.isNotEmpty(key)) {
|
||||
predicates.add(criteriaBuilder.like(root.get("key"), "%" + key + '%'));
|
||||
}
|
||||
|
||||
if (StrUtil.isNotEmpty(url)) {
|
||||
predicates.add(criteriaBuilder.like(root.get("url"), "%" + url + '%'));
|
||||
}
|
||||
|
||||
return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()]));
|
||||
};
|
||||
return shortLinkConfigRepository.findAll(specification, pageable);
|
||||
}
|
||||
|
||||
public void deleteById(Integer id) {
|
||||
shortLinkConfigRepository.deleteById(id);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -3,6 +3,7 @@ package im.zhaojun.zfile.service;
|
||||
import cn.hutool.core.convert.Convert;
|
||||
import cn.hutool.crypto.SecureUtil;
|
||||
import im.zhaojun.zfile.cache.ZFileCache;
|
||||
import im.zhaojun.zfile.exception.InvalidDriveException;
|
||||
import im.zhaojun.zfile.model.constant.SystemConfigConstant;
|
||||
import im.zhaojun.zfile.model.dto.SystemConfigDTO;
|
||||
import im.zhaojun.zfile.model.dto.SystemFrontConfigDTO;
|
||||
@@ -61,9 +62,7 @@ public class SystemConfigService {
|
||||
Object convertVal = Convert.convert(field.getType(), strVal);
|
||||
field.set(systemConfigDTO, convertVal);
|
||||
} catch (NoSuchFieldException | IllegalAccessException e) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("通过反射, 将字段 {" + key + "}注入 SystemConfigDTO 时出现异常:", e);
|
||||
}
|
||||
log.error("通过反射, 将字段 {} 注入 SystemConfigDTO 时出现异常:", key, e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -93,9 +92,7 @@ public class SystemConfigService {
|
||||
try {
|
||||
val = field.get(systemConfigDTO);
|
||||
} catch (IllegalAccessException e) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("通过反射, 从 SystemConfigDTO 获取字段 {" + key + "} 时出现异常:", e);
|
||||
}
|
||||
log.error("通过反射, 从 SystemConfigDTO 获取字段 {} 时出现异常:", key, e);
|
||||
}
|
||||
|
||||
if (val != null) {
|
||||
@@ -124,6 +121,9 @@ public class SystemConfigService {
|
||||
BeanUtils.copyProperties(systemConfig, systemFrontConfigDTO);
|
||||
|
||||
DriveConfig driveConfig = driveConfigService.findById(driveId);
|
||||
if (driveConfig == null) {
|
||||
throw new InvalidDriveException("此驱动器不存在或初始化失败, 请检查后台参数配置");
|
||||
}
|
||||
systemFrontConfigDTO.setSearchEnable(driveConfig.getSearchEnable());
|
||||
return systemFrontConfigDTO;
|
||||
}
|
||||
|
||||
@@ -1,69 +0,0 @@
|
||||
// package im.zhaojun.zfile.service;
|
||||
//
|
||||
// import im.zhaojun.zfile.model.constant.ZFileConstant;
|
||||
// import im.zhaojun.zfile.model.dto.FileItemDTO;
|
||||
// import im.zhaojun.zfile.model.dto.SiteConfigDTO;
|
||||
// import im.zhaojun.zfile.model.enums.StorageTypeEnum;
|
||||
// import im.zhaojun.zfile.service.base.AbstractBaseFileService;
|
||||
// import im.zhaojun.zfile.context.DriveContext;
|
||||
// import im.zhaojun.zfile.util.HttpUtil;
|
||||
// import im.zhaojun.zfile.util.StringUtils;
|
||||
// import lombok.extern.slf4j.Slf4j;
|
||||
// import org.springframework.stereotype.Service;
|
||||
// import org.springframework.web.client.HttpClientErrorException;
|
||||
//
|
||||
// import javax.annotation.Resource;
|
||||
// import java.util.ArrayList;
|
||||
// import java.util.List;
|
||||
// import java.util.Objects;
|
||||
//
|
||||
// /**
|
||||
// * @author zhaojun
|
||||
// */
|
||||
// @Slf4j
|
||||
// @Service
|
||||
// public class SystemService {
|
||||
//
|
||||
// @Resource
|
||||
// private DriveContext driveContext;
|
||||
//
|
||||
// /**
|
||||
// * 构建指定路径下标题, 页面文档信息
|
||||
// * @param path 路径
|
||||
// */
|
||||
// public SiteConfigDTO getConfig(Integer driveId, String path) throws Exception {
|
||||
//
|
||||
// SiteConfigDTO siteConfigDTO = new SiteConfigDTO();
|
||||
//
|
||||
// AbstractBaseFileService fileService = driveContext.getDriveService(driveId);
|
||||
//
|
||||
// List<FileItemDTO> fileItemList;
|
||||
//
|
||||
// if (Objects.equals(fileService.getStorageTypeEnum(), StorageTypeEnum.FTP)) {
|
||||
// fileItemList = new ArrayList<>();
|
||||
// } else {
|
||||
// fileItemList = fileService.fileList(path);
|
||||
// }
|
||||
//
|
||||
// for (FileItemDTO fileItemDTO : fileItemList) {
|
||||
// if (ZFileConstant.README_FILE_NAME.equalsIgnoreCase(fileItemDTO.getName())) {
|
||||
// String textContent = null;
|
||||
// try {
|
||||
// textContent = HttpUtil.getTextContent(fileItemDTO.getUrl());
|
||||
// } catch (HttpClientErrorException httpClientErrorException) {
|
||||
// log.debug("尝试重新获取文档区缓存中链接后仍失败", httpClientErrorException);
|
||||
// try {
|
||||
// String fullPath = StringUtils.removeDuplicateSeparator(fileItemDTO.getPath() + "/" + fileItemDTO.getName());
|
||||
// FileItemDTO fileItem = fileService.getFileItem(fullPath);
|
||||
// textContent = HttpUtil.getTextContent(fileItem.getUrl());
|
||||
// } catch (Exception e) {
|
||||
// log.debug("尝试重新获取文档区链接后仍失败, 已置为空", e);
|
||||
// }
|
||||
// }
|
||||
// siteConfigDTO.setReadme(textContent);
|
||||
// }
|
||||
// }
|
||||
// return siteConfigDTO;
|
||||
// }
|
||||
//
|
||||
// }
|
||||
@@ -1,12 +1,11 @@
|
||||
package im.zhaojun.zfile.service.base;
|
||||
|
||||
import im.zhaojun.zfile.cache.ZFileCache;
|
||||
import im.zhaojun.zfile.exception.InitializeDriveException;
|
||||
import im.zhaojun.zfile.model.dto.FileItemDTO;
|
||||
import im.zhaojun.zfile.model.entity.StorageConfig;
|
||||
import im.zhaojun.zfile.model.enums.StorageTypeEnum;
|
||||
import im.zhaojun.zfile.service.SystemConfigService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.aop.framework.AopContext;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
@@ -18,6 +17,10 @@ import java.util.List;
|
||||
@Slf4j
|
||||
public abstract class AbstractBaseFileService implements BaseFileService {
|
||||
|
||||
|
||||
@Resource
|
||||
private ZFileCache zFileCache;
|
||||
|
||||
/**
|
||||
* 下载链接过期时间, 目前只在兼容 S3 协议的存储策略中使用到.
|
||||
*/
|
||||
@@ -29,23 +32,16 @@ public abstract class AbstractBaseFileService implements BaseFileService {
|
||||
*/
|
||||
protected boolean isInitialized = false;
|
||||
|
||||
|
||||
/**
|
||||
* 基路径
|
||||
*/
|
||||
protected String basePath;
|
||||
|
||||
/**
|
||||
* 驱动器 ID
|
||||
*/
|
||||
public Integer driveId;
|
||||
|
||||
@Resource
|
||||
private SystemConfigService systemConfigService;
|
||||
|
||||
@Resource
|
||||
private ZFileCache zFileCache;
|
||||
|
||||
|
||||
/***
|
||||
* 获取指定路径下的文件及文件夹, 默认缓存 60 分钟,每隔 30 分钟刷新一次.
|
||||
*
|
||||
@@ -70,24 +66,22 @@ public abstract class AbstractBaseFileService implements BaseFileService {
|
||||
|
||||
/**
|
||||
* 初始化方法, 启动时自动调用实现类的此方法进行初始化.
|
||||
*
|
||||
* @param driveId
|
||||
* 驱动器 ID
|
||||
*/
|
||||
public abstract void init(Integer driveId);
|
||||
|
||||
|
||||
/**
|
||||
* 测试是否连接成功, 会尝试取调用获取根路径的文件, 如果没有抛出异常, 则认为连接成功, 某些存储策略需要复写此方法.
|
||||
*
|
||||
* @return 连接结果
|
||||
*/
|
||||
protected boolean testConnection() {
|
||||
boolean flag = true;
|
||||
protected void testConnection() {
|
||||
try {
|
||||
fileList("/");
|
||||
} catch (Exception e) {
|
||||
log.debug(getStorageTypeEnum().getDescription() + " 初始化异常", e);
|
||||
flag = false;
|
||||
throw new InitializeDriveException("初始化异常, 错误信息为: " + e.getMessage(), e);
|
||||
}
|
||||
return flag;
|
||||
}
|
||||
|
||||
|
||||
@@ -120,7 +114,7 @@ public abstract class AbstractBaseFileService implements BaseFileService {
|
||||
|
||||
|
||||
/**
|
||||
* 获取初始化当前存储策略, 所需要的参数信息 (表单填写)
|
||||
* 获取初始化当前存储策略, 所需要的参数信息 (用于表单填写)
|
||||
*
|
||||
* @return 初始化所需的参数列表
|
||||
*/
|
||||
@@ -150,4 +144,11 @@ public abstract class AbstractBaseFileService implements BaseFileService {
|
||||
*/
|
||||
public abstract FileItemDTO getFileItem(String path);
|
||||
|
||||
public Integer getDriveId() {
|
||||
return driveId;
|
||||
}
|
||||
|
||||
public void setDriveId(Integer driveId) {
|
||||
this.driveId = driveId;
|
||||
}
|
||||
}
|
||||
@@ -1,238 +1,26 @@
|
||||
package im.zhaojun.zfile.service.base;
|
||||
|
||||
import cn.hutool.core.util.URLUtil;
|
||||
import cn.hutool.http.HttpRequest;
|
||||
import cn.hutool.http.HttpResponse;
|
||||
import cn.hutool.http.HttpUtil;
|
||||
import com.alibaba.fastjson.JSONArray;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import im.zhaojun.zfile.model.constant.StorageConfigConstant;
|
||||
import im.zhaojun.zfile.model.constant.ZFileConstant;
|
||||
import im.zhaojun.zfile.model.dto.FileItemDTO;
|
||||
import im.zhaojun.zfile.model.entity.StorageConfig;
|
||||
import im.zhaojun.zfile.model.enums.FileTypeEnum;
|
||||
import im.zhaojun.zfile.model.support.OneDriveToken;
|
||||
import im.zhaojun.zfile.repository.StorageConfigRepository;
|
||||
import im.zhaojun.zfile.service.StorageConfigService;
|
||||
import im.zhaojun.zfile.util.StringUtils;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.http.HttpEntity;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.web.client.HttpClientErrorException;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Zhao Jun
|
||||
*/
|
||||
@Slf4j
|
||||
public abstract class AbstractOneDriveServiceBase extends AbstractBaseFileService {
|
||||
|
||||
protected static final String DRIVER_INFO_URL = "https://{graphEndPoint}/v1.0/me/drives";
|
||||
|
||||
protected static final String DRIVER_ROOT_URL = "https://{graphEndPoint}/v1.0/me/drive/root/children";
|
||||
|
||||
protected static final String DRIVER_ITEMS_URL = "https://{graphEndPoint}/v1.0/me/drive/root:{path}:/children";
|
||||
|
||||
protected static final String DRIVER_ITEM_URL = "https://{graphEndPoint}/v1.0/me/drive/root:{path}";
|
||||
|
||||
protected static final String AUTHENTICATE_URL = "https://{authenticateEndPoint}/common/oauth2/v2.0/token";
|
||||
|
||||
private static final String ONE_DRIVE_FILE_FLAG = "file";
|
||||
|
||||
@Resource
|
||||
@Lazy
|
||||
private RestTemplate oneDriveRestTemplate;
|
||||
|
||||
@Resource
|
||||
private StorageConfigRepository storageConfigRepository;
|
||||
|
||||
@Resource
|
||||
private StorageConfigService storageConfigService;
|
||||
|
||||
/**
|
||||
* 根据 RefreshToken 刷新 AccessToken, 返回刷新后的 Token.
|
||||
*
|
||||
* @return 刷新后的 Token
|
||||
*/
|
||||
public OneDriveToken getRefreshToken() {
|
||||
StorageConfig refreshStorageConfig =
|
||||
storageConfigRepository.findByDriveIdAndKey(driveId, StorageConfigConstant.REFRESH_TOKEN_KEY);
|
||||
|
||||
String param = "client_id=" + getClientId() +
|
||||
"&redirect_uri=" + getRedirectUri() +
|
||||
"&client_secret=" + getClientSecret() +
|
||||
"&refresh_token=" + refreshStorageConfig.getValue() +
|
||||
"&grant_type=refresh_token";
|
||||
|
||||
String fullAuthenticateUrl = AUTHENTICATE_URL.replace("{authenticateEndPoint}", getAuthenticateEndPoint());
|
||||
HttpRequest post = HttpUtil.createPost(fullAuthenticateUrl);
|
||||
|
||||
post.body(param, "application/x-www-form-urlencoded");
|
||||
HttpResponse response = post.execute();
|
||||
return JSONObject.parseObject(response.body(), OneDriveToken.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* OAuth2 协议中, 根据 code 换取 access_token 和 refresh_token.
|
||||
*
|
||||
* @param code
|
||||
* 代码
|
||||
*
|
||||
* @return 获取的 Token 信息.
|
||||
*/
|
||||
public OneDriveToken getToken(String code) {
|
||||
String param = "client_id=" + getClientId() +
|
||||
"&redirect_uri=" + getRedirectUri() +
|
||||
"&client_secret=" + getClientSecret() +
|
||||
"&code=" + code +
|
||||
"&scope=" + getScope() +
|
||||
"&grant_type=authorization_code";
|
||||
|
||||
String fullAuthenticateUrl = AUTHENTICATE_URL.replace("{authenticateEndPoint}", getAuthenticateEndPoint());
|
||||
HttpRequest post = HttpUtil.createPost(fullAuthenticateUrl);
|
||||
|
||||
post.body(param, "application/x-www-form-urlencoded");
|
||||
HttpResponse response = post.execute();
|
||||
return JSONObject.parseObject(response.body(), OneDriveToken.class);
|
||||
}
|
||||
public abstract class AbstractOneDriveServiceBase extends MicrosoftDriveServiceBase {
|
||||
|
||||
@Override
|
||||
public List<FileItemDTO> fileList(String path) {
|
||||
path = StringUtils.removeFirstSeparator(path);
|
||||
String fullPath = StringUtils.getFullPath(basePath, path);
|
||||
|
||||
List<FileItemDTO> result = new ArrayList<>();
|
||||
String nextLink = null;
|
||||
|
||||
do {
|
||||
|
||||
String requestUrl;
|
||||
|
||||
if (nextLink != null) {
|
||||
nextLink = nextLink.replace("+", "%2B");
|
||||
requestUrl = URLUtil.decode(nextLink);
|
||||
}else if (ZFileConstant.PATH_SEPARATOR.equalsIgnoreCase(fullPath) || "".equalsIgnoreCase(fullPath)) {
|
||||
requestUrl = DRIVER_ROOT_URL;
|
||||
} else {
|
||||
requestUrl = DRIVER_ITEMS_URL;
|
||||
}
|
||||
fullPath = StringUtils.removeLastSeparator(fullPath);
|
||||
|
||||
JSONObject root;
|
||||
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.set("driveId", driveId.toString());
|
||||
HttpEntity<Object> entity = new HttpEntity<>(headers);
|
||||
|
||||
try {
|
||||
root = oneDriveRestTemplate.exchange(requestUrl, HttpMethod.GET, entity, JSONObject.class, getGraphEndPoint(), fullPath).getBody();
|
||||
} catch (HttpClientErrorException e) {
|
||||
log.debug("调用 OneDrive 时出现了网络异常: {} , 已尝试重新刷新 token 后再试.", e.getMessage());
|
||||
refreshOneDriveToken();
|
||||
root = oneDriveRestTemplate.exchange(requestUrl, HttpMethod.GET, entity, JSONObject.class, getGraphEndPoint(), fullPath).getBody();
|
||||
}
|
||||
|
||||
if (root == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
nextLink = root.getString("@odata.nextLink");
|
||||
|
||||
JSONArray fileList = root.getJSONArray("value");
|
||||
|
||||
for (int i = 0; i < fileList.size(); i++) {
|
||||
|
||||
FileItemDTO fileItemDTO = new FileItemDTO();
|
||||
JSONObject fileItem = fileList.getJSONObject(i);
|
||||
fileItemDTO.setName(fileItem.getString("name"));
|
||||
fileItemDTO.setSize(fileItem.getLong("size"));
|
||||
fileItemDTO.setTime(fileItem.getDate("lastModifiedDateTime"));
|
||||
|
||||
if (fileItem.containsKey("file")) {
|
||||
fileItemDTO.setUrl(fileItem.getString("@microsoft.graph.downloadUrl"));
|
||||
fileItemDTO.setType(FileTypeEnum.FILE);
|
||||
} else {
|
||||
fileItemDTO.setType(FileTypeEnum.FOLDER);
|
||||
}
|
||||
|
||||
fileItemDTO.setPath(path);
|
||||
result.add(fileItemDTO);
|
||||
}
|
||||
} while (nextLink != null);
|
||||
|
||||
return result;
|
||||
public String getType() {
|
||||
return "me";
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public FileItemDTO getFileItem(String path) {
|
||||
|
||||
String fullPath = StringUtils.getFullPath(basePath, path);
|
||||
|
||||
String requestUrl;
|
||||
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.set("driveId", driveId.toString());
|
||||
HttpEntity<Object> entity = new HttpEntity<>(headers);
|
||||
|
||||
JSONObject fileItem = oneDriveRestTemplate.exchange(DRIVER_ITEM_URL, HttpMethod.GET, entity, JSONObject.class, getGraphEndPoint(), fullPath).getBody();
|
||||
|
||||
if (fileItem == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
FileItemDTO fileItemDTO = new FileItemDTO();
|
||||
fileItemDTO.setName(fileItem.getString("name"));
|
||||
fileItemDTO.setSize(fileItem.getLong("size"));
|
||||
fileItemDTO.setTime(fileItem.getDate("lastModifiedDateTime"));
|
||||
|
||||
if (fileItem.containsKey(ONE_DRIVE_FILE_FLAG)) {
|
||||
fileItemDTO.setUrl(fileItem.getString("@microsoft.graph.downloadUrl"));
|
||||
fileItemDTO.setType(FileTypeEnum.FILE);
|
||||
} else {
|
||||
fileItemDTO.setType(FileTypeEnum.FOLDER);
|
||||
}
|
||||
|
||||
fileItemDTO.setPath(path);
|
||||
return fileItemDTO;
|
||||
}
|
||||
|
||||
|
||||
public abstract String getGraphEndPoint();
|
||||
|
||||
public abstract String getAuthenticateEndPoint();
|
||||
|
||||
public abstract String getClientId();
|
||||
|
||||
public abstract String getRedirectUri();
|
||||
|
||||
public abstract String getClientSecret();
|
||||
|
||||
public abstract String getScope();
|
||||
|
||||
public void refreshOneDriveToken() {
|
||||
OneDriveToken refreshToken = getRefreshToken();
|
||||
|
||||
if (refreshToken.getAccessToken() == null || refreshToken.getRefreshToken() == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
StorageConfig accessTokenConfig =
|
||||
storageConfigService.findByDriveIdAndKey(driveId, StorageConfigConstant.ACCESS_TOKEN_KEY);
|
||||
StorageConfig refreshTokenConfig =
|
||||
storageConfigService.findByDriveIdAndKey(driveId, StorageConfigConstant.REFRESH_TOKEN_KEY);
|
||||
accessTokenConfig.setValue(refreshToken.getAccessToken());
|
||||
refreshTokenConfig.setValue(refreshToken.getRefreshToken());
|
||||
|
||||
storageConfigService.updateStorageConfig(Arrays.asList(accessTokenConfig, refreshTokenConfig));
|
||||
public String getDownloadUrl(String path) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -243,5 +31,4 @@ public abstract class AbstractOneDriveServiceBase extends AbstractBaseFileServic
|
||||
add(new StorageConfig("basePath", "基路径"));
|
||||
}};
|
||||
}
|
||||
|
||||
}
|
||||
@@ -7,6 +7,7 @@ import com.amazonaws.services.s3.model.ListObjectsRequest;
|
||||
import com.amazonaws.services.s3.model.ObjectListing;
|
||||
import com.amazonaws.services.s3.model.S3ObjectSummary;
|
||||
import im.zhaojun.zfile.exception.NotExistFileException;
|
||||
import im.zhaojun.zfile.model.constant.ZFileConstant;
|
||||
import im.zhaojun.zfile.model.dto.FileItemDTO;
|
||||
import im.zhaojun.zfile.model.enums.FileTypeEnum;
|
||||
import im.zhaojun.zfile.service.StorageConfigService;
|
||||
@@ -43,12 +44,14 @@ public abstract class AbstractS3BaseFileService extends AbstractBaseFileService
|
||||
return s3FileList(path);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getDownloadUrl(String path) {
|
||||
this.path = path;
|
||||
return s3ObjectUrl(path);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取 S3 指定目录下的对象列表
|
||||
* @param path 路径
|
||||
@@ -88,13 +91,14 @@ public abstract class AbstractS3BaseFileService extends AbstractBaseFileService
|
||||
return fileItemList;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取对象的访问链接, 如果指定了域名, 则替换为自定义域名.
|
||||
* @return S3 对象访问地址
|
||||
*/
|
||||
public String s3ObjectUrl(String path) {
|
||||
basePath = basePath == null ? "" : basePath;
|
||||
String fullPath = StringUtils.removeFirstSeparator(StringUtils.removeDuplicateSeparator(basePath + "/" + path));
|
||||
String fullPath = StringUtils.removeFirstSeparator(StringUtils.removeDuplicateSeparator(basePath + ZFileConstant.PATH_SEPARATOR + path));
|
||||
|
||||
// 如果不是私有空间, 且指定了加速域名, 则直接返回下载地址.
|
||||
if (BooleanUtil.isFalse(isPrivate) && StringUtils.isNotNullOrEmpty(domain)) {
|
||||
@@ -111,6 +115,7 @@ public abstract class AbstractS3BaseFileService extends AbstractBaseFileService
|
||||
return URLUtil.decode(defaultUrl);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public FileItemDTO getFileItem(String path) {
|
||||
List<FileItemDTO> list;
|
||||
@@ -130,4 +135,5 @@ public abstract class AbstractS3BaseFileService extends AbstractBaseFileService
|
||||
|
||||
throw new NotExistFileException();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package im.zhaojun.zfile.service.base;
|
||||
|
||||
import im.zhaojun.zfile.model.entity.StorageConfig;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public abstract class AbstractSharePointServiceBase extends MicrosoftDriveServiceBase {
|
||||
|
||||
protected String siteId;
|
||||
|
||||
@Override
|
||||
public String getType() {
|
||||
return "sites/" + siteId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDownloadUrl(String path) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<StorageConfig> storageStrategyConfigList() {
|
||||
return new ArrayList<StorageConfig>() {{
|
||||
add(new StorageConfig("accessToken", "访问令牌"));
|
||||
add(new StorageConfig("refreshToken", "刷新令牌"));
|
||||
add(new StorageConfig("basePath", "基路径"));
|
||||
add(new StorageConfig("siteName", "站点名称"));
|
||||
add(new StorageConfig("siteId", "SiteId"));
|
||||
add(new StorageConfig("siteType", "siteType"));
|
||||
}};
|
||||
}
|
||||
}
|
||||
@@ -17,6 +17,7 @@ public interface BaseFileService {
|
||||
*/
|
||||
List<FileItemDTO> fileList(String path) throws Exception;
|
||||
|
||||
|
||||
/**
|
||||
* 获取文件下载地址
|
||||
* @param path 文件路径
|
||||
@@ -24,4 +25,4 @@ public interface BaseFileService {
|
||||
*/
|
||||
String getDownloadUrl(String path);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,261 @@
|
||||
package im.zhaojun.zfile.service.base;
|
||||
|
||||
import cn.hutool.core.util.URLUtil;
|
||||
import cn.hutool.http.HttpRequest;
|
||||
import cn.hutool.http.HttpResponse;
|
||||
import cn.hutool.http.HttpUtil;
|
||||
import com.alibaba.fastjson.JSONArray;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import im.zhaojun.zfile.model.constant.StorageConfigConstant;
|
||||
import im.zhaojun.zfile.model.constant.ZFileConstant;
|
||||
import im.zhaojun.zfile.model.dto.FileItemDTO;
|
||||
import im.zhaojun.zfile.model.entity.StorageConfig;
|
||||
import im.zhaojun.zfile.model.enums.FileTypeEnum;
|
||||
import im.zhaojun.zfile.model.support.OneDriveToken;
|
||||
import im.zhaojun.zfile.repository.StorageConfigRepository;
|
||||
import im.zhaojun.zfile.service.StorageConfigService;
|
||||
import im.zhaojun.zfile.util.StringUtils;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.http.HttpEntity;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.web.client.HttpClientErrorException;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
@Slf4j
|
||||
public abstract class MicrosoftDriveServiceBase extends AbstractBaseFileService {
|
||||
|
||||
protected static final String DRIVER_ROOT_URL = "https://{graphEndPoint}/v1.0/{type}/drive/root/children";
|
||||
|
||||
protected static final String DRIVER_ITEMS_URL = "https://{graphEndPoint}/v1.0/{type}/drive/root:{path}:/children";
|
||||
|
||||
protected static final String DRIVER_ITEM_URL = "https://{graphEndPoint}/v1.0/{type}/drive/root:{path}";
|
||||
|
||||
protected static final String AUTHENTICATE_URL = "https://{authenticateEndPoint}/common/oauth2/v2.0/token";
|
||||
|
||||
private static final String ONE_DRIVE_FILE_FLAG = "file";
|
||||
|
||||
@Resource
|
||||
@Lazy
|
||||
private RestTemplate oneDriveRestTemplate;
|
||||
|
||||
@Resource
|
||||
private StorageConfigRepository storageConfigRepository;
|
||||
|
||||
@Resource
|
||||
private StorageConfigService storageConfigService;
|
||||
|
||||
/**
|
||||
* 根据 RefreshToken 刷新 AccessToken, 返回刷新后的 Token.
|
||||
*
|
||||
* @return 刷新后的 Token
|
||||
*/
|
||||
public OneDriveToken getRefreshToken() {
|
||||
StorageConfig refreshStorageConfig =
|
||||
storageConfigRepository.findByDriveIdAndKey(driveId, StorageConfigConstant.REFRESH_TOKEN_KEY);
|
||||
|
||||
String param = "client_id=" + getClientId() +
|
||||
"&redirect_uri=" + getRedirectUri() +
|
||||
"&client_secret=" + getClientSecret() +
|
||||
"&refresh_token=" + refreshStorageConfig.getValue() +
|
||||
"&grant_type=refresh_token";
|
||||
|
||||
String fullAuthenticateUrl = AUTHENTICATE_URL.replace("{authenticateEndPoint}", getAuthenticateEndPoint());
|
||||
HttpRequest post = HttpUtil.createPost(fullAuthenticateUrl);
|
||||
|
||||
post.body(param, "application/x-www-form-urlencoded");
|
||||
HttpResponse response = post.execute();
|
||||
return JSONObject.parseObject(response.body(), OneDriveToken.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* OAuth2 协议中, 根据 code 换取 access_token 和 refresh_token.
|
||||
*
|
||||
* @param code
|
||||
* 代码
|
||||
*
|
||||
* @return 获取的 Token 信息.
|
||||
*/
|
||||
public OneDriveToken getToken(String code) {
|
||||
String param = "client_id=" + getClientId() +
|
||||
"&redirect_uri=" + getRedirectUri() +
|
||||
"&client_secret=" + getClientSecret() +
|
||||
"&code=" + code +
|
||||
"&scope=" + getScope() +
|
||||
"&grant_type=authorization_code";
|
||||
|
||||
String fullAuthenticateUrl = AUTHENTICATE_URL.replace("{authenticateEndPoint}", getAuthenticateEndPoint());
|
||||
HttpRequest post = HttpUtil.createPost(fullAuthenticateUrl);
|
||||
|
||||
post.body(param, "application/x-www-form-urlencoded");
|
||||
HttpResponse response = post.execute();
|
||||
return JSONObject.parseObject(response.body(), OneDriveToken.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<FileItemDTO> fileList(String path) {
|
||||
path = StringUtils.removeFirstSeparator(path);
|
||||
String fullPath = StringUtils.getFullPath(basePath, path);
|
||||
|
||||
List<FileItemDTO> result = new ArrayList<>();
|
||||
String nextLink = null;
|
||||
|
||||
do {
|
||||
|
||||
String requestUrl;
|
||||
|
||||
if (nextLink != null) {
|
||||
nextLink = nextLink.replace("+", "%2B");
|
||||
requestUrl = URLUtil.decode(nextLink);
|
||||
}else if (ZFileConstant.PATH_SEPARATOR.equalsIgnoreCase(fullPath) || "".equalsIgnoreCase(fullPath)) {
|
||||
requestUrl = DRIVER_ROOT_URL;
|
||||
} else {
|
||||
requestUrl = DRIVER_ITEMS_URL;
|
||||
}
|
||||
fullPath = StringUtils.removeLastSeparator(fullPath);
|
||||
|
||||
JSONObject root;
|
||||
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.set("driveId", driveId.toString());
|
||||
HttpEntity<Object> entity = new HttpEntity<>(headers);
|
||||
|
||||
try {
|
||||
root = oneDriveRestTemplate.exchange(requestUrl, HttpMethod.GET, entity, JSONObject.class, getGraphEndPoint(), getType(), fullPath).getBody();
|
||||
} catch (HttpClientErrorException e) {
|
||||
log.debug("调用 OneDrive 时出现了网络异常, 已尝试重新刷新 token 后再试.", e);
|
||||
refreshOneDriveToken();
|
||||
root = oneDriveRestTemplate.exchange(requestUrl, HttpMethod.GET, entity, JSONObject.class, getGraphEndPoint(), getType(), fullPath).getBody();
|
||||
}
|
||||
|
||||
if (root == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
nextLink = root.getString("@odata.nextLink");
|
||||
|
||||
JSONArray fileList = root.getJSONArray("value");
|
||||
|
||||
for (int i = 0; i < fileList.size(); i++) {
|
||||
|
||||
FileItemDTO fileItemDTO = new FileItemDTO();
|
||||
JSONObject fileItem = fileList.getJSONObject(i);
|
||||
fileItemDTO.setName(fileItem.getString("name"));
|
||||
fileItemDTO.setSize(fileItem.getLong("size"));
|
||||
fileItemDTO.setTime(fileItem.getDate("lastModifiedDateTime"));
|
||||
|
||||
if (fileItem.containsKey("file")) {
|
||||
fileItemDTO.setUrl(fileItem.getString("@microsoft.graph.downloadUrl"));
|
||||
fileItemDTO.setType(FileTypeEnum.FILE);
|
||||
} else {
|
||||
fileItemDTO.setType(FileTypeEnum.FOLDER);
|
||||
}
|
||||
|
||||
fileItemDTO.setPath(path);
|
||||
result.add(fileItemDTO);
|
||||
}
|
||||
} while (nextLink != null);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FileItemDTO getFileItem(String path) {
|
||||
|
||||
String fullPath = StringUtils.getFullPath(basePath, path);
|
||||
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.set("driveId", driveId.toString());
|
||||
HttpEntity<Object> entity = new HttpEntity<>(headers);
|
||||
|
||||
JSONObject fileItem = oneDriveRestTemplate.exchange(DRIVER_ITEM_URL, HttpMethod.GET, entity, JSONObject.class, getGraphEndPoint(), getType(), fullPath).getBody();
|
||||
|
||||
if (fileItem == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
FileItemDTO fileItemDTO = new FileItemDTO();
|
||||
fileItemDTO.setName(fileItem.getString("name"));
|
||||
fileItemDTO.setSize(fileItem.getLong("size"));
|
||||
fileItemDTO.setTime(fileItem.getDate("lastModifiedDateTime"));
|
||||
|
||||
if (fileItem.containsKey(ONE_DRIVE_FILE_FLAG)) {
|
||||
fileItemDTO.setUrl(fileItem.getString("@microsoft.graph.downloadUrl"));
|
||||
fileItemDTO.setType(FileTypeEnum.FILE);
|
||||
} else {
|
||||
fileItemDTO.setType(FileTypeEnum.FOLDER);
|
||||
}
|
||||
|
||||
fileItemDTO.setPath(path);
|
||||
return fileItemDTO;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取存储类型, 对于 OneDrive 或 SharePoint, 此地址会不同.
|
||||
* @return Graph 连接点
|
||||
*/
|
||||
public abstract String getType();
|
||||
|
||||
/**
|
||||
* 获取 GraphEndPoint, 对于不同版本的 OneDrive, 此地址会不同.
|
||||
* @return Graph 连接点
|
||||
*/
|
||||
public abstract String getGraphEndPoint();
|
||||
|
||||
|
||||
/**
|
||||
* 获取 AuthenticateEndPoint, 对于不同版本的 OneDrive, 此地址会不同.
|
||||
* @return Authenticate 连接点
|
||||
*/
|
||||
public abstract String getAuthenticateEndPoint();
|
||||
|
||||
/**
|
||||
* 获取 Client ID.
|
||||
* @return Client Id
|
||||
*/
|
||||
public abstract String getClientId();
|
||||
|
||||
/**
|
||||
* 获取重定向地址.
|
||||
* @return 重定向地址
|
||||
*/
|
||||
public abstract String getRedirectUri();
|
||||
|
||||
/**
|
||||
* 获取 Client Secret 密钥.
|
||||
* @return Client Secret 密钥.
|
||||
*/
|
||||
public abstract String getClientSecret();
|
||||
|
||||
/**
|
||||
* 获取 API Scope.
|
||||
* @return Scope
|
||||
*/
|
||||
public abstract String getScope();
|
||||
|
||||
public void refreshOneDriveToken() {
|
||||
OneDriveToken refreshToken = getRefreshToken();
|
||||
|
||||
if (refreshToken.getAccessToken() == null || refreshToken.getRefreshToken() == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
StorageConfig accessTokenConfig =
|
||||
storageConfigService.findByDriveIdAndKey(driveId, StorageConfigConstant.ACCESS_TOKEN_KEY);
|
||||
StorageConfig refreshTokenConfig =
|
||||
storageConfigService.findByDriveIdAndKey(driveId, StorageConfigConstant.REFRESH_TOKEN_KEY);
|
||||
accessTokenConfig.setValue(refreshToken.getAccessToken());
|
||||
refreshTokenConfig.setValue(refreshToken.getRefreshToken());
|
||||
|
||||
storageConfigService.updateStorageConfig(Arrays.asList(accessTokenConfig, refreshTokenConfig));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -32,32 +32,29 @@ public class AliyunServiceImpl extends AbstractS3BaseFileService implements Base
|
||||
|
||||
@Override
|
||||
public void init(Integer driveId) {
|
||||
try {
|
||||
this.driveId = driveId;
|
||||
Map<String, StorageConfig> stringStorageConfigMap =
|
||||
storageConfigService.selectStorageConfigMapByDriveId(driveId);
|
||||
String accessKey = stringStorageConfigMap.get(StorageConfigConstant.ACCESS_KEY).getValue();
|
||||
String secretKey = stringStorageConfigMap.get(StorageConfigConstant.SECRET_KEY).getValue();
|
||||
String endPoint = stringStorageConfigMap.get(StorageConfigConstant.ENDPOINT_KEY).getValue();
|
||||
this.driveId = driveId;
|
||||
Map<String, StorageConfig> stringStorageConfigMap =
|
||||
storageConfigService.selectStorageConfigMapByDriveId(driveId);
|
||||
String accessKey = stringStorageConfigMap.get(StorageConfigConstant.ACCESS_KEY).getValue();
|
||||
String secretKey = stringStorageConfigMap.get(StorageConfigConstant.SECRET_KEY).getValue();
|
||||
String endPoint = stringStorageConfigMap.get(StorageConfigConstant.ENDPOINT_KEY).getValue();
|
||||
|
||||
super.domain = stringStorageConfigMap.get(StorageConfigConstant.DOMAIN_KEY).getValue();
|
||||
super.basePath = stringStorageConfigMap.get(StorageConfigConstant.BASE_PATH).getValue();
|
||||
super.bucketName = stringStorageConfigMap.get(StorageConfigConstant.BUCKET_NAME_KEY).getValue();
|
||||
super.isPrivate = Convert.toBool(stringStorageConfigMap.get(StorageConfigConstant.IS_PRIVATE).getValue(), true);
|
||||
super.domain = stringStorageConfigMap.get(StorageConfigConstant.DOMAIN_KEY).getValue();
|
||||
super.basePath = stringStorageConfigMap.get(StorageConfigConstant.BASE_PATH).getValue();
|
||||
super.bucketName = stringStorageConfigMap.get(StorageConfigConstant.BUCKET_NAME_KEY).getValue();
|
||||
super.isPrivate = Convert.toBool(stringStorageConfigMap.get(StorageConfigConstant.IS_PRIVATE).getValue(), true);
|
||||
|
||||
if (Objects.isNull(accessKey) || Objects.isNull(secretKey) || Objects.isNull(endPoint) || Objects.isNull(bucketName)) {
|
||||
log.debug("初始化存储策略 [{}] 失败: 参数不完整", getStorageTypeEnum().getDescription());
|
||||
isInitialized = false;
|
||||
} else {
|
||||
BasicAWSCredentials credentials = new BasicAWSCredentials(accessKey, secretKey);
|
||||
if (Objects.isNull(accessKey) || Objects.isNull(secretKey) || Objects.isNull(endPoint) || Objects.isNull(bucketName)) {
|
||||
log.debug("初始化存储策略 [{}] 失败: 参数不完整", getStorageTypeEnum().getDescription());
|
||||
isInitialized = false;
|
||||
} else {
|
||||
BasicAWSCredentials credentials = new BasicAWSCredentials(accessKey, secretKey);
|
||||
|
||||
super.s3Client = AmazonS3ClientBuilder.standard()
|
||||
.withCredentials(new AWSStaticCredentialsProvider(credentials))
|
||||
.withEndpointConfiguration(new AwsClientBuilder.EndpointConfiguration(endPoint, "oss")).build();
|
||||
isInitialized = testConnection();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.debug(getStorageTypeEnum().getDescription() + " 初始化异常, 已跳过", e);
|
||||
super.s3Client = AmazonS3ClientBuilder.standard()
|
||||
.withCredentials(new AWSStaticCredentialsProvider(credentials))
|
||||
.withEndpointConfiguration(new AwsClientBuilder.EndpointConfiguration(endPoint, "oss")).build();
|
||||
testConnection();
|
||||
isInitialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -11,16 +11,16 @@ import im.zhaojun.zfile.service.StorageConfigService;
|
||||
import im.zhaojun.zfile.service.base.AbstractBaseFileService;
|
||||
import im.zhaojun.zfile.service.base.BaseFileService;
|
||||
import im.zhaojun.zfile.util.StringUtils;
|
||||
import lombok.SneakyThrows;
|
||||
import org.apache.commons.net.ftp.FTP;
|
||||
import org.apache.commons.net.ftp.FTPClientConfig;
|
||||
import org.apache.commons.net.ftp.FTPFile;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
|
||||
import org.springframework.context.annotation.Scope;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -34,8 +34,6 @@ import java.util.Objects;
|
||||
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
|
||||
public class FtpServiceImpl extends AbstractBaseFileService implements BaseFileService {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(FtpServiceImpl.class);
|
||||
|
||||
@Resource
|
||||
private StorageConfigService storageConfigService;
|
||||
|
||||
@@ -51,28 +49,26 @@ public class FtpServiceImpl extends AbstractBaseFileService implements BaseFileS
|
||||
|
||||
private String password;
|
||||
|
||||
@SneakyThrows(IOException.class)
|
||||
@Override
|
||||
public void init(Integer driveId) {
|
||||
try {
|
||||
this.driveId = driveId;
|
||||
Map<String, StorageConfig> stringStorageConfigMap =
|
||||
storageConfigService.selectStorageConfigMapByDriveId(driveId);
|
||||
host = stringStorageConfigMap.get(StorageConfigConstant.HOST_KEY).getValue();
|
||||
port = stringStorageConfigMap.get(StorageConfigConstant.PORT_KEY).getValue();
|
||||
username = stringStorageConfigMap.get(StorageConfigConstant.USERNAME_KEY).getValue();
|
||||
password = stringStorageConfigMap.get(StorageConfigConstant.PASSWORD_KEY).getValue();
|
||||
domain = stringStorageConfigMap.get(StorageConfigConstant.DOMAIN_KEY).getValue();
|
||||
super.basePath = stringStorageConfigMap.get(StorageConfigConstant.BASE_PATH).getValue();
|
||||
if (Objects.isNull(host) || Objects.isNull(port) || Objects.isNull(username) || Objects.isNull(password)) {
|
||||
isInitialized = false;
|
||||
} else {
|
||||
ftp = new Ftp(host, Integer.parseInt(port), username, password, StandardCharsets.UTF_8);
|
||||
ftp.getClient().configure(new FTPClientConfig(FTPClientConfig.SYST_UNIX));
|
||||
ftp.getClient().type(FTP.BINARY_FILE_TYPE);
|
||||
isInitialized = testConnection();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.debug(getStorageTypeEnum().getDescription() + " 初始化异常, 已跳过");
|
||||
this.driveId = driveId;
|
||||
Map<String, StorageConfig> stringStorageConfigMap =
|
||||
storageConfigService.selectStorageConfigMapByDriveId(driveId);
|
||||
host = stringStorageConfigMap.get(StorageConfigConstant.HOST_KEY).getValue();
|
||||
port = stringStorageConfigMap.get(StorageConfigConstant.PORT_KEY).getValue();
|
||||
username = stringStorageConfigMap.get(StorageConfigConstant.USERNAME_KEY).getValue();
|
||||
password = stringStorageConfigMap.get(StorageConfigConstant.PASSWORD_KEY).getValue();
|
||||
domain = stringStorageConfigMap.get(StorageConfigConstant.DOMAIN_KEY).getValue();
|
||||
super.basePath = stringStorageConfigMap.get(StorageConfigConstant.BASE_PATH).getValue();
|
||||
if (Objects.isNull(host) || Objects.isNull(port)) {
|
||||
isInitialized = false;
|
||||
} else {
|
||||
ftp = new Ftp(host, Integer.parseInt(port), username, password, StandardCharsets.UTF_8);
|
||||
ftp.getClient().configure(new FTPClientConfig(FTPClientConfig.SYST_UNIX));
|
||||
ftp.getClient().type(FTP.BINARY_FILE_TYPE);
|
||||
testConnection();
|
||||
isInitialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -145,4 +141,5 @@ public class FtpServiceImpl extends AbstractBaseFileService implements BaseFileS
|
||||
add(new StorageConfig("basePath", "基路径"));
|
||||
}};
|
||||
}
|
||||
|
||||
}
|
||||
@@ -32,32 +32,29 @@ public class HuaweiServiceImpl extends AbstractS3BaseFileService implements Base
|
||||
|
||||
@Override
|
||||
public void init(Integer driveId) {
|
||||
try {
|
||||
this.driveId = driveId;
|
||||
Map<String, StorageConfig> stringStorageConfigMap =
|
||||
storageConfigService.selectStorageConfigMapByDriveId(driveId);
|
||||
String accessKey = stringStorageConfigMap.get(StorageConfigConstant.ACCESS_KEY).getValue();
|
||||
String secretKey = stringStorageConfigMap.get(StorageConfigConstant.SECRET_KEY).getValue();
|
||||
String endPoint = stringStorageConfigMap.get(StorageConfigConstant.ENDPOINT_KEY).getValue();
|
||||
this.driveId = driveId;
|
||||
Map<String, StorageConfig> stringStorageConfigMap =
|
||||
storageConfigService.selectStorageConfigMapByDriveId(driveId);
|
||||
String accessKey = stringStorageConfigMap.get(StorageConfigConstant.ACCESS_KEY).getValue();
|
||||
String secretKey = stringStorageConfigMap.get(StorageConfigConstant.SECRET_KEY).getValue();
|
||||
String endPoint = stringStorageConfigMap.get(StorageConfigConstant.ENDPOINT_KEY).getValue();
|
||||
|
||||
bucketName = stringStorageConfigMap.get(StorageConfigConstant.BUCKET_NAME_KEY).getValue();
|
||||
domain = stringStorageConfigMap.get(StorageConfigConstant.DOMAIN_KEY).getValue();
|
||||
basePath = stringStorageConfigMap.get(StorageConfigConstant.BASE_PATH).getValue();
|
||||
isPrivate = Convert.toBool(stringStorageConfigMap.get(StorageConfigConstant.IS_PRIVATE).getValue(), true);
|
||||
bucketName = stringStorageConfigMap.get(StorageConfigConstant.BUCKET_NAME_KEY).getValue();
|
||||
domain = stringStorageConfigMap.get(StorageConfigConstant.DOMAIN_KEY).getValue();
|
||||
basePath = stringStorageConfigMap.get(StorageConfigConstant.BASE_PATH).getValue();
|
||||
isPrivate = Convert.toBool(stringStorageConfigMap.get(StorageConfigConstant.IS_PRIVATE).getValue(), true);
|
||||
|
||||
if (Objects.isNull(accessKey) || Objects.isNull(secretKey) || Objects.isNull(endPoint) || Objects.isNull(bucketName)) {
|
||||
log.debug("初始化存储策略 [{}] 失败: 参数不完整", getStorageTypeEnum().getDescription());
|
||||
isInitialized = false;
|
||||
} else {
|
||||
BasicAWSCredentials credentials = new BasicAWSCredentials(accessKey, secretKey);
|
||||
s3Client = AmazonS3ClientBuilder.standard()
|
||||
.withCredentials(new AWSStaticCredentialsProvider(credentials))
|
||||
.withEndpointConfiguration(new AwsClientBuilder.EndpointConfiguration(endPoint, "obs")).build();
|
||||
if (Objects.isNull(accessKey) || Objects.isNull(secretKey) || Objects.isNull(endPoint) || Objects.isNull(bucketName)) {
|
||||
log.debug("初始化存储策略 [{}] 失败: 参数不完整", getStorageTypeEnum().getDescription());
|
||||
isInitialized = false;
|
||||
} else {
|
||||
BasicAWSCredentials credentials = new BasicAWSCredentials(accessKey, secretKey);
|
||||
s3Client = AmazonS3ClientBuilder.standard()
|
||||
.withCredentials(new AWSStaticCredentialsProvider(credentials))
|
||||
.withEndpointConfiguration(new AwsClientBuilder.EndpointConfiguration(endPoint, "obs")).build();
|
||||
|
||||
isInitialized = testConnection();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.debug(getStorageTypeEnum().getDescription() + " 初始化异常, 已跳过");
|
||||
testConnection();
|
||||
isInitialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -79,5 +76,4 @@ public class HuaweiServiceImpl extends AbstractS3BaseFileService implements Base
|
||||
}};
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,8 +1,10 @@
|
||||
package im.zhaojun.zfile.service.impl;
|
||||
|
||||
import im.zhaojun.zfile.exception.InitializeDriveException;
|
||||
import im.zhaojun.zfile.exception.NotExistFileException;
|
||||
import im.zhaojun.zfile.model.constant.StorageConfigConstant;
|
||||
import im.zhaojun.zfile.model.constant.SystemConfigConstant;
|
||||
import im.zhaojun.zfile.model.constant.ZFileConstant;
|
||||
import im.zhaojun.zfile.model.dto.FileItemDTO;
|
||||
import im.zhaojun.zfile.model.entity.StorageConfig;
|
||||
import im.zhaojun.zfile.model.entity.SystemConfig;
|
||||
@@ -47,27 +49,31 @@ public class LocalServiceImpl extends AbstractBaseFileService implements BaseFil
|
||||
|
||||
@Override
|
||||
public void init(Integer driveId) {
|
||||
try {
|
||||
this.driveId = driveId;
|
||||
Map<String, StorageConfig> stringStorageConfigMap =
|
||||
storageConfigService.selectStorageConfigMapByDriveId(driveId);
|
||||
filePath = stringStorageConfigMap.get(StorageConfigConstant.FILE_PATH_KEY).getValue();
|
||||
if (Objects.isNull(filePath)) {
|
||||
log.debug("初始化存储策略 [{}] 失败: 参数不完整", getStorageTypeEnum().getDescription());
|
||||
isInitialized = false;
|
||||
} else {
|
||||
isInitialized = testConnection();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.debug(getStorageTypeEnum().getDescription() + " 初始化异常, 已跳过");
|
||||
this.driveId = driveId;
|
||||
Map<String, StorageConfig> stringStorageConfigMap =
|
||||
storageConfigService.selectStorageConfigMapByDriveId(driveId);
|
||||
filePath = stringStorageConfigMap.get(StorageConfigConstant.FILE_PATH_KEY).getValue();
|
||||
if (Objects.isNull(filePath)) {
|
||||
log.debug("初始化存储策略 [{}] 失败: 参数不完整", getStorageTypeEnum().getDescription());
|
||||
isInitialized = false;
|
||||
return;
|
||||
}
|
||||
|
||||
File file = new File(filePath);
|
||||
if (!file.exists()) {
|
||||
throw new InitializeDriveException("文件路径: \"" + file.getAbsolutePath() + "\"不存在, 请检查是否填写正确.");
|
||||
} else {
|
||||
testConnection();
|
||||
isInitialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public List<FileItemDTO> fileList(String path) throws FileNotFoundException {
|
||||
List<FileItemDTO> fileItemList = new ArrayList<>();
|
||||
|
||||
String fullPath = StringUtils.concatPath(filePath, path);
|
||||
String fullPath = StringUtils.removeDuplicateSeparator(filePath + path);
|
||||
|
||||
File file = new File(fullPath);
|
||||
|
||||
@@ -99,7 +105,7 @@ public class LocalServiceImpl extends AbstractBaseFileService implements BaseFil
|
||||
@Override
|
||||
public String getDownloadUrl(String path) {
|
||||
SystemConfig usernameConfig = systemConfigRepository.findByKey(SystemConfigConstant.DOMAIN);
|
||||
return StringUtils.removeDuplicateSeparator(usernameConfig.getValue() + "/file/" + driveId + "/" + path);
|
||||
return StringUtils.removeDuplicateSeparator(usernameConfig.getValue() + "/file/" + driveId + ZFileConstant.PATH_SEPARATOR + path);
|
||||
}
|
||||
|
||||
public String getFilePath() {
|
||||
@@ -117,7 +123,7 @@ public class LocalServiceImpl extends AbstractBaseFileService implements BaseFil
|
||||
|
||||
@Override
|
||||
public FileItemDTO getFileItem(String path) {
|
||||
String fullPath = StringUtils.concatPath(filePath, path);
|
||||
String fullPath = filePath + path;
|
||||
|
||||
File file = new File(fullPath);
|
||||
|
||||
@@ -144,4 +150,5 @@ public class LocalServiceImpl extends AbstractBaseFileService implements BaseFil
|
||||
add(new StorageConfig("filePath", "文件路径"));
|
||||
}};
|
||||
}
|
||||
|
||||
}
|
||||
@@ -32,31 +32,28 @@ public class MinIOServiceImpl extends AbstractS3BaseFileService implements BaseF
|
||||
|
||||
@Override
|
||||
public void init(Integer driveId) {
|
||||
try {
|
||||
this.driveId = driveId;
|
||||
Map<String, StorageConfig> stringStorageConfigMap =
|
||||
storageConfigService.selectStorageConfigMapByDriveId(driveId);
|
||||
String accessKey = stringStorageConfigMap.get(StorageConfigConstant.ACCESS_KEY).getValue();
|
||||
String secretKey = stringStorageConfigMap.get(StorageConfigConstant.SECRET_KEY).getValue();
|
||||
String endPoint = stringStorageConfigMap.get(StorageConfigConstant.ENDPOINT_KEY).getValue();
|
||||
bucketName = stringStorageConfigMap.get(StorageConfigConstant.BUCKET_NAME_KEY).getValue();
|
||||
basePath = stringStorageConfigMap.get(StorageConfigConstant.BASE_PATH).getValue();
|
||||
isPrivate = Convert.toBool(stringStorageConfigMap.get(StorageConfigConstant.IS_PRIVATE).getValue(), true);
|
||||
this.driveId = driveId;
|
||||
Map<String, StorageConfig> stringStorageConfigMap =
|
||||
storageConfigService.selectStorageConfigMapByDriveId(driveId);
|
||||
String accessKey = stringStorageConfigMap.get(StorageConfigConstant.ACCESS_KEY).getValue();
|
||||
String secretKey = stringStorageConfigMap.get(StorageConfigConstant.SECRET_KEY).getValue();
|
||||
String endPoint = stringStorageConfigMap.get(StorageConfigConstant.ENDPOINT_KEY).getValue();
|
||||
bucketName = stringStorageConfigMap.get(StorageConfigConstant.BUCKET_NAME_KEY).getValue();
|
||||
basePath = stringStorageConfigMap.get(StorageConfigConstant.BASE_PATH).getValue();
|
||||
isPrivate = Convert.toBool(stringStorageConfigMap.get(StorageConfigConstant.IS_PRIVATE).getValue(), true);
|
||||
|
||||
if (Objects.isNull(accessKey) || Objects.isNull(secretKey) || Objects.isNull(endPoint) || Objects.isNull(bucketName)) {
|
||||
log.debug("初始化存储策略 [{}] 失败: 参数不完整", getStorageTypeEnum().getDescription());
|
||||
isInitialized = false;
|
||||
} else {
|
||||
BasicAWSCredentials credentials = new BasicAWSCredentials(accessKey, secretKey);
|
||||
s3Client = AmazonS3ClientBuilder.standard()
|
||||
.withPathStyleAccessEnabled(true)
|
||||
.withCredentials(new AWSStaticCredentialsProvider(credentials))
|
||||
.withEndpointConfiguration(new AwsClientBuilder.EndpointConfiguration(endPoint, "minio")).build();
|
||||
if (Objects.isNull(accessKey) || Objects.isNull(secretKey) || Objects.isNull(endPoint) || Objects.isNull(bucketName)) {
|
||||
log.debug("初始化存储策略 [{}] 失败: 参数不完整", getStorageTypeEnum().getDescription());
|
||||
isInitialized = false;
|
||||
} else {
|
||||
BasicAWSCredentials credentials = new BasicAWSCredentials(accessKey, secretKey);
|
||||
s3Client = AmazonS3ClientBuilder.standard()
|
||||
.withPathStyleAccessEnabled(true)
|
||||
.withCredentials(new AWSStaticCredentialsProvider(credentials))
|
||||
.withEndpointConfiguration(new AwsClientBuilder.EndpointConfiguration(endPoint, "minio")).build();
|
||||
|
||||
isInitialized = testConnection();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.debug(getStorageTypeEnum().getDescription() + " 初始化异常, 已跳过");
|
||||
testConnection();
|
||||
isInitialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -41,31 +41,23 @@ public class OneDriveChinaServiceImpl extends AbstractOneDriveServiceBase implem
|
||||
|
||||
@Override
|
||||
public void init(Integer driveId) {
|
||||
try {
|
||||
this.driveId = driveId;
|
||||
Map<String, StorageConfig> stringStorageConfigMap =
|
||||
storageConfigService.selectStorageConfigMapByDriveId(driveId);
|
||||
String accessToken = stringStorageConfigMap.get(StorageConfigConstant.ACCESS_TOKEN_KEY).getValue();
|
||||
String refreshToken = stringStorageConfigMap.get(StorageConfigConstant.REFRESH_TOKEN_KEY).getValue();
|
||||
super.basePath = stringStorageConfigMap.get(StorageConfigConstant.BASE_PATH).getValue();
|
||||
this.driveId = driveId;
|
||||
Map<String, StorageConfig> stringStorageConfigMap =
|
||||
storageConfigService.selectStorageConfigMapByDriveId(driveId);
|
||||
String accessToken = stringStorageConfigMap.get(StorageConfigConstant.ACCESS_TOKEN_KEY).getValue();
|
||||
String refreshToken = stringStorageConfigMap.get(StorageConfigConstant.REFRESH_TOKEN_KEY).getValue();
|
||||
super.basePath = stringStorageConfigMap.get(StorageConfigConstant.BASE_PATH).getValue();
|
||||
|
||||
if (StringUtils.isEmpty(accessToken) || StringUtils.isEmpty(refreshToken)) {
|
||||
log.debug("初始化存储策略 [{}] 失败: 参数不完整", getStorageTypeEnum().getDescription());
|
||||
isInitialized = false;
|
||||
} else {
|
||||
refreshOneDriveToken();
|
||||
isInitialized = testConnection();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.debug(getStorageTypeEnum().getDescription() + " 初始化异常, 已跳过");
|
||||
if (StringUtils.isEmpty(accessToken) || StringUtils.isEmpty(refreshToken)) {
|
||||
log.debug("初始化存储策略 [{}] 失败: 参数不完整", getStorageTypeEnum().getDescription());
|
||||
isInitialized = false;
|
||||
} else {
|
||||
refreshOneDriveToken();
|
||||
testConnection();
|
||||
isInitialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDownloadUrl(String path) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public StorageTypeEnum getStorageTypeEnum() {
|
||||
return StorageTypeEnum.ONE_DRIVE_CHINA;
|
||||
|
||||
@@ -41,31 +41,23 @@ public class OneDriveServiceImpl extends AbstractOneDriveServiceBase implements
|
||||
|
||||
@Override
|
||||
public void init(Integer driveId) {
|
||||
try {
|
||||
this.driveId = driveId;
|
||||
Map<String, StorageConfig> stringStorageConfigMap =
|
||||
storageConfigService.selectStorageConfigMapByDriveId(driveId);
|
||||
String accessToken = stringStorageConfigMap.get(StorageConfigConstant.ACCESS_TOKEN_KEY).getValue();
|
||||
String refreshToken = stringStorageConfigMap.get(StorageConfigConstant.REFRESH_TOKEN_KEY).getValue();
|
||||
super.basePath = stringStorageConfigMap.get(StorageConfigConstant.BASE_PATH).getValue();
|
||||
this.driveId = driveId;
|
||||
Map<String, StorageConfig> stringStorageConfigMap =
|
||||
storageConfigService.selectStorageConfigMapByDriveId(driveId);
|
||||
String accessToken = stringStorageConfigMap.get(StorageConfigConstant.ACCESS_TOKEN_KEY).getValue();
|
||||
String refreshToken = stringStorageConfigMap.get(StorageConfigConstant.REFRESH_TOKEN_KEY).getValue();
|
||||
super.basePath = stringStorageConfigMap.get(StorageConfigConstant.BASE_PATH).getValue();
|
||||
|
||||
if (StringUtils.isEmpty(accessToken) || StringUtils.isEmpty(refreshToken)) {
|
||||
log.debug("初始化存储策略 [{}] 失败: 参数不完整", getStorageTypeEnum().getDescription());
|
||||
isInitialized = false;
|
||||
} else {
|
||||
refreshOneDriveToken();
|
||||
isInitialized = testConnection();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.debug(getStorageTypeEnum().getDescription() + " 初始化异常, 已跳过");
|
||||
if (StringUtils.isEmpty(accessToken) || StringUtils.isEmpty(refreshToken)) {
|
||||
log.debug("初始化存储策略 [{}] 失败: 参数不完整", getStorageTypeEnum().getDescription());
|
||||
isInitialized = false;
|
||||
} else {
|
||||
refreshOneDriveToken();
|
||||
testConnection();
|
||||
isInitialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDownloadUrl(String path) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public StorageTypeEnum getStorageTypeEnum() {
|
||||
return StorageTypeEnum.ONE_DRIVE;
|
||||
@@ -100,4 +92,5 @@ public class OneDriveServiceImpl extends AbstractOneDriveServiceBase implements
|
||||
public String getScope() {
|
||||
return scope;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -32,32 +32,29 @@ public class QiniuServiceImpl extends AbstractS3BaseFileService implements BaseF
|
||||
|
||||
@Override
|
||||
public void init(Integer driveId) {
|
||||
try {
|
||||
this.driveId = driveId;
|
||||
Map<String, StorageConfig> stringStorageConfigMap =
|
||||
storageConfigService.selectStorageConfigMapByDriveId(driveId);
|
||||
String accessKey = stringStorageConfigMap.get(StorageConfigConstant.ACCESS_KEY).getValue();
|
||||
String secretKey = stringStorageConfigMap.get(StorageConfigConstant.SECRET_KEY).getValue();
|
||||
String endPoint = stringStorageConfigMap.get(StorageConfigConstant.ENDPOINT_KEY).getValue();
|
||||
this.driveId = driveId;
|
||||
Map<String, StorageConfig> stringStorageConfigMap =
|
||||
storageConfigService.selectStorageConfigMapByDriveId(driveId);
|
||||
String accessKey = stringStorageConfigMap.get(StorageConfigConstant.ACCESS_KEY).getValue();
|
||||
String secretKey = stringStorageConfigMap.get(StorageConfigConstant.SECRET_KEY).getValue();
|
||||
String endPoint = stringStorageConfigMap.get(StorageConfigConstant.ENDPOINT_KEY).getValue();
|
||||
|
||||
bucketName = stringStorageConfigMap.get(StorageConfigConstant.BUCKET_NAME_KEY).getValue();
|
||||
domain = stringStorageConfigMap.get(StorageConfigConstant.DOMAIN_KEY).getValue();
|
||||
basePath = stringStorageConfigMap.get(StorageConfigConstant.BASE_PATH).getValue();
|
||||
isPrivate = Convert.toBool(stringStorageConfigMap.get(StorageConfigConstant.IS_PRIVATE).getValue(), true);
|
||||
bucketName = stringStorageConfigMap.get(StorageConfigConstant.BUCKET_NAME_KEY).getValue();
|
||||
domain = stringStorageConfigMap.get(StorageConfigConstant.DOMAIN_KEY).getValue();
|
||||
basePath = stringStorageConfigMap.get(StorageConfigConstant.BASE_PATH).getValue();
|
||||
isPrivate = Convert.toBool(stringStorageConfigMap.get(StorageConfigConstant.IS_PRIVATE).getValue(), true);
|
||||
|
||||
if (Objects.isNull(accessKey) || Objects.isNull(secretKey) || Objects.isNull(endPoint) || Objects.isNull(bucketName)) {
|
||||
log.debug("初始化存储策略 [{}] 失败: 参数不完整", getStorageTypeEnum().getDescription());
|
||||
isInitialized = false;
|
||||
} else {
|
||||
BasicAWSCredentials credentials = new BasicAWSCredentials(accessKey, secretKey);
|
||||
s3Client = AmazonS3ClientBuilder.standard()
|
||||
.withCredentials(new AWSStaticCredentialsProvider(credentials))
|
||||
.withEndpointConfiguration(new AwsClientBuilder.EndpointConfiguration(endPoint, "kodo")).build();
|
||||
if (Objects.isNull(accessKey) || Objects.isNull(secretKey) || Objects.isNull(endPoint) || Objects.isNull(bucketName)) {
|
||||
log.debug("初始化存储策略 [{}] 失败: 参数不完整", getStorageTypeEnum().getDescription());
|
||||
isInitialized = false;
|
||||
} else {
|
||||
BasicAWSCredentials credentials = new BasicAWSCredentials(accessKey, secretKey);
|
||||
s3Client = AmazonS3ClientBuilder.standard()
|
||||
.withCredentials(new AWSStaticCredentialsProvider(credentials))
|
||||
.withEndpointConfiguration(new AwsClientBuilder.EndpointConfiguration(endPoint, "kodo")).build();
|
||||
|
||||
isInitialized = testConnection();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.debug(getStorageTypeEnum().getDescription() + " 初始化异常, 已跳过");
|
||||
testConnection();
|
||||
isInitialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -32,37 +32,34 @@ public class S3ServiceImpl extends AbstractS3BaseFileService implements BaseFile
|
||||
|
||||
@Override
|
||||
public void init(Integer driveId) {
|
||||
try {
|
||||
this.driveId = driveId;
|
||||
Map<String, StorageConfig> stringStorageConfigMap =
|
||||
storageConfigService.selectStorageConfigMapByDriveId(driveId);
|
||||
String accessKey = stringStorageConfigMap.get(StorageConfigConstant.ACCESS_KEY).getValue();
|
||||
String secretKey = stringStorageConfigMap.get(StorageConfigConstant.SECRET_KEY).getValue();
|
||||
String endPoint = stringStorageConfigMap.get(StorageConfigConstant.ENDPOINT_KEY).getValue();
|
||||
this.driveId = driveId;
|
||||
Map<String, StorageConfig> stringStorageConfigMap =
|
||||
storageConfigService.selectStorageConfigMapByDriveId(driveId);
|
||||
String accessKey = stringStorageConfigMap.get(StorageConfigConstant.ACCESS_KEY).getValue();
|
||||
String secretKey = stringStorageConfigMap.get(StorageConfigConstant.SECRET_KEY).getValue();
|
||||
String endPoint = stringStorageConfigMap.get(StorageConfigConstant.ENDPOINT_KEY).getValue();
|
||||
|
||||
super.domain = stringStorageConfigMap.get(StorageConfigConstant.DOMAIN_KEY).getValue();
|
||||
super.basePath = stringStorageConfigMap.get(StorageConfigConstant.BASE_PATH).getValue();
|
||||
super.bucketName = stringStorageConfigMap.get(StorageConfigConstant.BUCKET_NAME_KEY).getValue();
|
||||
super.isPrivate = Convert.toBool(stringStorageConfigMap.get(StorageConfigConstant.IS_PRIVATE).getValue(), true);
|
||||
super.domain = stringStorageConfigMap.get(StorageConfigConstant.DOMAIN_KEY).getValue();
|
||||
super.basePath = stringStorageConfigMap.get(StorageConfigConstant.BASE_PATH).getValue();
|
||||
super.bucketName = stringStorageConfigMap.get(StorageConfigConstant.BUCKET_NAME_KEY).getValue();
|
||||
super.isPrivate = Convert.toBool(stringStorageConfigMap.get(StorageConfigConstant.IS_PRIVATE).getValue(), true);
|
||||
|
||||
String pathStyle = stringStorageConfigMap.get(StorageConfigConstant.PATH_STYLE).getValue();
|
||||
String pathStyle = stringStorageConfigMap.get(StorageConfigConstant.PATH_STYLE).getValue();
|
||||
|
||||
boolean isPathStyle = "path-style".equals(pathStyle);
|
||||
boolean isPathStyle = "path-style".equals(pathStyle);
|
||||
|
||||
if (Objects.isNull(accessKey) || Objects.isNull(secretKey) || Objects.isNull(endPoint) || Objects.isNull(bucketName)) {
|
||||
log.debug("初始化存储策略 [{}] 失败: 参数不完整", getStorageTypeEnum().getDescription());
|
||||
isInitialized = false;
|
||||
} else {
|
||||
BasicAWSCredentials credentials = new BasicAWSCredentials(accessKey, secretKey);
|
||||
s3Client = AmazonS3ClientBuilder.standard()
|
||||
.withPathStyleAccessEnabled(isPathStyle)
|
||||
.withCredentials(new AWSStaticCredentialsProvider(credentials))
|
||||
.withEndpointConfiguration(new AwsClientBuilder.EndpointConfiguration(endPoint, "")).build();
|
||||
if (Objects.isNull(accessKey) || Objects.isNull(secretKey) || Objects.isNull(endPoint) || Objects.isNull(bucketName)) {
|
||||
log.debug("初始化存储策略 [{}] 失败: 参数不完整", getStorageTypeEnum().getDescription());
|
||||
isInitialized = false;
|
||||
} else {
|
||||
BasicAWSCredentials credentials = new BasicAWSCredentials(accessKey, secretKey);
|
||||
s3Client = AmazonS3ClientBuilder.standard()
|
||||
.withPathStyleAccessEnabled(isPathStyle)
|
||||
.withCredentials(new AWSStaticCredentialsProvider(credentials))
|
||||
.withEndpointConfiguration(new AwsClientBuilder.EndpointConfiguration(endPoint, "")).build();
|
||||
|
||||
isInitialized = testConnection();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.debug(getStorageTypeEnum().getDescription() + " 初始化异常, 已跳过");
|
||||
testConnection();
|
||||
isInitialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -84,4 +81,5 @@ public class S3ServiceImpl extends AbstractS3BaseFileService implements BaseFile
|
||||
add(new StorageConfig("isPrivate", "是否是私有空间"));
|
||||
}};
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
package im.zhaojun.zfile.service.impl;
|
||||
|
||||
import im.zhaojun.zfile.model.constant.StorageConfigConstant;
|
||||
import im.zhaojun.zfile.model.entity.StorageConfig;
|
||||
import im.zhaojun.zfile.model.enums.StorageTypeEnum;
|
||||
import im.zhaojun.zfile.service.StorageConfigService;
|
||||
import im.zhaojun.zfile.service.base.AbstractSharePointServiceBase;
|
||||
import im.zhaojun.zfile.service.base.BaseFileService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
|
||||
import org.springframework.context.annotation.Scope;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author zhaojun
|
||||
*/
|
||||
@Service
|
||||
@Slf4j
|
||||
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
|
||||
public class SharePointChinaServiceImpl extends AbstractSharePointServiceBase implements BaseFileService {
|
||||
|
||||
@Resource
|
||||
private StorageConfigService storageConfigService;
|
||||
|
||||
@Value("${zfile.onedrive-china.clientId}")
|
||||
private String clientId;
|
||||
|
||||
@Value("${zfile.onedrive-china.redirectUri}")
|
||||
private String redirectUri;
|
||||
|
||||
@Value("${zfile.onedrive-china.clientSecret}")
|
||||
private String clientSecret;
|
||||
|
||||
@Value("${zfile.onedrive-china.scope}")
|
||||
private String scope;
|
||||
|
||||
@Override
|
||||
public void init(Integer driveId) {
|
||||
this.driveId = driveId;
|
||||
Map<String, StorageConfig> stringStorageConfigMap =
|
||||
storageConfigService.selectStorageConfigMapByDriveId(driveId);
|
||||
String accessToken = stringStorageConfigMap.get(StorageConfigConstant.ACCESS_TOKEN_KEY).getValue();
|
||||
String refreshToken = stringStorageConfigMap.get(StorageConfigConstant.REFRESH_TOKEN_KEY).getValue();
|
||||
super.siteId = stringStorageConfigMap.get(StorageConfigConstant.SHAREPOINT_SITE_ID).getValue();
|
||||
super.basePath = stringStorageConfigMap.get(StorageConfigConstant.BASE_PATH).getValue();
|
||||
|
||||
if (StringUtils.isEmpty(accessToken) || StringUtils.isEmpty(refreshToken)) {
|
||||
log.debug("初始化存储策略 [{}] 失败: 参数不完整", getStorageTypeEnum().getDescription());
|
||||
isInitialized = false;
|
||||
} else {
|
||||
refreshOneDriveToken();
|
||||
testConnection();
|
||||
isInitialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public StorageTypeEnum getStorageTypeEnum() {
|
||||
return StorageTypeEnum.SHAREPOINT_DRIVE_CHINA;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getGraphEndPoint() {
|
||||
return "microsoftgraph.chinacloudapi.cn";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAuthenticateEndPoint() {
|
||||
return "login.partner.microsoftonline.cn";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getClientId() {
|
||||
return clientId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRedirectUri() {
|
||||
return redirectUri;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getClientSecret() {
|
||||
return clientSecret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getScope() {
|
||||
return scope;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
package im.zhaojun.zfile.service.impl;
|
||||
|
||||
import im.zhaojun.zfile.model.constant.StorageConfigConstant;
|
||||
import im.zhaojun.zfile.model.entity.StorageConfig;
|
||||
import im.zhaojun.zfile.model.enums.StorageTypeEnum;
|
||||
import im.zhaojun.zfile.service.StorageConfigService;
|
||||
import im.zhaojun.zfile.service.base.AbstractSharePointServiceBase;
|
||||
import im.zhaojun.zfile.service.base.BaseFileService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
|
||||
import org.springframework.context.annotation.Scope;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author zhaojun
|
||||
*/
|
||||
@Service
|
||||
@Slf4j
|
||||
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
|
||||
public class SharePointServiceImpl extends AbstractSharePointServiceBase implements BaseFileService {
|
||||
|
||||
@Resource
|
||||
private StorageConfigService storageConfigService;
|
||||
|
||||
@Value("${zfile.onedrive.clientId}")
|
||||
protected String clientId;
|
||||
|
||||
@Value("${zfile.onedrive.redirectUri}")
|
||||
protected String redirectUri;
|
||||
|
||||
@Value("${zfile.onedrive.clientSecret}")
|
||||
protected String clientSecret;
|
||||
|
||||
@Value("${zfile.onedrive.scope}")
|
||||
protected String scope;
|
||||
|
||||
@Override
|
||||
public void init(Integer driveId) {
|
||||
this.driveId = driveId;
|
||||
Map<String, StorageConfig> stringStorageConfigMap =
|
||||
storageConfigService.selectStorageConfigMapByDriveId(driveId);
|
||||
String accessToken = stringStorageConfigMap.get(StorageConfigConstant.ACCESS_TOKEN_KEY).getValue();
|
||||
String refreshToken = stringStorageConfigMap.get(StorageConfigConstant.REFRESH_TOKEN_KEY).getValue();
|
||||
super.siteId = stringStorageConfigMap.get(StorageConfigConstant.SHAREPOINT_SITE_ID).getValue();
|
||||
super.basePath = stringStorageConfigMap.get(StorageConfigConstant.BASE_PATH).getValue();
|
||||
|
||||
if (StringUtils.isEmpty(accessToken) || StringUtils.isEmpty(refreshToken)) {
|
||||
log.debug("初始化存储策略 [{}] 失败: 参数不完整", getStorageTypeEnum().getDescription());
|
||||
isInitialized = false;
|
||||
} else {
|
||||
refreshOneDriveToken();
|
||||
testConnection();
|
||||
isInitialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public StorageTypeEnum getStorageTypeEnum() {
|
||||
return StorageTypeEnum.SHAREPOINT_DRIVE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getGraphEndPoint() {
|
||||
return "graph.microsoft.com";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAuthenticateEndPoint() {
|
||||
return "login.microsoftonline.com";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getClientId() {
|
||||
return clientId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRedirectUri() {
|
||||
return redirectUri;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getClientSecret() {
|
||||
return clientSecret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getScope() {
|
||||
return scope;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -32,31 +32,28 @@ public class TencentServiceImpl extends AbstractS3BaseFileService implements Bas
|
||||
|
||||
@Override
|
||||
public void init(Integer driveId) {
|
||||
try {
|
||||
this.driveId = driveId;
|
||||
Map<String, StorageConfig> stringStorageConfigMap =
|
||||
storageConfigService.selectStorageConfigMapByDriveId(driveId);
|
||||
String secretId = stringStorageConfigMap.get(StorageConfigConstant.SECRET_ID_KEY).getValue();
|
||||
String secretKey = stringStorageConfigMap.get(StorageConfigConstant.SECRET_KEY).getValue();
|
||||
String endPoint = stringStorageConfigMap.get(StorageConfigConstant.ENDPOINT_KEY).getValue();
|
||||
bucketName = stringStorageConfigMap.get(StorageConfigConstant.BUCKET_NAME_KEY).getValue();
|
||||
domain = stringStorageConfigMap.get(StorageConfigConstant.DOMAIN_KEY).getValue();
|
||||
basePath = stringStorageConfigMap.get(StorageConfigConstant.BASE_PATH).getValue();
|
||||
isPrivate = Convert.toBool(stringStorageConfigMap.get(StorageConfigConstant.IS_PRIVATE).getValue(), true);
|
||||
this.driveId = driveId;
|
||||
Map<String, StorageConfig> stringStorageConfigMap =
|
||||
storageConfigService.selectStorageConfigMapByDriveId(driveId);
|
||||
String secretId = stringStorageConfigMap.get(StorageConfigConstant.SECRET_ID_KEY).getValue();
|
||||
String secretKey = stringStorageConfigMap.get(StorageConfigConstant.SECRET_KEY).getValue();
|
||||
String endPoint = stringStorageConfigMap.get(StorageConfigConstant.ENDPOINT_KEY).getValue();
|
||||
bucketName = stringStorageConfigMap.get(StorageConfigConstant.BUCKET_NAME_KEY).getValue();
|
||||
domain = stringStorageConfigMap.get(StorageConfigConstant.DOMAIN_KEY).getValue();
|
||||
basePath = stringStorageConfigMap.get(StorageConfigConstant.BASE_PATH).getValue();
|
||||
isPrivate = Convert.toBool(stringStorageConfigMap.get(StorageConfigConstant.IS_PRIVATE).getValue(), true);
|
||||
|
||||
if (Objects.isNull(secretId) || Objects.isNull(secretKey) || Objects.isNull(endPoint) || Objects.isNull(bucketName)) {
|
||||
log.debug("初始化存储策略 [{}] 失败: 参数不完整", getStorageTypeEnum().getDescription());
|
||||
isInitialized = false;
|
||||
} else {
|
||||
BasicAWSCredentials credentials = new BasicAWSCredentials(secretId, secretKey);
|
||||
s3Client = AmazonS3ClientBuilder.standard()
|
||||
.withCredentials(new AWSStaticCredentialsProvider(credentials))
|
||||
.withEndpointConfiguration(new AwsClientBuilder.EndpointConfiguration(endPoint, "cos")).build();
|
||||
if (Objects.isNull(secretId) || Objects.isNull(secretKey) || Objects.isNull(endPoint) || Objects.isNull(bucketName)) {
|
||||
log.debug("初始化存储策略 [{}] 失败: 参数不完整", getStorageTypeEnum().getDescription());
|
||||
isInitialized = false;
|
||||
} else {
|
||||
BasicAWSCredentials credentials = new BasicAWSCredentials(secretId, secretKey);
|
||||
s3Client = AmazonS3ClientBuilder.standard()
|
||||
.withCredentials(new AWSStaticCredentialsProvider(credentials))
|
||||
.withEndpointConfiguration(new AwsClientBuilder.EndpointConfiguration(endPoint, "cos")).build();
|
||||
|
||||
isInitialized = testConnection();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.debug(getStorageTypeEnum().getDescription() + " 初始化异常, 已跳过");
|
||||
testConnection();
|
||||
isInitialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -78,4 +75,5 @@ public class TencentServiceImpl extends AbstractS3BaseFileService implements Bas
|
||||
add(new StorageConfig("isPrivate", "是否是私有空间"));
|
||||
}};
|
||||
}
|
||||
|
||||
}
|
||||
@@ -17,4 +17,4 @@ public class UFileServiceImpl extends UpYunServiceImpl {
|
||||
return StorageTypeEnum.UFILE;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -6,6 +6,7 @@ import com.UpYun;
|
||||
import com.upyun.UpException;
|
||||
import im.zhaojun.zfile.exception.NotExistFileException;
|
||||
import im.zhaojun.zfile.model.constant.StorageConfigConstant;
|
||||
import im.zhaojun.zfile.model.constant.ZFileConstant;
|
||||
import im.zhaojun.zfile.model.dto.FileItemDTO;
|
||||
import im.zhaojun.zfile.model.entity.StorageConfig;
|
||||
import im.zhaojun.zfile.model.enums.FileTypeEnum;
|
||||
@@ -49,26 +50,23 @@ public class UpYunServiceImpl extends AbstractBaseFileService implements BaseFil
|
||||
|
||||
@Override
|
||||
public void init(Integer driveId) {
|
||||
try {
|
||||
this.driveId = driveId;
|
||||
Map<String, StorageConfig> stringStorageConfigMap =
|
||||
storageConfigService.selectStorageConfigMapByDriveId(driveId);
|
||||
String bucketName = stringStorageConfigMap.get(StorageConfigConstant.BUCKET_NAME_KEY).getValue();
|
||||
String username = stringStorageConfigMap.get(StorageConfigConstant.USERNAME_KEY).getValue();
|
||||
String password = stringStorageConfigMap.get(StorageConfigConstant.PASSWORD_KEY).getValue();
|
||||
domain = stringStorageConfigMap.get(StorageConfigConstant.DOMAIN_KEY).getValue();
|
||||
basePath = stringStorageConfigMap.get(StorageConfigConstant.BASE_PATH).getValue();
|
||||
basePath = ObjectUtil.defaultIfNull(basePath, "");
|
||||
this.driveId = driveId;
|
||||
Map<String, StorageConfig> stringStorageConfigMap =
|
||||
storageConfigService.selectStorageConfigMapByDriveId(driveId);
|
||||
String bucketName = stringStorageConfigMap.get(StorageConfigConstant.BUCKET_NAME_KEY).getValue();
|
||||
String username = stringStorageConfigMap.get(StorageConfigConstant.USERNAME_KEY).getValue();
|
||||
String password = stringStorageConfigMap.get(StorageConfigConstant.PASSWORD_KEY).getValue();
|
||||
domain = stringStorageConfigMap.get(StorageConfigConstant.DOMAIN_KEY).getValue();
|
||||
basePath = stringStorageConfigMap.get(StorageConfigConstant.BASE_PATH).getValue();
|
||||
basePath = ObjectUtil.defaultIfNull(basePath, "");
|
||||
|
||||
if (Objects.isNull(bucketName) || Objects.isNull(username) || Objects.isNull(password)) {
|
||||
log.debug("初始化存储策略 [{}] 失败: 参数不完整", getStorageTypeEnum().getDescription());
|
||||
isInitialized = false;
|
||||
} else {
|
||||
upYun = new UpYun(bucketName, username, password);
|
||||
isInitialized = testConnection();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.debug(getStorageTypeEnum().getDescription() + " 初始化异常, 已跳过");
|
||||
if (Objects.isNull(bucketName) || Objects.isNull(username) || Objects.isNull(password)) {
|
||||
log.debug("初始化存储策略 [{}] 失败: 参数不完整", getStorageTypeEnum().getDescription());
|
||||
isInitialized = false;
|
||||
} else {
|
||||
upYun = new UpYun(bucketName, username, password);
|
||||
testConnection();
|
||||
isInitialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -122,7 +120,7 @@ public class UpYunServiceImpl extends AbstractBaseFileService implements BaseFil
|
||||
int lastDelimiterIndex = path.lastIndexOf("/");
|
||||
String name = path.substring(lastDelimiterIndex + 1);
|
||||
|
||||
Map<String, String> fileInfo = upYun.getFileInfo(StringUtils.removeDuplicateSeparator(basePath + "/" + path));
|
||||
Map<String, String> fileInfo = upYun.getFileInfo(StringUtils.removeDuplicateSeparator(basePath + ZFileConstant.PATH_SEPARATOR + path));
|
||||
|
||||
if (fileInfo == null) {
|
||||
throw new NotExistFileException();
|
||||
@@ -138,7 +136,7 @@ public class UpYunServiceImpl extends AbstractBaseFileService implements BaseFil
|
||||
fileItemDTO.setType(FileTypeEnum.FOLDER);
|
||||
} else {
|
||||
fileItemDTO.setType(FileTypeEnum.FILE);
|
||||
fileItemDTO.setUrl(getDownloadUrl(StringUtils.removeDuplicateSeparator(basePath + "/" + path)));
|
||||
fileItemDTO.setUrl(getDownloadUrl(StringUtils.removeDuplicateSeparator(basePath + ZFileConstant.PATH_SEPARATOR + path)));
|
||||
}
|
||||
return fileItemDTO;
|
||||
} catch (IOException | UpException e) {
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
package im.zhaojun.zfile.service.support;
|
||||
|
||||
import im.zhaojun.zfile.model.support.SystemMonitorInfo;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* @author zhaojun
|
||||
*/
|
||||
@Service
|
||||
public class SystemMonitorService {
|
||||
|
||||
public SystemMonitorInfo systemMonitorInfo() {
|
||||
return new SystemMonitorInfo();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -24,9 +24,9 @@ import java.net.URL;
|
||||
* 音频解析工具类
|
||||
* @author zhaojun
|
||||
*/
|
||||
public class AudioHelper {
|
||||
public class AudioUtil {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(AudioHelper.class);
|
||||
private static final Logger log = LoggerFactory.getLogger(AudioUtil.class);
|
||||
|
||||
public static AudioInfoDTO getAudioInfo(String url) throws Exception {
|
||||
String query = new URL(URLUtil.decode(url)).getQuery();
|
||||
@@ -41,7 +41,9 @@ public class AudioHelper {
|
||||
return AudioInfoDTO.buildDefaultAudioInfoDTO();
|
||||
}
|
||||
|
||||
File file = new File(ZFileConstant.USER_HOME + ZFileConstant.AUDIO_TMP_PATH + UUID.fastUUID());
|
||||
String fullFilePath = StringUtils.removeDuplicateSeparator(ZFileConstant.TMP_FILE_PATH + ZFileConstant.PATH_SEPARATOR + UUID.fastUUID());
|
||||
|
||||
File file = new File(fullFilePath);
|
||||
FileUtil.mkParentDirs(file);
|
||||
HttpUtil.downloadFile(url, file);
|
||||
AudioInfoDTO audioInfoDTO = parseAudioInfo(file);
|
||||
@@ -1,5 +1,6 @@
|
||||
package im.zhaojun.zfile.util;
|
||||
|
||||
import cn.hutool.core.io.FileUtil;
|
||||
import im.zhaojun.zfile.exception.PreviewException;
|
||||
import im.zhaojun.zfile.model.constant.ZFileConstant;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@@ -16,13 +17,19 @@ import java.net.URLConnection;
|
||||
public class HttpUtil {
|
||||
|
||||
/**
|
||||
* 最大支持文件预览大小: 1M
|
||||
* 获取 URL 对应的文件内容
|
||||
*
|
||||
* @param url
|
||||
* 文件 URL
|
||||
* @return 文件 URL
|
||||
*/
|
||||
public static String getTextContent(String url) {
|
||||
RestTemplate restTemplate = SpringContextHolder.getBean("restTemplate");
|
||||
|
||||
if (getRemoteFileSize(url) > (1024 * ZFileConstant.TEXT_MAX_FILE_SIZE_KB)) {
|
||||
throw new PreviewException("存储源跨域请求失败, 服务器中转状态, 预览文件超出大小, 最大支持 1M");
|
||||
long maxFileSize = 1024 * ZFileConstant.TEXT_MAX_FILE_SIZE_KB;
|
||||
|
||||
if (getRemoteFileSize(url) > maxFileSize) {
|
||||
throw new PreviewException("预览文件超出大小, 最大支持 " + FileUtil.readableFileSize(maxFileSize));
|
||||
}
|
||||
|
||||
String result = restTemplate.getForObject(url, String.class);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package im.zhaojun.zfile.util;
|
||||
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import im.zhaojun.zfile.model.constant.ZFileConstant;
|
||||
|
||||
/**
|
||||
* @author zhaojun
|
||||
@@ -98,6 +99,6 @@ public class StringUtils {
|
||||
public static String getFullPath(String basePath, String path) {
|
||||
basePath = ObjectUtil.defaultIfNull(basePath, "");
|
||||
path = ObjectUtil.defaultIfNull(path, "");
|
||||
return StringUtils.removeDuplicateSeparator(basePath + "/" + path);
|
||||
return StringUtils.removeDuplicateSeparator(basePath + ZFileConstant.PATH_SEPARATOR + path);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,6 +71,26 @@
|
||||
"name": "zfile.preview.text.maxFileSizeKb",
|
||||
"type": "java.lang.Long",
|
||||
"description": "允许在线读取文本文件的文件大小, 单位为 KB."
|
||||
},
|
||||
{
|
||||
"name": "zfile.log.path",
|
||||
"type": "java.lang.String",
|
||||
"description": "日志文件路径."
|
||||
},
|
||||
{
|
||||
"name": "zfile.db.path",
|
||||
"type": "java.lang.String",
|
||||
"description": "数据库文件路径."
|
||||
},
|
||||
{
|
||||
"name": "zfile.tmp.path",
|
||||
"type": "java.lang.String",
|
||||
"description": "临时文件路径."
|
||||
},
|
||||
{
|
||||
"name": "zfile.debug",
|
||||
"type": "java.lang.Boolean",
|
||||
"description": "是否开启 debug 模式."
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,3 +1,34 @@
|
||||
zfile:
|
||||
debug: false
|
||||
log:
|
||||
path: ${user.home}/.zfile/logs
|
||||
db:
|
||||
path: ${user.home}/.zfile/db/zfile
|
||||
tmp:
|
||||
path: ${user.home}/.zfile/tmp
|
||||
cache:
|
||||
auto-refresh:
|
||||
interval: 1
|
||||
timeout: 1800
|
||||
constant:
|
||||
readme: readme.md
|
||||
password: password.txt
|
||||
preview:
|
||||
audio:
|
||||
maxFileSizeMb: 5
|
||||
text:
|
||||
maxFileSizeKb: 512
|
||||
onedrive:
|
||||
clientId: 09939809-c617-43c8-a220-a93c1513c5d4
|
||||
clientSecret: _l:zI-_yrW75lV8M61K@z.I2K@B/On6Q
|
||||
redirectUri: https://zfile.jun6.net/onedrive/callback
|
||||
scope: offline_access User.Read Files.ReadWrite.All
|
||||
onedrive-china:
|
||||
clientId: 4a72d927-1907-488d-9eb2-1b465c53c1c5
|
||||
clientSecret: Y9CEA=82da5n-y_]KAWAgLH3?R9xf7Uw
|
||||
redirectUri: https://zfile.jun6.net/onedrive/china-callback
|
||||
scope: offline_access User.Read Files.ReadWrite.All
|
||||
|
||||
server:
|
||||
port: 8080
|
||||
servlet:
|
||||
@@ -13,7 +44,7 @@ spring:
|
||||
settings:
|
||||
web-allow-others: true
|
||||
path: /h2-console
|
||||
enabled: false
|
||||
enabled: ${zfile.debug}
|
||||
datasource:
|
||||
# 初始化数据导入
|
||||
data: classpath*:db/data.sql
|
||||
@@ -24,7 +55,7 @@ spring:
|
||||
|
||||
# h2 内存数据库 配置
|
||||
driver-class-name: org.h2.Driver
|
||||
url: jdbc:h2:~/.zfile-new/db/zfile
|
||||
url: jdbc:h2:${zfile.db.path}
|
||||
username: zfile
|
||||
password: 123456
|
||||
|
||||
@@ -47,28 +78,4 @@ spring:
|
||||
chain:
|
||||
gzipped: true
|
||||
profiles:
|
||||
active: prod
|
||||
|
||||
zfile:
|
||||
cache:
|
||||
auto-refresh:
|
||||
interval: 1
|
||||
timeout: 1800
|
||||
constant:
|
||||
readme: readme.md
|
||||
password: password.txt
|
||||
preview:
|
||||
audio:
|
||||
maxFileSizeMb: 5
|
||||
text:
|
||||
maxFileSizeKb: 512
|
||||
onedrive:
|
||||
clientId: 09939809-c617-43c8-a220-a93c1513c5d4
|
||||
clientSecret: _l:zI-_yrW75lV8M61K@z.I2K@B/On6Q
|
||||
redirectUri: https://zfile.jun6.net/onedrive/callback
|
||||
scope: offline_access User.Read Files.ReadWrite.All
|
||||
onedrive-china:
|
||||
clientId: 4a72d927-1907-488d-9eb2-1b465c53c1c5
|
||||
clientSecret: Y9CEA=82da5n-y_]KAWAgLH3?R9xf7Uw
|
||||
redirectUri: https://zfile.jun6.net/onedrive/china-callback
|
||||
scope: offline_access User.Read Files.ReadWrite.All
|
||||
active: prod
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user