Compare commits

...

33 Commits
2.4 ... 2.8.1

Author SHA1 Message Date
zhaojun1998
75f5de6b9a 🔖 发布 2.8.1 版 2020-08-18 20:43:07 +08:00
zhaojun1998
499942ef70 🎨 更新静态页面 2020-08-18 20:43:02 +08:00
zhaojun1998
e11277ce26 🔖 发布 2.8 版 2020-08-17 21:04:40 +08:00
zhaojun1998
5edd9e38a7 🎨 更新静态页面 2020-08-17 21:04:16 +08:00
zhaojun1998
f4ffee706b 驱动器无效时, 访问系统设置, 给予异常提示 2020-08-16 09:23:07 +08:00
zhaojun1998
bb65750278 查询数据库为空判断 2020-08-16 09:20:21 +08:00
zhaojun1998
e09167c0d0 拖动排序功能 2020-08-15 21:18:38 +08:00
zhaojun1998
ee6c04fa11 🐛 修复 ftp 模式, 依旧获取尝试获取 readme 内容的 BUG. 2020-08-15 17:48:51 +08:00
zhaojun1998
b31982b788 增加文件过滤功能, 同一存储器支持多条规则, 支持通配符. 2020-08-15 17:48:07 +08:00
zhaojun1998
544a3d3eb2 更新静态页面 2020-08-07 21:33:36 +08:00
zhaojun1998
1987bc97a9 🎨 改进 README 文件不存在时, 异常处理机制. 2020-06-27 21:13:24 +08:00
zhaojun1998
7e878af06c 驱动器增加 "启用/禁用" 和 "排序" 功能. 2020-06-27 21:12:54 +08:00
zhaojun1998
766a047ee1 🔊 优化日志输出, 完善日志信息, 便于调试. 2020-06-26 21:35:08 +08:00
zhaojun1998
c1d29a46f5 🎨 代码规范调整, 移除无效引用, 增加注释. 2020-06-26 16:26:09 +08:00
zhaojun1998
08e39b3d15 ✏️ 修复拼写错误 2020-06-26 12:36:35 +08:00
zhaojun1998
e7790ac256 🎨 改进异常处理机制, 给予更详细的提示信息, 便于排查问题. 2020-06-26 12:35:34 +08:00
zhaojun1998
499f3e108c 🔧 日志输出添加代码行号显示, 便于调试. 2020-06-26 12:20:26 +08:00
zhaojun1998
19144b653e 📝 更新 API 文档 2020-06-25 17:54:05 +08:00
zhaojun1998
17a87648fa 🐛 修复本地存储, 填写 Windows 盘符, 无法正常识别的 BUG 2020-06-25 17:52:33 +08:00
zhaojun1998
ac4cef0980 配置文件新增配置项, 以自定义 '日志文件', '数据文件', '临时文件' 的路径 2020-06-25 17:51:35 +08:00
zhaojun1998
71978f8003 🎨 移除未用到的代码 2020-06-25 17:49:58 +08:00
zhaojun1998
0b3a67ec6e 🎨 优化代码结构, 拆分代码 2020-06-25 17:48:38 +08:00
zhaojun1998
ee5fb54ebb 🎨 优化代码结构, 调整包名, 方法名. 2020-06-25 17:05:59 +08:00
zhaojun1998
4585f22817 🔖 发布 2.7 版 2020-05-24 15:46:10 +08:00
zhaojun1998
b523453588 💄 更新页面 2020-05-24 15:45:38 +08:00
zhaojun1998
a8cc03c911 🔨 优化代码 2020-05-24 15:45:25 +08:00
zhaojun1998
949c437653 新增缓存管理功能, 支持手动/自动刷新缓存, 查看、清理缓存。 2020-05-24 15:41:33 +08:00
zhaojun1998
84e9cce60f 🔖 发布 2.6 版 2020-05-13 21:52:46 +08:00
zhaojun1998
5720bd93ec 💄 更新页面 2020-05-13 21:51:52 +08:00
zhaojun1998
bcae9713bc 🐛 修复自定义 JS, CSS 超出数据库长度无法保存的 BUG. 2020-05-13 21:51:27 +08:00
zhaojun1998
04e3023071 🔖 发布 2.5 版 2020-05-04 21:00:33 +08:00
zhaojun1998
a09ef84629 💄 更新页面 2020-05-04 21:00:13 +08:00
zhaojun1998
1d29395191 🐛 修复 OneDrive 某些情况下 Access Token 过长, 因超出数据库长度无法保存的 BUG. 2020-05-04 20:59:48 +08:00
115 changed files with 1366 additions and 993 deletions

115
API.md
View File

@@ -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
}
}
```
```

View File

@@ -12,7 +12,7 @@
<groupId>im.zhaojun</groupId>
<artifactId>zfile</artifactId>
<version>2.4</version>
<version>2.8.1</version>
<name>zfile</name>
<packaging>war</packaging>
<description>一个在线的文件浏览系统</description>

View File

@@ -19,7 +19,7 @@ import java.util.List;
*/
@Aspect
@Component
public class FileListCacheAop {
public class FileListCacheAspect {
@Resource
private ZFileCache zFileCache;

View File

@@ -0,0 +1,19 @@
package im.zhaojun.zfile.cache;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @author zhaojun
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class DriveCacheKey {
private Integer driveId;
private String key;
}

View File

@@ -0,0 +1,55 @@
package im.zhaojun.zfile.cache;
import cn.hutool.cache.impl.CacheObj;
import cn.hutool.cache.impl.TimedCache;
import im.zhaojun.zfile.context.DriveContext;
import im.zhaojun.zfile.service.base.AbstractBaseFileService;
import im.zhaojun.zfile.util.SpringContextHolder;
import lombok.extern.slf4j.Slf4j;
import java.util.Map;
/**
* @author zhaojun
*/
@Slf4j
public class MyTimedCache<K, V> extends TimedCache<K, V> {
private DriveContext driveContext;
public MyTimedCache(long timeout) {
super(timeout);
}
public MyTimedCache(long timeout, Map<K, CacheObj<K, V>> map) {
super(timeout, map);
}
@Override
protected void onRemove(K key, V cachedObject) {
if (driveContext == null) {
driveContext = SpringContextHolder.getBean(DriveContext.class);
}
DriveCacheKey cacheKey = (DriveCacheKey) key;
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);
e.printStackTrace();
}
}
}

View File

@@ -1,14 +1,13 @@
package im.zhaojun.zfile.cache;
import cn.hutool.cache.CacheUtil;
import cn.hutool.cache.impl.CacheObj;
import cn.hutool.cache.impl.TimedCache;
import cn.hutool.core.util.StrUtil;
import im.zhaojun.zfile.model.constant.ZFileConstant;
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;
@@ -28,14 +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>>
@@ -44,16 +55,13 @@ public class ZFileCache {
* key: 文件夹路径
* value: 文件夹中内容
*/
private ConcurrentMap<Integer, TimedCache<String, List<FileItemDTO>>> drivesCache = new ConcurrentHashMap<>();
private ConcurrentMap<Integer, MyTimedCache<DriveCacheKey, List<FileItemDTO>>> drivesCache = new ConcurrentHashMap<>();
/**
* 系统设置缓存
*/
private SystemConfigDTO systemConfigCache;
@Resource
private DriverConfigRepository driverConfigRepository;
/**
* 写入缓存
@@ -68,7 +76,7 @@ public class ZFileCache {
* 文件夹中列表
*/
public synchronized void put(Integer driveId, String key, List<FileItemDTO> value) {
getCacheByDriveId(driveId).put(key, value);
getCacheByDriveId(driveId).put(new DriveCacheKey(driveId, key), value);
}
@@ -84,7 +92,7 @@ public class ZFileCache {
* @return 驱动器中文件夹的内容
*/
public List<FileItemDTO> get(Integer driveId, String key) {
return getCacheByDriveId(driveId).get(key, false);
return getCacheByDriveId(driveId).get(new DriveCacheKey(driveId, key), false);
}
@@ -95,6 +103,9 @@ public class ZFileCache {
* 驱动器 ID
*/
public void clear(Integer driveId) {
if (log.isDebugEnabled()) {
log.debug("清空驱动器所有缓存, driveId: {}", driveId);
}
getCacheByDriveId(driveId).clear();
}
@@ -161,17 +172,17 @@ public class ZFileCache {
* @return 所有缓存 key
*/
public Set<String> keySet(Integer driveId) {
Iterator<CacheObj<String, List<FileItemDTO>>> cacheObjIterator = getCacheByDriveId(driveId).cacheObjIterator();
Iterator<CacheObj<DriveCacheKey, List<FileItemDTO>>> cacheObjIterator = getCacheByDriveId(driveId).cacheObjIterator();
Set<String> keys = new HashSet<>();
while (cacheObjIterator.hasNext()) {
keys.add(cacheObjIterator.next().getKey());
keys.add(cacheObjIterator.next().getKey().getKey());
}
return keys;
}
/**
* 从缓存中删除指定存储器的某个路径的缓存
* 从缓存中删除指定驱动器的某个路径的缓存
*
* @param driveId
* 驱动器 ID
@@ -180,7 +191,7 @@ public class ZFileCache {
* 文件夹路径
*/
public void remove(Integer driveId, String key) {
getCacheByDriveId(driveId).remove(key);
getCacheByDriveId(driveId).remove(new DriveCacheKey(driveId, key));
}
@@ -241,14 +252,80 @@ public class ZFileCache {
*
* @return 驱动器对应的缓存
*/
private synchronized TimedCache<String, List<FileItemDTO>> getCacheByDriveId(Integer driveId) {
TimedCache<String, List<FileItemDTO>> driveCache = drivesCache.get(driveId);
private synchronized MyTimedCache<DriveCacheKey, List<FileItemDTO>> getCacheByDriveId(Integer driveId) {
MyTimedCache<DriveCacheKey, List<FileItemDTO>> driveCache = drivesCache.get(driveId);
if (driveCache == null) {
driveCache = CacheUtil.newTimedCache(timeout * 1000);
driveCache = new MyTimedCache<>(timeout * 1000);
drivesCache.put(driveId, driveCache);
startAutoCacheRefresh(driveId);
}
return driveCache;
}
/**
* 获取指定驱动器的缓存命中数
*
* @param driveId
* 驱动器 ID
*
* @return 缓存命中数
*/
public int getHitCount(Integer driveId) {
return getCacheByDriveId(driveId).getHitCount();
}
/**
* 获取指定驱动器的缓存未命中数
*
* @param driveId
* 驱动器 ID
*
* @return 缓存未命中数
*/
public int getMissCount(Integer driveId) {
return getCacheByDriveId(driveId).getMissCount();
}
/**
* 开启缓存自动刷新
*
* @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) {
MyTimedCache<DriveCacheKey, List<FileItemDTO>> driveCache = drivesCache.get(driveId);
if (driveCache == null) {
driveCache = new MyTimedCache<>(timeout * 1000);
drivesCache.put(driveId, driveCache);
}
driveCache.schedulePrune(autoRefreshInterval * 1000);
}
}
/**
* 停止缓存自动刷新
*
* @param driveId
* 驱动器 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();
}
}
}

View File

@@ -2,10 +2,7 @@ package im.zhaojun.zfile.config;
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.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;
@@ -25,13 +22,6 @@ public class OneDriveConfig {
@Resource
private StorageConfigService storageConfigService;
@Resource
private OneDriveServiceImpl oneDriveServiceImpl;
@Resource
private OneDriveChinaServiceImpl oneDriveChinaServiceImpl;
/**
* OneDrive 请求 RestTemplate, 会在请求头中添加 Bearer: Authorization {token} 信息, 用于 API 认证.
*/

View File

@@ -31,4 +31,4 @@ public class ZFileConfiguration {
return restTemplate;
}
}
}

View File

@@ -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);
}
@@ -92,16 +128,4 @@ public class DriveContext implements ApplicationContextAware {
return null;
}
/**
* 项目启动时, 自动调用所有驱动器进行初始化.
*/
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
List<DriveConfig> list = driveConfigService.list();
for (DriveConfig driveConfig : list) {
initDrive(driveConfig.getId());
}
}
}

View File

@@ -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;

View File

@@ -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());
}
}

View File

@@ -1,7 +1,9 @@
package im.zhaojun.zfile.controller.admin;
import im.zhaojun.zfile.model.dto.ResultBean;
import im.zhaojun.zfile.model.dto.CacheInfoDTO;
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;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
@@ -21,17 +23,50 @@ public class CacheController {
@Resource
private DriveConfigService driveConfigService;
@PostMapping("/{driveId}/enable")
public ResultBean enableCache(@PathVariable("driveId") Integer driveId) {
driveConfigService.updateCacheStatus(driveId, true);
return ResultBean.success();
}
@PostMapping("/{driveId}/disable")
public ResultBean disableCache(@PathVariable("driveId") Integer driveId) {
driveConfigService.updateCacheStatus(driveId, false);
return ResultBean.success();
}
@GetMapping("/{driveId}/info")
public ResultBean cacheInfo(@PathVariable("driveId") Integer driveId) {
CacheInfoDTO cacheInfo = driveConfigService.findCacheInfo(driveId);
return ResultBean.success(cacheInfo);
}
@PostMapping("/{driveId}/refresh")
public ResultBean refreshCache(@PathVariable("driveId") Integer driveId, String key) throws Exception {
driveConfigService.refreshCache(driveId, key);
return ResultBean.success();
}
@PostMapping("/{driveId}/auto-refresh/start")
public ResultBean enableAutoRefresh(@PathVariable("driveId") Integer driveId) {
driveConfigService.startAutoCacheRefresh(driveId);
return ResultBean.success();
}
@PostMapping("/{driveId}/auto-refresh/stop")
public ResultBean disableAutoRefresh(@PathVariable("driveId") Integer driveId) {
driveConfigService.stopAutoCacheRefresh(driveId);
return ResultBean.success();
}
@PostMapping("/{driveId}/clear")
public ResultBean clearCache(@PathVariable("driveId") Integer driveId) {
driveConfigService.clearCache(driveId);
return ResultBean.success();
}
}

View File

@@ -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,25 @@ 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);
@@ -47,9 +50,9 @@ public class DriveController {
* @param id
* 驱动器 ID
*
* @return 驱动器基本信息信息
* @return 驱动器基本信息
*/
@GetMapping("drive/{id}")
@GetMapping("/drive/{id}")
public ResultBean driveItem(@PathVariable Integer id) {
DriveConfigDTO driveConfig = driveConfigService.findDriveConfigDTOById(id);
return ResultBean.success(driveConfig);
@@ -59,9 +62,9 @@ public class DriveController {
/**
* 保存驱动器设置
*/
@PostMapping("drive")
@PostMapping("/drive")
public ResultBean saveDriveItem(@RequestBody DriveConfigDTO driveConfigDTO) {
driveConfigService.save(driveConfigDTO);
driveConfigService.saveDriveConfigDTO(driveConfigDTO);
return ResultBean.success();
}
@@ -72,10 +75,58 @@ public class DriveController {
* @param id
* 驱动器 ID
*/
@DeleteMapping("drive/{id}")
@DeleteMapping("/drive/{id}")
public ResultBean deleteDriveItem(@PathVariable Integer id) {
driveConfigService.deleteById(id);
return ResultBean.success();
}
/**
* 启用驱动器
*
* @param id
* 驱动器 ID
*/
@PostMapping("/drive/{id}/enable")
public ResultBean enable(@PathVariable("id") Integer id) {
DriveConfig driveConfig = driveConfigService.findById(id);
driveConfig.setEnable(true);
driveConfigService.saveOrUpdate(driveConfig);
return ResultBean.success();
}
/**
* 停止驱动器
*
* @param id
* 驱动器 ID
*/
@PostMapping("/drive/{id}/disable")
public ResultBean disable(@PathVariable("id") Integer id) {
DriveConfig driveConfig = driveConfigService.findById(id);
driveConfig.setEnable(false);
driveConfigService.saveOrUpdate(driveConfig);
return ResultBean.success();
}
@GetMapping("/drive/{id}/filters")
public ResultBean getFilters(@PathVariable("id") Integer id) {
return ResultBean.success(filterConfigService.findByDriveId(id));
}
@PostMapping("/drive/{id}/filters")
public ResultBean saveFilters(@RequestBody List<FilterConfig> filter, @PathVariable("id") Integer driveId) {
filterConfigService.batchSave(filter, driveId);
return ResultBean.success();
}
@PostMapping("/drive/drag")
public ResultBean saveDriveDrag(@RequestBody List<JSONObject> driveConfigs) {
driveConfigService.saveDriveDrag(driveConfigs);
return ResultBean.success();
}
}

View File

@@ -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");
}
}

View File

@@ -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);
}
}

View File

@@ -0,0 +1,26 @@
package im.zhaojun.zfile.controller.admin;
import im.zhaojun.zfile.model.support.ResultBean;
import im.zhaojun.zfile.model.support.SystemMonitorInfo;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* 系统监控 Controller
* @author zhaojun
*/
@RestController
@RequestMapping("/admin")
public class MonitorController {
/**
* 获取系统监控信息
*/
@GetMapping("monitor")
public ResultBean monitor() {
return ResultBean.success(new SystemMonitorInfo());
}
}

View File

@@ -1,11 +1,11 @@
package im.zhaojun.zfile.controller;
package im.zhaojun.zfile.controller.home;
import cn.hutool.core.util.URLUtil;
import im.zhaojun.zfile.context.DriveContext;
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;
@@ -20,7 +20,7 @@ import java.util.Objects;
* @author Zhao Jun
*/
@Controller
public class PageController {
public class DirectLinkController {
@Resource
private DriveContext driveContext;
@@ -44,7 +44,7 @@ public class PageController {
filePath = "/" + filePath;
}
AbstractBaseFileService fileService = driveContext.getDriveService(driveId);
AbstractBaseFileService fileService = driveContext.get(driveId);
FileItemDTO fileItem = fileService.getFileItem(filePath);
String url = fileItem.getUrl();
@@ -67,4 +67,5 @@ public class PageController {
return "redirect:" + url;
}
}
}
}

View File

@@ -1,14 +1,19 @@
package im.zhaojun.zfile.controller;
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.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.entity.DriveConfig;
import im.zhaojun.zfile.model.enums.StorageTypeEnum;
import im.zhaojun.zfile.model.support.FilePageModel;
import im.zhaojun.zfile.model.support.ResultBean;
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.context.DriveContext;
import im.zhaojun.zfile.util.FileComparator;
import im.zhaojun.zfile.util.HttpUtil;
import im.zhaojun.zfile.util.StringUtils;
@@ -45,6 +50,9 @@ public class FileController {
@Resource
private DriveConfigService driveConfigService;
@Resource
private FilterConfigService filterConfigService;
/**
* 滚动加载每页条数.
*/
@@ -52,13 +60,13 @@ public class FileController {
/**
* 获取所有驱动器
* 获取所有已启用的驱动器
*
* @return 所有驱动器
* @return 所有已启用驱动器
*/
@GetMapping("/drive/list")
public ResultBean drives() {
return ResultBean.success(driveConfigService.list());
return ResultBean.success(driveConfigService.listOnlyEnable());
}
/**
@@ -83,8 +91,9 @@ public class FileController {
@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 + "/"));
AbstractBaseFileService fileService = driveContext.get(driveId);
List<FileItemDTO> fileItemList =
fileService.fileList(StringUtils.removeDuplicateSeparator(ZFileConstant.PATH_SEPARATOR + path + ZFileConstant.PATH_SEPARATOR));
for (FileItemDTO fileItemDTO : fileItemList) {
if (ZFileConstant.PASSWORD_FILE_NAME.equals(fileItemDTO.getName())) {
@@ -92,13 +101,14 @@ public class FileController {
try {
expectedPasswordContent = HttpUtil.getTextContent(fileItemDTO.getUrl());
} catch (HttpClientErrorException httpClientErrorException) {
log.debug("尝试重新获取密码文件缓存中链接后仍失败", httpClientErrorException);
log.error("尝试重新获取密码文件缓存中链接后仍失败, driveId: {}, path: {}, inputPassword: {}, passwordFile:{} ",
driveId, path, password, JSON.toJSONString(fileItemDTO), httpClientErrorException);
try {
String fullPath = StringUtils.removeDuplicateSeparator(fileItemDTO.getPath() + "/" + fileItemDTO.getName());
String fullPath = StringUtils.removeDuplicateSeparator(fileItemDTO.getPath() + ZFileConstant.PATH_SEPARATOR + fileItemDTO.getName());
FileItemDTO fileItem = fileService.getFileItem(fullPath);
expectedPasswordContent = HttpUtil.getTextContent(fileItem.getUrl());
} catch (Exception e) {
log.debug("尝试重新获取密码文件链接后仍失败, 已暂时取消密码", e);
log.error("尝试重新获取密码文件链接后仍失败, 已暂时取消密码", e);
break;
}
}
@@ -113,6 +123,9 @@ public class FileController {
return ResultBean.error("此文件夹需要密码.", ResultBean.REQUIRED_PASSWORD);
}
}
// 过滤掉表达式中不存在的数据.
fileItemList.removeIf(next -> filterConfigService.filterResultIsHidden(driveId, StringUtils.concatUrl(next.getPath(), next.getName())));
return ResultBean.successData(getSortedPagingData(fileItemList, page));
}
@@ -122,20 +135,29 @@ public class FileController {
* @param driveId
* 驱动器 ID
*
* @return 返回指定存储器的系统配置信息
* @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);
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 {
FileItemDTO fileItem = fileService.getFileItem(fullPath);
String readme = HttpUtil.getTextContent(fileItem.getUrl());
systemConfig.setReadme(readme);
fileItem = fileService.getFileItem(fullPath);
if (!Objects.equals(driveConfig.getType(), StorageTypeEnum.FTP)) {
String readme = HttpUtil.getTextContent(fileItem.getUrl());
systemConfig.setReadme(readme);
}
} catch (Exception e) {
// ignore
if (e instanceof NotExistFileException) {
log.debug("不存在 README 文件, 已跳过, fullPath: {}, fileItem: {}", fullPath, JSON.toJSONString(fileItem));
} else {
log.error("获取 README 文件异常, fullPath: {}, fileItem: {}", fullPath, JSON.toJSONString(fileItem), e);
}
}
return ResultBean.successData(systemConfig);
@@ -214,7 +236,8 @@ public class FileController {
*/
@GetMapping("/directlink/{driveId}")
public ResultBean directlink(@PathVariable(name = "driveId") Integer driveId, String path) {
AbstractBaseFileService fileService = driveContext.getDriveService(driveId);
AbstractBaseFileService fileService = driveContext.get(driveId);
return ResultBean.successData(fileService.getFileItem(path));
}
}
}

View File

@@ -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));
}
}

View File

@@ -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)));
}
}

View File

@@ -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())) {

View File

@@ -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;

View File

@@ -1,6 +1,6 @@
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;
@@ -20,28 +20,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 +29,7 @@ public class GlobleExceptionHandler {
return ResultBean.error("文件不存在");
}
/**
* 捕获 ClientAbortException 异常, 不做任何处理, 防止出现大量堆栈日志输出, 此异常不影响功能.
*/
@@ -63,6 +42,7 @@ public class GlobleExceptionHandler {
// }
}
/**
* 文件预览异常
*/
@@ -77,24 +57,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)
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("系统异常, 请联系管理员");
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -26,4 +26,5 @@ public class StorageStrategyUninitializedException extends RuntimeException {
public StorageStrategyUninitializedException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
}
}

View File

@@ -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);
}
}

View File

@@ -23,4 +23,5 @@ public class MyCorsFilter {
urlBasedCorsConfigurationSource.registerCorsConfiguration("/**", corsConfiguration);
return new CorsFilter(urlBasedCorsConfigurationSource);
}
}
}

View File

@@ -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 {
}
}
}

View File

@@ -24,4 +24,4 @@ public class AudioInfoDTO {
return audioInfoDTO;
}
}
}

View File

@@ -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;
}

View File

@@ -0,0 +1,23 @@
package im.zhaojun.zfile.model.dto;
import lombok.AllArgsConstructor;
import lombok.Data;
import java.util.Set;
/**
* @author zhaojun
*/
@Data
@AllArgsConstructor
public class CacheInfoDTO {
private Integer cacheCount;
private Integer hitCount;
private Integer missCount;
private Set<String> cacheKeys;
}

View File

@@ -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;
}

View File

@@ -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 +
'}';
}
}

View File

@@ -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;
//
// }

View File

@@ -19,9 +19,6 @@ public class SystemFrontConfigDTO {
private Boolean searchEnable;
// @JsonSerialize(using = StorageTypeEnumSerializerConvert.class)
// private StorageTypeEnum storageStrategy;
private String username;
private String domain;

View File

@@ -21,6 +21,8 @@ public class DriveConfig {
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
private Boolean enable;
private String name;
private Boolean enableCache;
@@ -35,4 +37,6 @@ public class DriveConfig {
private Boolean searchContainEncryptedFile;
private Integer orderNum;
}

View File

@@ -0,0 +1,27 @@
package im.zhaojun.zfile.model.entity;
import lombok.Data;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Lob;
/**
* @author zhaojun
*/
@Entity(name = "FILTER_CONFIG")
@Data
public class FilterConfig {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
private Integer driveId;
private String expression;
}

View File

@@ -8,6 +8,7 @@ import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Lob;
/**
* @author zhaojun
@@ -27,7 +28,7 @@ public class StorageConfig {
private String title;
@Column(length = 4000)
@Lob
private String value;
private Integer driveId;
@@ -37,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;
}
}

View File

@@ -7,6 +7,7 @@ import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Lob;
/**
* @author zhaojun
@@ -22,39 +23,9 @@ public class SystemConfig {
@Column(name = "k")
private String key;
@Lob
private String value;
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;
}
}

View File

@@ -28,4 +28,5 @@ public enum FileTypeEnum {
public void setValue(String value) {
this.value = value;
}
}

View File

@@ -63,4 +63,4 @@ public enum StorageTypeEnum {
return enumMap.get(value.toLowerCase());
}
}
}

View File

@@ -1,4 +1,4 @@
package im.zhaojun.zfile.model.dto;
package im.zhaojun.zfile.model.support;
import java.io.Serializable;

View File

@@ -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,13 @@ public interface DriverConfigRepository extends JpaRepository<DriveConfig, Integ
* @param type
* 存储类型
*
* @return 指定存储类型的存储
* @return 指定存储类型的驱动
*/
List<DriveConfig> findByType(StorageTypeEnum type);
@Modifying
@Query(value="update DRIVER_CONFIG set orderNum = :orderNum where id = :id")
void updateSetOrderNumById(Integer orderNum, Integer id);
}

View File

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

View File

@@ -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;
/**
@@ -23,13 +21,7 @@ import java.util.List;
@Configuration
@EnableScheduling
@Slf4j
public class GlobalScheduleTask {
@Resource
private OneDriveServiceImpl oneDriveServiceImpl;
@Resource
private OneDriveChinaServiceImpl oneDriveChinaServiceImpl;
public class OneDriveTokenRefreshSchedule {
@Resource
private DriveConfigService driveConfigService;
@@ -54,17 +46,17 @@ public class GlobalScheduleTask {
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);
}
}

View File

@@ -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;

View File

@@ -1,8 +1,12 @@
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;
import im.zhaojun.zfile.model.dto.StorageStrategyConfig;
import im.zhaojun.zfile.model.entity.DriveConfig;
@@ -11,9 +15,10 @@ import im.zhaojun.zfile.model.enums.StorageTypeEnum;
import im.zhaojun.zfile.repository.DriverConfigRepository;
import im.zhaojun.zfile.repository.StorageConfigRepository;
import im.zhaojun.zfile.service.base.AbstractBaseFileService;
import im.zhaojun.zfile.context.DriveContext;
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;
@@ -21,6 +26,7 @@ import javax.annotation.Resource;
import java.lang.reflect.Field;
import java.util.List;
import java.util.Objects;
import java.util.Set;
/**
* 驱动器 Service 类
@@ -39,6 +45,9 @@ public class DriveConfigService {
@Resource
private DriveContext driveContext;
@Resource
private ZFileCache zFileCache;
public static final Class<StorageStrategyConfig> STORAGE_STRATEGY_CONFIG_CLASS = StorageStrategyConfig.class;
/**
@@ -47,10 +56,24 @@ public class DriveConfigService {
* @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);
}
/**
* 获取指定驱动器设置
*
@@ -60,7 +83,7 @@ public class DriveConfigService {
* @return 驱动器设置
*/
public DriveConfig findById(Integer id) {
return driverConfigRepository.getOne(id);
return driverConfigRepository.findById(id).orElse(null);
}
@@ -95,9 +118,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);
}
}
@@ -115,18 +136,27 @@ public class DriveConfigService {
* @return 驱动器对应的存储策略.
*/
public StorageTypeEnum findStorageTypeById(Integer id) {
// return findById(id).getType();
return driverConfigRepository.findById(id).get().getType();
}
/**
* 新增或设置驱动器设置
* @param driveConfig 驱动器设置
* @return 保存后的驱动器设置
*/
public DriveConfig saveOrUpdate(DriveConfig driveConfig) {
return 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;
@@ -161,20 +191,25 @@ 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());
}
}
@@ -186,9 +221,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);
}
}
@@ -198,7 +244,7 @@ public class DriveConfigService {
* @param type
* 存储类型
*
* @return 指定存储类型的存储
* @return 指定存储类型的驱动
*/
public List<DriveConfig> findByType(StorageTypeEnum type) {
return driverConfigRepository.findByType(type);
@@ -221,4 +267,109 @@ public class DriveConfigService {
driverConfigRepository.save(driveConfig);
}
}
/**
* 更新指定驱动器的缓存启用状态
*
* @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
* 驱动器 ID
* @return 缓存信息
*/
public CacheInfoDTO findCacheInfo(Integer driveId) {
int hitCount = zFileCache.getHitCount(driveId);
int missCount = zFileCache.getMissCount(driveId);
Set<String> keys = zFileCache.keySet(driveId);
int cacheCount = keys.size();
return new CacheInfoDTO(cacheCount, hitCount, missCount, keys);
}
/**
* 刷新指定 key 的缓存:
* 1. 清空此 key 的缓存.
* 2. 重新调用方法写入缓存.
*
* @param driveId
* 驱动器 ID
*
* @param key
* 缓存 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.get(driveId);
baseFileService.fileList(key);
}
/**
* 开启缓存自动刷新
*
* @param driveId
* 驱动器 ID
*/
public void startAutoCacheRefresh(Integer driveId) {
DriveConfig driveConfig = findById(driveId);
driveConfig.setAutoRefreshCache(true);
driverConfigRepository.save(driveConfig);
zFileCache.startAutoCacheRefresh(driveId);
}
/**
* 停止缓存自动刷新
*
* @param driveId
* 驱动器 ID
*/
public void stopAutoCacheRefresh(Integer driveId) {
DriveConfig driveConfig = findById(driveId);
driveConfig.setAutoRefreshCache(false);
driverConfigRepository.save(driveConfig);
zFileCache.stopAutoCacheRefresh(driveId);
}
/**
* 清理缓存
*
* @param driveId
* 驱动器 ID
*/
public void clearCache(Integer driveId) {
zFileCache.clear(driveId);
}
/**
* 交换驱动器排序
*/
@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"));
}
}
}

View File

@@ -0,0 +1,74 @@
package im.zhaojun.zfile.service;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ReUtil;
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.Path;
import java.nio.file.PathMatcher;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
/**
* @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;
}
}

View File

@@ -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;
}

View File

@@ -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;
// }
//
// }

View File

@@ -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 初始化所需的参数列表
*/
@@ -140,21 +134,6 @@ public abstract class AbstractBaseFileService implements BaseFileService {
}
/**
* 刷新指定 key 的缓存:
* 1. 清空此 key 的缓存.
* 2. 重新调用方法写入缓存.
*
* @param key
* 缓存 key (文件夹名称)
*/
public void refreshCache(String key) throws Exception {
zFileCache.remove(driveId, key);
BaseFileService currentFileService = (BaseFileService) AopContext.currentProxy();
currentFileService.fileList(key);
}
/**
* 获取单个文件信息
*

View File

@@ -20,7 +20,6 @@ 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;
@@ -136,7 +135,7 @@ public abstract class AbstractOneDriveServiceBase extends AbstractBaseFileServic
try {
root = oneDriveRestTemplate.exchange(requestUrl, HttpMethod.GET, entity, JSONObject.class, getGraphEndPoint(), fullPath).getBody();
} catch (HttpClientErrorException e) {
log.debug("调用 OneDrive 时出现了网络异常: {} , 已尝试重新刷新 token 后再试.", e.getMessage());
log.debug("调用 OneDrive 时出现了网络异常, 已尝试重新刷新 token 后再试.", e);
refreshOneDriveToken();
root = oneDriveRestTemplate.exchange(requestUrl, HttpMethod.GET, entity, JSONObject.class, getGraphEndPoint(), fullPath).getBody();
}
@@ -177,8 +176,6 @@ public abstract class AbstractOneDriveServiceBase extends AbstractBaseFileServic
String fullPath = StringUtils.getFullPath(basePath, path);
String requestUrl;
HttpHeaders headers = new HttpHeaders();
headers.set("driveId", driveId.toString());
HttpEntity<Object> entity = new HttpEntity<>(headers);
@@ -206,16 +203,41 @@ public abstract class AbstractOneDriveServiceBase extends AbstractBaseFileServic
}
/**
* 获取 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() {

View File

@@ -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();
}
}

View File

@@ -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);
}
}

View File

@@ -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;
}
}

View File

@@ -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", "基路径"));
}};
}
}

View File

@@ -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
}};
}
}

View File

@@ -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() {
@@ -144,4 +150,5 @@ public class LocalServiceImpl extends AbstractBaseFileService implements BaseFil
add(new StorageConfig("filePath", "文件路径"));
}};
}
}

View File

@@ -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;
}
}

View File

@@ -41,23 +41,20 @@ 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;
}
}

View File

@@ -41,23 +41,20 @@ 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;
}
}
@@ -100,4 +97,5 @@ public class OneDriveServiceImpl extends AbstractOneDriveServiceBase implements
public String getScope() {
return scope;
}
}

View File

@@ -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;
}
}

View File

@@ -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", "是否是私有空间"));
}};
}
}

View File

@@ -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", "是否是私有空间"));
}};
}
}

View File

@@ -17,4 +17,4 @@ public class UFileServiceImpl extends UpYunServiceImpl {
return StorageTypeEnum.UFILE;
}
}
}

View File

@@ -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) {

View File

@@ -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);

View File

@@ -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);
}
}

View File

@@ -5,20 +5,10 @@
"type": "java.lang.Long",
"description": "目录缓存过期时间 和 下载地址过期时间. 单位为秒."
},
{
"name": "zfile.cache.auto-refresh.enable",
"type": "java.lang.Boolean",
"description": "是否开启自动刷新缓存."
},
{
"name": "zfile.cache.auto-refresh.delay",
"type": "java.lang.Long",
"description": "启动项目后多久开始自动刷新缓存, 推荐与 interval 一致, 因为项目启动时会缓存所有文件. 单位为秒.."
},
{
"name": "zfile.cache.auto-refresh.interval",
"type": "java.lang.Long",
"description": "任务间隔时间, 也就是每多长时间会自动刷新缓存一次.."
"description": "任务间隔时间, 每隔多长时间检测一次到期的缓存 KEY 并自动刷新, 单位为秒."
},
{
"name": "zfile.constant.readme",
@@ -81,6 +71,21 @@
"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": "临时文件路径."
}
]
}

View File

@@ -24,7 +24,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
@@ -50,11 +50,15 @@ spring:
active: prod
zfile:
log:
path: ${user.home}/.zfile/logs
db:
path: ${user.home}/.zfile/db/zfile
tmp:
path: ${user.home}/.zfile/tmp
cache:
# auto-refresh: # 新版本尚未实现此功能
# enable: true # 是否开启自动刷新缓存.
# delay: 1800 # 启动项目后多久开始自动刷新缓存, 推荐与 interval 一致, 因为项目启动时会缓存所有文件.
# interval: 1800 # 任务间隔时间, 也就是每多长时间会自动刷新缓存一次.
auto-refresh:
interval: 1
timeout: 1800
constant:
readme: readme.md
@@ -73,4 +77,4 @@ zfile:
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
scope: offline_access User.Read Files.ReadWrite.All

View File

@@ -14,7 +14,9 @@
converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter"/>
<!-- 定义日志的根目录 -->
<property name="LOG_HOME" value="${user.home}/.zfile/logs"/>
<property resource="application.yml"/>
<springProperty scope="context" name="LOG_HOME" source="zfile.log.path"/>
<!-- 定义日志文件名称 -->
<property name="appName" value="zfile"/>
@@ -27,7 +29,7 @@
</springProfile>
<layout class="ch.qos.logback.classic.PatternLayout">
<pattern>%clr(%d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd HH:mm:ss.SSS}}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}</pattern>
<pattern>%clr(%d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd HH:mm:ss.SSS}}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(%-6L){yellow} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}</pattern>
</layout>
</appender>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1 +0,0 @@
.el-menu[data-v-23e92c9f],.el-row[data-v-23e92c9f]{height:100vh}

View File

@@ -1 +0,0 @@
.login-container[data-v-ec97d092]{width:100%;height:100%}.login-page[data-v-ec97d092]{border-radius:5px;margin:180px auto;width:350px;padding:35px 35px 15px;background:#fff;border:1px solid #eaeaea;-webkit-box-shadow:0 0 25px #cac6c6;box-shadow:0 0 25px #cac6c6}label.el-checkbox.rememberme[data-v-ec97d092]{margin:0 0 15px;text-align:left}

View File

@@ -0,0 +1 @@
.el-menu[data-v-19f6ef89],.el-row[data-v-19f6ef89]{height:100vh}

View File

@@ -1 +0,0 @@
.zfile-header[data-v-5fca0787]{height:48px;line-height:48px!important;background:#fafafa;border-bottom:1px solid rgba(0,0,0,.05);padding-left:30px}.zfile-header .el-breadcrumb[data-v-5fca0787],.zfile-header .el-input[data-v-5fca0787]{line-height:48px}@media only screen and (max-width:767px){.hidden-xs-only{display:none!important}}@media only screen and (min-width:768px){.hidden-sm-and-up{display:none!important}}@media only screen and (min-width:768px) and (max-width:991px){.hidden-sm-only{display:none!important}}@media only screen and (max-width:991px){.hidden-sm-and-down{display:none!important}}@media only screen and (min-width:992px){.hidden-md-and-up{display:none!important}}@media only screen and (min-width:992px) and (max-width:1199px){.hidden-md-only{display:none!important}}@media only screen and (max-width:1199px){.hidden-md-and-down{display:none!important}}@media only screen and (min-width:1200px){.hidden-lg-and-up{display:none!important}}@media only screen and (min-width:1200px) and (max-width:1919px){.hidden-lg-only{display:none!important}}@media only screen and (max-width:1919px){.hidden-lg-and-down{display:none!important}}@media only screen and (min-width:1920px){.hidden-xl-only{display:none!important}}#List[data-v-39c0e91d]{overflow:hidden}.el-table[data-v-39c0e91d]{margin:20px 0 0 20px;padding-right:30px;overflow-y:hidden}.el-table[data-v-39c0e91d]:before{height:0}.el-table svg[data-v-39c0e91d]{font-size:18px;margin-right:15px}#ListTable[data-v-39c0e91d] .table-header-left{margin-left:38px}#ListTable[data-v-39c0e91d] tr{cursor:pointer}.el-scrollbar[data-v-39c0e91d] .el-scrollbar__wrap{overflow-x:hidden!important}#videoDialog[data-v-39c0e91d] .el-dialog__body{padding:10px 0 0 0}#List[data-v-39c0e91d] .el-dialog__header{text-align:center;margin-bottom:-10px;padding:5px 0 5px 0}#videoDialog[data-v-39c0e91d] .el-dialog__headerbtn{top:10px}#textDialog[data-v-39c0e91d] .el-dialog{margin-bottom:0}.v-contextmenu-item[data-v-39c0e91d] label{margin-left:10px}@media screen and (max-device-width:1920px){#videoDialog[data-v-39c0e91d] .el-dialog{margin-top:5vh!important;width:70%!important}}@media screen and (max-device-width:769px){#videoDialog[data-v-39c0e91d] .el-dialog{margin-top:10vh!important;width:90%!important}}.operator-btn[data-v-39c0e91d]{color:#1e9fff;margin-right:20px;font-size:16px}#app{font-family:Helvetica Neue,Helvetica,PingFang SC,Hiragino Sans GB,Microsoft YaHei,"\5FAE\8F6F\96C5\9ED1",Arial,sans-serif;font-size:16px;line-height:1.5;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;color:#2c3e50;overflow-x:hidden}body{margin:unset}.icon,body{overflow:hidden}.icon{width:1em;height:1em;vertical-align:-.15em;fill:currentColor}::-webkit-scrollbar{width:6px;height:8px;background:rgba(144,147,153,.3)}::-webkit-scrollbar-button:vertical{display:none}::-webkit-scrollbar-corner,::-webkit-scrollbar-track{background-color:#e2e2e2}::-webkit-scrollbar-thumb{border-radius:8px;background-color:#a6a6a6}::-webkit-scrollbar-thumb:vertical:hover{background-color:#7f7f7f}::-webkit-scrollbar-thumb:vertical:active{background-color:rgba(0,0,0,.38)}.center-box-card{width:1100px;margin:0 auto}.markdown-body{height:300px;overflow-y:auto;padding:0!important;min-width:100%!important}.alert{background-color:#f4f4f5;color:#909399;font-size:12px;margin:0 0 0;width:100%;padding:10px 16px;-webkit-box-sizing:border-box;box-sizing:border-box;border-radius:4px;position:relative;overflow:hidden;opacity:1;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-transition:opacity .2s;transition:opacity .2s}

View File

@@ -0,0 +1 @@
.zfile-word-aux[data-v-8ff29128]{margin-left:20px;color:#aaa}.el-row[data-v-8ff29128]{padding:20px}.el-form-item[data-v-8ff29128]{margin-right:50px}.card-title[data-v-8ff29128]{color:rgba(0,0,0,.45);font-size:14px}.card-content[data-v-8ff29128]{color:rgba(0,0,0,.85);font-size:25px;line-height:30px}.card-title-button[data-v-8ff29128]{float:right;padding:3px 0}.table-search-input[data-v-8ff29128]{width:300px;float:right}#filterForm .el-row[data-v-8ff29128]{padding:0}

View File

@@ -1 +0,0 @@
.markdown-body[data-v-271433d0]{padding:20px!important}.scroll[data-v-271433d0]{height:100vh;overflow-y:auto}

View File

@@ -0,0 +1 @@
.zfile-login[data-v-3671c5e6]{width:100%;height:100%}.zfile-login-title[data-v-3671c5e6]{text-align:center}.zfile-login-form[data-v-3671c5e6]{border-radius:5px;margin:180px auto;width:350px;padding:35px 35px 15px;background:#fff;border:1px solid #eaeaea;-webkit-box-shadow:0 0 25px #cac6c6;box-shadow:0 0 25px #cac6c6}

View File

@@ -0,0 +1 @@
.zfile-markdown-body[data-v-7eaf2a28]{padding:20px!important}.scroll[data-v-7eaf2a28]{height:100vh;overflow-y:auto}

View File

@@ -1 +0,0 @@
.zfile-word-aux[data-v-6b54edde]{margin-left:20px;color:#aaa}

View File

@@ -0,0 +1 @@
.zfile-header[data-v-6cac5cc6]{height:48px;line-height:48px!important;background:#fafafa;border-bottom:1px solid rgba(0,0,0,.05);padding-left:30px}.zfile-header .el-breadcrumb[data-v-6cac5cc6],.zfile-header .el-input[data-v-6cac5cc6]{line-height:48px}@media only screen and (max-width:767px){.hidden-xs-only,.zfile-header[data-v-6cac5cc6] .el-breadcrumb__separator{display:none!important}}@media only screen and (min-width:768px){.hidden-sm-and-up{display:none!important}}@media only screen and (min-width:768px) and (max-width:991px){.hidden-sm-only{display:none!important}}@media only screen and (max-width:991px){.hidden-sm-and-down{display:none!important}}@media only screen and (min-width:992px){.hidden-md-and-up{display:none!important}}@media only screen and (min-width:992px) and (max-width:1199px){.hidden-md-only{display:none!important}}@media only screen and (max-width:1199px){.hidden-md-and-down{display:none!important}}@media only screen and (min-width:1200px){.hidden-lg-and-up{display:none!important}}@media only screen and (min-width:1200px) and (max-width:1919px){.hidden-lg-only{display:none!important}}@media only screen and (max-width:1919px){.hidden-lg-and-down{display:none!important}}@media only screen and (min-width:1920px){.hidden-xl-only{display:none!important}}#List[data-v-7432d45b]{overflow:hidden}.el-table[data-v-7432d45b]{margin:20px 0 0 20px;padding-right:30px;overflow-y:hidden}.el-table[data-v-7432d45b]:before{height:0}.el-table svg[data-v-7432d45b]{font-size:18px;margin-right:15px}#ListTable[data-v-7432d45b] .table-header-left{margin-left:38px}#ListTable[data-v-7432d45b] tr{cursor:pointer}.el-scrollbar[data-v-7432d45b] .el-scrollbar__wrap{overflow-x:hidden!important}#videoDialog[data-v-7432d45b] .el-dialog__body{padding:10px 0 0 0}#List[data-v-7432d45b] .el-dialog__header{text-align:center;margin-bottom:-10px;padding:5px 0 5px 0}#videoDialog[data-v-7432d45b] .el-dialog__headerbtn{top:10px}#textDialog[data-v-7432d45b] .el-dialog{margin-bottom:0}.v-contextmenu-item[data-v-7432d45b] label{margin-left:10px}@media screen and (max-device-width:1920px){#videoDialog[data-v-7432d45b] .el-dialog{margin-top:5vh!important;width:70%!important}}@media screen and (max-device-width:769px){#videoDialog[data-v-7432d45b] .el-dialog{margin-top:10vh!important;width:90%!important}}.operator-btn[data-v-7432d45b]{color:#1e9fff;margin-right:20px;font-size:16px}body{overflow:hidden}.zfile-readme-center{width:1100px;margin:0 auto}.zfile-markdown-body{height:300px;overflow-y:auto;padding:0!important;min-width:100%!important}.zfile-header-announcement{background-color:#f4f4f5;color:#909399;font-size:12px;margin:0 0 0;width:100%;padding:10px 16px;-webkit-box-sizing:border-box;box-sizing:border-box;border-radius:4px;position:relative;overflow:hidden;opacity:1;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-transition:opacity .2s;-webkit-transition:opacity 10s;transition:opacity 10s}.icon{width:1em;height:1em;vertical-align:-.15em;fill:currentColor;overflow:hidden}::-webkit-scrollbar{width:6px;height:8px;background:rgba(144,147,153,.3)}::-webkit-scrollbar-button:vertical{display:none}::-webkit-scrollbar-corner,::-webkit-scrollbar-track{background-color:#e2e2e2}::-webkit-scrollbar-thumb{border-radius:8px;background-color:#a6a6a6}::-webkit-scrollbar-thumb:vertical:hover{background-color:#7f7f7f}::-webkit-scrollbar-thumb:vertical:active{background-color:rgba(0,0,0,.38)}

View File

@@ -1 +1 @@
<!DOCTYPE html><html><head><meta charset=utf-8><meta http-equiv=X-UA-Compatible content="IE=edge"><meta name=viewport content="width=device-width,initial-scale=1"><link rel=icon href=/favicon.ico><title></title><link href=/css/chunk-02f22860.feb62c82.css rel=prefetch><link href=/css/chunk-049ad60c.8d1c3f59.css rel=prefetch><link href=/css/chunk-06f6e882.4c106b9d.css rel=prefetch><link href=/css/chunk-07a35882.0e88456f.css rel=prefetch><link href=/css/chunk-2136f455.1ba478f4.css rel=prefetch><link href=/css/chunk-227db9c4.091f6ac0.css rel=prefetch><link href=/css/chunk-361b31cc.434c5719.css rel=prefetch><link href=/css/chunk-45cf82c0.2c8124b0.css rel=prefetch><link href=/css/chunk-4c69887f.7aac81e0.css rel=prefetch><link href=/css/chunk-6a2760fc.50f63948.css rel=prefetch><link href=/css/chunk-cf5906ce.d5432c19.css rel=prefetch><link href=/css/chunk-d1e104d6.ecae5695.css rel=prefetch><link href=/css/chunk-e753ba4a.ccd07028.css rel=prefetch><link href=/css/chunk-f1b5112e.d30178ad.css rel=prefetch><link href=/js/chunk-02f22860.1fa0c7f9.js rel=prefetch><link href=/js/chunk-049ad60c.0b1b3166.js rel=prefetch><link href=/js/chunk-06f6e882.fc195f68.js rel=prefetch><link href=/js/chunk-07a35882.781f33fb.js rel=prefetch><link href=/js/chunk-2136f455.e499e949.js rel=prefetch><link href=/js/chunk-227db9c4.0342e2c8.js rel=prefetch><link href=/js/chunk-2d0a43df.0bb25464.js rel=prefetch><link href=/js/chunk-2d0e57ec.56324ec2.js rel=prefetch><link href=/js/chunk-361b31cc.ec6b72b5.js rel=prefetch><link href=/js/chunk-45cf82c0.8f119c4a.js rel=prefetch><link href=/js/chunk-4c69887f.a7bdc194.js rel=prefetch><link href=/js/chunk-6a2760fc.071a3677.js rel=prefetch><link href=/js/chunk-cf5906ce.6b80535b.js rel=prefetch><link href=/js/chunk-d1e104d6.5ae45d97.js rel=prefetch><link href=/js/chunk-e753ba4a.79e89cf6.js rel=prefetch><link href=/js/chunk-f1b5112e.c2c62934.js rel=prefetch><link href=/css/app.34f4cf05.css rel=preload as=style><link href=/css/chunk-vendors.1f2b3e18.css rel=preload as=style><link href=/js/app.cf7e02ab.js rel=preload as=script><link href=/js/chunk-vendors.47b7f6a4.js rel=preload as=script><link href=/css/chunk-vendors.1f2b3e18.css rel=stylesheet><link href=/css/app.34f4cf05.css rel=stylesheet></head><body><noscript><strong>We're sorry but zfile doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id=app></div><script src=/js/chunk-vendors.47b7f6a4.js></script><script src=/js/app.cf7e02ab.js></script></body></html>
<!DOCTYPE html><html><head><meta charset=utf-8><meta http-equiv=X-UA-Compatible content="IE=edge"><meta name=viewport content="width=device-width,initial-scale=1"><link rel=icon href=/favicon.ico><title></title><link href=/css/chunk-049ad60c.8d1c3f59.css rel=prefetch><link href=/css/chunk-07a35882.0e88456f.css rel=prefetch><link href=/css/chunk-31cb73ed.ff2b080b.css rel=prefetch><link href=/css/chunk-361b31cc.434c5719.css rel=prefetch><link href=/css/chunk-445c476e.7be97d9b.css rel=prefetch><link href=/css/chunk-4c69887f.7aac81e0.css rel=prefetch><link href=/css/chunk-60db0096.8f6b58b7.css rel=prefetch><link href=/css/chunk-6a9b9031.b4a493ec.css rel=prefetch><link href=/css/chunk-c1d518da.d961cbe4.css rel=prefetch><link href=/css/chunk-cd60f930.3a6ecbc6.css rel=prefetch><link href=/css/chunk-cf5906ce.d5432c19.css rel=prefetch><link href=/css/chunk-d1e104d6.ecae5695.css rel=prefetch><link href=/css/chunk-e9b21f10.b59e08c0.css rel=prefetch><link href=/css/chunk-f1b5112e.d30178ad.css rel=prefetch><link href=/js/chunk-049ad60c.63f517c2.js rel=prefetch><link href=/js/chunk-07a35882.a59c34dd.js rel=prefetch><link href=/js/chunk-2d0a43df.0bb25464.js rel=prefetch><link href=/js/chunk-2d0e57ec.56324ec2.js rel=prefetch><link href=/js/chunk-31cb73ed.6701ac0f.js rel=prefetch><link href=/js/chunk-361b31cc.14ea9ecc.js rel=prefetch><link href=/js/chunk-445c476e.ad85292f.js rel=prefetch><link href=/js/chunk-4c69887f.80444a3c.js rel=prefetch><link href=/js/chunk-60db0096.8103337b.js rel=prefetch><link href=/js/chunk-6a9b9031.ffae9f45.js rel=prefetch><link href=/js/chunk-c1d518da.eaf9a37a.js rel=prefetch><link href=/js/chunk-cd60f930.756c1289.js rel=prefetch><link href=/js/chunk-cf5906ce.7121596b.js rel=prefetch><link href=/js/chunk-d1e104d6.eca2459a.js rel=prefetch><link href=/js/chunk-e9b21f10.cb207be5.js rel=prefetch><link href=/js/chunk-f1b5112e.d5882604.js rel=prefetch><link href=/css/app.5b36629d.css rel=preload as=style><link href=/css/chunk-vendors.f28a77e6.css rel=preload as=style><link href=/js/app.677ab7e5.js rel=preload as=script><link href=/js/chunk-vendors.1269c628.js rel=preload as=script><link href=/css/chunk-vendors.f28a77e6.css rel=stylesheet><link href=/css/app.5b36629d.css rel=stylesheet></head><body><noscript><strong>We're sorry but zfile doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id=app></div><script src=/js/chunk-vendors.1269c628.js></script><script src=/js/app.677ab7e5.js></script></body></html>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1 +0,0 @@
(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["chunk-02f22860"],{2448:function(t,e,i){},"30d5":function(t,e,i){"use strict";var s=i("2448"),a=i.n(s);a.a},adf4:function(t,e,i){"use strict";i.r(e);var s=function(){var t=this,e=t.$createElement,i=t._self._c||e;return i("el-row",[i("el-col",{attrs:{span:3}},[i("el-menu",{staticClass:"el-menu-vertical-demo",attrs:{"default-active":"/admin"!==this.$route.path?this.$route.path:"/admin/site",router:!0}},[i("el-menu-item",{attrs:{index:"/admin/site"}},[i("i",{staticClass:"el-icon-setting"}),i("span",{attrs:{slot:"title"},slot:"title"},[t._v("基本设置")])]),i("el-menu-item",{attrs:{index:"/admin/drive-list"}},[i("i",{staticClass:"el-icon-folder-opened"}),i("span",{attrs:{slot:"title"},slot:"title"},[t._v("驱动器列表")])]),i("el-menu-item",{attrs:{index:"/admin/view"}},[i("i",{staticClass:"el-icon-view"}),i("span",{attrs:{slot:"title"},slot:"title"},[t._v("显示设置")])]),i("el-menu-item",{attrs:{index:"/admin/password"}},[i("i",{staticClass:"el-icon-key"}),i("span",{attrs:{slot:"title"},slot:"title"},[t._v("修改密码")])]),i("el-menu-item",{attrs:{index:"/admin/api"}},[i("i",{staticClass:"el-icon-document"}),i("span",{attrs:{slot:"title"},slot:"title"},[t._v("API 文档")])]),i("el-menu-item",{attrs:{index:"/admin/monitor"}},[i("i",{staticClass:"el-icon-monitor"}),i("span",{attrs:{slot:"title"},slot:"title"},[t._v("系统监控")])]),i("el-menu-item",{on:{click:t.click}},[i("i",{staticClass:"el-icon-s-home"}),i("span",{attrs:{slot:"title"},slot:"title"},[t._v("前往首页")])])],1)],1),i("el-col",{attrs:{span:16}},[i("keep-alive",{attrs:{exclude:"CacheManager,SiteSetting"}},[i("router-view")],1)],1)],1)},a=[],n={name:"Index",data:function(){return{active:"/admin/storage"}},methods:{click:function(){window.open("/","_blank")}}},l=n,o=(i("30d5"),i("2877")),c=Object(o["a"])(l,s,a,!1,null,"23e92c9f",null);e["default"]=c.exports}}]);

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

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