mirror of
https://github.com/zfile-dev/zfile.git
synced 2025-04-19 05:34:52 +00:00
🏗️ 架构调整, 支持多个驱动器.
This commit is contained in:
@@ -1,13 +1,14 @@
|
||||
package im.zhaojun.zfile.core;
|
||||
package im.zhaojun.zfile.aspect;
|
||||
|
||||
import im.zhaojun.zfile.cache.ZFileCache;
|
||||
import im.zhaojun.zfile.model.dto.FileItemDTO;
|
||||
import im.zhaojun.zfile.service.SystemConfigService;
|
||||
import im.zhaojun.zfile.model.entity.DriveConfig;
|
||||
import im.zhaojun.zfile.service.DriveConfigService;
|
||||
import im.zhaojun.zfile.service.base.AbstractBaseFileService;
|
||||
import org.aspectj.lang.ProceedingJoinPoint;
|
||||
import org.aspectj.lang.annotation.Around;
|
||||
import org.aspectj.lang.annotation.Aspect;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
@@ -24,28 +25,41 @@ public class FileListCacheAop {
|
||||
private ZFileCache zFileCache;
|
||||
|
||||
@Resource
|
||||
private SystemConfigService systemConfigService;
|
||||
private DriveConfigService driveConfigService;
|
||||
|
||||
|
||||
/**
|
||||
* 缓存切面, 如果此驱动器开启了缓存, 则从缓存中取数据, 没有开启, 则直接调用方法.
|
||||
*/
|
||||
@Around(value = "execution(public * im.zhaojun.zfile.service.base.AbstractBaseFileService.fileList(..))")
|
||||
public Object around(ProceedingJoinPoint point) throws Throwable {
|
||||
List<FileItemDTO> result;
|
||||
|
||||
// 获取请求路径
|
||||
Object[] args = point.getArgs();
|
||||
String path = String.valueOf(args[0]);
|
||||
|
||||
boolean enableCache = systemConfigService.getEnableCache();
|
||||
// 获取当前驱动器
|
||||
AbstractBaseFileService fileService = ((AbstractBaseFileService) point.getTarget());
|
||||
Integer driveId = fileService.driveId;
|
||||
|
||||
// 判断驱动器是否开启了缓存
|
||||
DriveConfig driveConfig = driveConfigService.findById(driveId);
|
||||
boolean enableCache = driveConfig.getEnableCache();
|
||||
|
||||
if (enableCache) {
|
||||
List<FileItemDTO> cacheFileList = zFileCache.get(path);
|
||||
if (CollectionUtils.isEmpty(cacheFileList)) {
|
||||
List<FileItemDTO> cacheFileList = zFileCache.get(driveId, path);
|
||||
if (cacheFileList == null) {
|
||||
result = (List<FileItemDTO>) point.proceed();
|
||||
zFileCache.put(path, result);
|
||||
zFileCache.put(driveId, path, result);
|
||||
} else {
|
||||
result = cacheFileList;
|
||||
}
|
||||
} else {
|
||||
result = (List<FileItemDTO>) point.proceed();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
210
src/main/java/im/zhaojun/zfile/cache/ZFileCache.java
vendored
210
src/main/java/im/zhaojun/zfile/cache/ZFileCache.java
vendored
@@ -1,85 +1,136 @@
|
||||
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 org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.*;
|
||||
import javax.annotation.Resource;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
|
||||
/**
|
||||
* @author zhaojun
|
||||
* ZFile 缓存类
|
||||
*
|
||||
* @author zhaojun
|
||||
*/
|
||||
@Component
|
||||
public class ZFileCache {
|
||||
|
||||
@Value("${zfile.cache.timeout}")
|
||||
private long timeout;
|
||||
|
||||
|
||||
/**
|
||||
* 缓存 map 对象.
|
||||
*
|
||||
* ConcurrentMap<Integer, ConcurrentHashMap<String, List<FileItemDTO>>>
|
||||
* ConcurrentMap<driveId, ConcurrentHashMap<key, value>>
|
||||
*
|
||||
* driveId: 驱动器 ID
|
||||
* key: 文件夹路径
|
||||
* value: 文件夹中内容
|
||||
*/
|
||||
private ConcurrentMap<String, List<FileItemDTO>> cache = new ConcurrentHashMap<>();
|
||||
private ConcurrentMap<Integer, TimedCache<String, List<FileItemDTO>>> drivesCache = new ConcurrentHashMap<>();
|
||||
|
||||
/**
|
||||
* 系统设置缓存
|
||||
*/
|
||||
private SystemConfigDTO systemConfigCache;
|
||||
|
||||
/**
|
||||
* 缓存最后自动刷新时间
|
||||
*/
|
||||
public Date lastCacheAutoRefreshDate;
|
||||
@Resource
|
||||
private DriverConfigRepository driverConfigRepository;
|
||||
|
||||
|
||||
/**
|
||||
* 写入缓存
|
||||
* @param key 文件夹路径
|
||||
* @param value 文件夹中内容
|
||||
*
|
||||
* @param driveId
|
||||
* 驱动器 ID
|
||||
*
|
||||
* @param key
|
||||
* 文件夹路径
|
||||
*
|
||||
* @param value
|
||||
* 文件夹中列表
|
||||
*/
|
||||
public synchronized void put(String key, List<FileItemDTO> value) {
|
||||
cache.put(key, value);
|
||||
public synchronized void put(Integer driveId, String key, List<FileItemDTO> value) {
|
||||
getCacheByDriveId(driveId).put(key, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据文件夹路径取的环境
|
||||
* @param key 文件夹路径
|
||||
* @return 文件夹中内容
|
||||
*/
|
||||
public List<FileItemDTO> get(String key) {
|
||||
return cache.get(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* 清空缓存.
|
||||
* 获取指定驱动器, 某个文件夹的名称
|
||||
*
|
||||
* @param driveId
|
||||
* 驱动器 ID
|
||||
*
|
||||
* @param key
|
||||
* 文件夹路径
|
||||
*
|
||||
* @return 驱动器中文件夹的内容
|
||||
*/
|
||||
public void clear() {
|
||||
cache.clear();
|
||||
public List<FileItemDTO> get(Integer driveId, String key) {
|
||||
return getCacheByDriveId(driveId).get(key, false);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取已缓存文件夹数量
|
||||
* 清空指定驱动器的缓存.
|
||||
*
|
||||
* @param driveId
|
||||
* 驱动器 ID
|
||||
*/
|
||||
public void clear(Integer driveId) {
|
||||
getCacheByDriveId(driveId).clear();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取指定驱动器中已缓存文件夹数量
|
||||
*
|
||||
* @param driveId
|
||||
* 驱动器 ID
|
||||
*
|
||||
* @return 已缓存文件夹数量
|
||||
*/
|
||||
public int cacheCount() {
|
||||
return cache.size();
|
||||
public int cacheCount(Integer driveId) {
|
||||
return getCacheByDriveId(driveId).size();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 搜索缓存中内容
|
||||
* @param key 搜索键, 可匹配文件夹名称和文件名称.
|
||||
* @param ignoreCase 是否忽略大小写, true 为忽略, false 为不忽略.
|
||||
* @param searchContainEncryptedFile 搜索是否包含加密文件. true 为不包含, false 为包含, 用于控制当文件夹被密码保护时, 是否出现在搜索结果中.
|
||||
* @return 搜索结果, 包含文件夹和文件.
|
||||
* 指定驱动器, 根据文件及文件名查找相关的文件
|
||||
*
|
||||
* @param driveId
|
||||
* 驱动器 ID
|
||||
*
|
||||
* @param key
|
||||
* 搜索键, 可匹配文件夹名称和文件名称.
|
||||
*
|
||||
* @return 搜索结果, 包含文件夹和文件.
|
||||
*/
|
||||
public List<FileItemDTO> find(String key, boolean ignoreCase, boolean searchContainEncryptedFile) {
|
||||
public List<FileItemDTO> find(Integer driveId, String key) {
|
||||
List<FileItemDTO> result = new ArrayList<>();
|
||||
|
||||
Collection<List<FileItemDTO>> values = cache.values();
|
||||
for (List<FileItemDTO> fileItemList : values) {
|
||||
DriveConfig driveConfig = driverConfigRepository.getOne(driveId);
|
||||
boolean searchContainEncryptedFile = driveConfig.getSearchContainEncryptedFile();
|
||||
boolean ignoreCase = driveConfig.getSearchIgnoreCase();
|
||||
|
||||
for (List<FileItemDTO> fileItemList : getCacheByDriveId(driveId)) {
|
||||
// 过滤加密文件
|
||||
if (!searchContainEncryptedFile && isEncryptedFolder(fileItemList)) {
|
||||
continue;
|
||||
@@ -103,38 +154,58 @@ public class ZFileCache {
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取所有缓存 key (文件夹名称)
|
||||
* @return 所有缓存 key
|
||||
*/
|
||||
public Set<String> keySet() {
|
||||
return cache.keySet();
|
||||
}
|
||||
|
||||
/**
|
||||
* 从缓存中删除一个条目
|
||||
* @param key 文件夹名称
|
||||
* 获取所有缓存 key (文件夹名称)
|
||||
*
|
||||
* @return 所有缓存 key
|
||||
*/
|
||||
public void remove(String key) {
|
||||
cache.remove(key);
|
||||
public Set<String> keySet(Integer driveId) {
|
||||
Iterator<CacheObj<String, List<FileItemDTO>>> cacheObjIterator = getCacheByDriveId(driveId).cacheObjIterator();
|
||||
Set<String> keys = new HashSet<>();
|
||||
while (cacheObjIterator.hasNext()) {
|
||||
keys.add(cacheObjIterator.next().getKey());
|
||||
}
|
||||
return keys;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 从缓存中删除指定存储器的某个路径的缓存
|
||||
*
|
||||
* @param driveId
|
||||
* 驱动器 ID
|
||||
*
|
||||
* @param key
|
||||
* 文件夹路径
|
||||
*/
|
||||
public void remove(Integer driveId, String key) {
|
||||
getCacheByDriveId(driveId).remove(key);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 更新缓存中的系统设置
|
||||
* @param systemConfigCache 系统设置
|
||||
*
|
||||
* @param systemConfigCache
|
||||
* 系统设置
|
||||
*/
|
||||
public void updateConfig(SystemConfigDTO systemConfigCache) {
|
||||
this.systemConfigCache = systemConfigCache;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 从获取中获取系统设置
|
||||
* 从缓存中获取系统设置
|
||||
*
|
||||
* @return 系统设置
|
||||
*/
|
||||
public SystemConfigDTO getConfig() {
|
||||
return this.systemConfigCache;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 清空系统设置缓存
|
||||
*/
|
||||
@@ -142,27 +213,14 @@ public class ZFileCache {
|
||||
this.systemConfigCache = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取缓存最后刷新时间
|
||||
* @return 缓存最后刷新时间
|
||||
*/
|
||||
public Date getLastCacheAutoRefreshDate() {
|
||||
return lastCacheAutoRefreshDate;
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新缓存最后刷新时间
|
||||
* @param lastCacheAutoRefreshDate 缓存最后刷新时间
|
||||
*/
|
||||
public void setLastCacheAutoRefreshDate(Date lastCacheAutoRefreshDate) {
|
||||
this.lastCacheAutoRefreshDate = lastCacheAutoRefreshDate;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 判断是否为加密文件夹
|
||||
* @param list 文件夹中的内容
|
||||
* @return 返回此文件夹是否加密.
|
||||
* 判断此文件夹是否为加密文件夹 (包含)
|
||||
*
|
||||
* @param list
|
||||
* 文件夹中的内容
|
||||
*
|
||||
* @return 返回此文件夹是否是加密的 ().
|
||||
*/
|
||||
private boolean isEncryptedFolder(List<FileItemDTO> list) {
|
||||
// 遍历文件判断是否包含
|
||||
@@ -173,4 +231,24 @@ public class ZFileCache {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取指定驱动器对应的缓存
|
||||
*
|
||||
* @param driveId
|
||||
* 驱动器 ID
|
||||
*
|
||||
* @return 驱动器对应的缓存
|
||||
*/
|
||||
private synchronized TimedCache<String, List<FileItemDTO>> getCacheByDriveId(Integer driveId) {
|
||||
TimedCache<String, List<FileItemDTO>> driveCache = drivesCache.get(driveId);
|
||||
if (driveCache == null) {
|
||||
driveCache = CacheUtil.newTimedCache(timeout * 1000);
|
||||
drivesCache.put(driveId, driveCache);
|
||||
}
|
||||
|
||||
return driveCache;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
package im.zhaojun.zfile.config;
|
||||
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpRequest;
|
||||
import org.springframework.http.client.ClientHttpRequestExecution;
|
||||
import org.springframework.http.client.ClientHttpRequestInterceptor;
|
||||
import org.springframework.http.client.ClientHttpResponse;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
|
||||
/**
|
||||
* @author zhaojun
|
||||
*/
|
||||
public class ContentTypeTextToTextJson implements ClientHttpRequestInterceptor {
|
||||
|
||||
@Override
|
||||
public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution)
|
||||
throws IOException {
|
||||
ClientHttpResponse response = execution.execute(request, body);
|
||||
HttpHeaders headers = response.getHeaders();
|
||||
headers.put("Content-Type", Collections.singletonList("application/text"));
|
||||
return response;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,81 +0,0 @@
|
||||
package im.zhaojun.zfile.config;
|
||||
|
||||
import im.zhaojun.zfile.model.enums.StorageTypeEnum;
|
||||
import im.zhaojun.zfile.service.SystemConfigService;
|
||||
import im.zhaojun.zfile.service.base.AbstractBaseFileService;
|
||||
import im.zhaojun.zfile.service.impl.OneDriveChinaServiceImpl;
|
||||
import im.zhaojun.zfile.service.impl.OneDriveServiceImpl;
|
||||
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.Objects;
|
||||
|
||||
/**
|
||||
* @author zhaojun
|
||||
*/
|
||||
@Configuration
|
||||
@EnableScheduling
|
||||
@Slf4j
|
||||
public class GlobalScheduleTask {
|
||||
|
||||
@Resource
|
||||
private OneDriveServiceImpl oneDriveServiceImpl;
|
||||
|
||||
@Resource
|
||||
private OneDriveChinaServiceImpl oneDriveChinaServiceImpl;
|
||||
|
||||
@Resource
|
||||
private SystemConfigService systemConfigService;
|
||||
|
||||
/**
|
||||
* 项目启动 30 秒后, 每 15 分钟执行一次刷新 OneDrive Token 的定时任务.
|
||||
*/
|
||||
@Scheduled(fixedRate = 1000 * 60 * 10, initialDelay = 1000 * 30)
|
||||
public void autoRefreshOneDriveToken() {
|
||||
|
||||
try {
|
||||
log.debug("尝试调用 OneDrive 自动刷新 AccessToken 定时任务");
|
||||
|
||||
AbstractBaseFileService currentFileService = systemConfigService.getCurrentFileService();
|
||||
|
||||
if (!(currentFileService instanceof OneDriveServiceImpl
|
||||
|| currentFileService instanceof OneDriveChinaServiceImpl)) {
|
||||
log.debug("当前启用存储类型, 不是 OneDrive, 跳过自动刷新 AccessToken");
|
||||
return;
|
||||
}
|
||||
|
||||
if (currentFileService.getIsUnInitialized()) {
|
||||
log.debug("当前启用 OneDrive 未初始化成功, 跳过自动刷新 AccessToken");
|
||||
return;
|
||||
}
|
||||
|
||||
StorageTypeEnum currentStorageTypeEnum = currentFileService.getStorageTypeEnum();
|
||||
|
||||
try {
|
||||
refreshOneDriveToken(currentStorageTypeEnum);
|
||||
} catch (Exception e) {
|
||||
log.debug("刷新 " + currentStorageTypeEnum.getDescription() + " Token 失败.", e);
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
log.debug("尝试调用 OneDrive 自动刷新 AccessToken 定时任务出现未知异常", e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 调用刷新 OneDrive Token
|
||||
*/
|
||||
public void refreshOneDriveToken(StorageTypeEnum storageType) {
|
||||
if (Objects.equals(storageType, StorageTypeEnum.ONE_DRIVE_CHINA)) {
|
||||
oneDriveChinaServiceImpl.refreshOneDriveToken();
|
||||
} else {
|
||||
oneDriveServiceImpl.refreshOneDriveToken();
|
||||
}
|
||||
log.info("刷新 {} key 时间: {}", storageType.getDescription(), LocalDateTime.now());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,14 +1,13 @@
|
||||
package im.zhaojun.zfile.config;
|
||||
|
||||
import im.zhaojun.zfile.model.entity.StorageConfig;
|
||||
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.context.annotation.Lazy;
|
||||
import org.springframework.http.client.ClientHttpRequestInterceptor;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
@@ -25,13 +24,15 @@ public class OneDriveConfig {
|
||||
private StorageConfigService storageConfigService;
|
||||
|
||||
@Resource
|
||||
@Lazy
|
||||
private OneDriveServiceImpl oneDriveServiceImpl;
|
||||
|
||||
@Resource
|
||||
@Lazy
|
||||
private OneDriveChinaServiceImpl oneDriveChinaServiceImpl;
|
||||
|
||||
|
||||
/**
|
||||
* OneDrive 请求 RestTemplate, 会在请求头中添加 Bearer: Authorization {token} 信息, 用于 API 认证.
|
||||
*/
|
||||
@Bean
|
||||
public RestTemplate oneDriveRestTemplate() {
|
||||
RestTemplate restTemplate = new RestTemplate();
|
||||
@@ -58,4 +59,4 @@ public class OneDriveConfig {
|
||||
return restTemplate;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -22,10 +22,13 @@ public class WebMvcConfig implements WebMvcConfigurer {
|
||||
@Bean
|
||||
public ServletWebServerFactory webServerFactory() {
|
||||
TomcatServletWebServerFactory webServerFactory = new TomcatServletWebServerFactory();
|
||||
|
||||
// 添加对 URL 中特殊符号的支持.
|
||||
webServerFactory.addConnectorCustomizers(connector -> {
|
||||
connector.setAttribute("relaxedPathChars", "<>[\\]^`{|}");
|
||||
connector.setAttribute("relaxedQueryChars", "<>[\\]^`{|}");
|
||||
});
|
||||
return webServerFactory;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -2,6 +2,8 @@ package im.zhaojun.zfile.config;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.client.ClientHttpResponse;
|
||||
import org.springframework.http.converter.StringHttpMessageConverter;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
@@ -18,7 +20,14 @@ public class ZFileConfiguration {
|
||||
public RestTemplate restTemplate(){
|
||||
RestTemplate restTemplate = new RestTemplate();
|
||||
restTemplate.getMessageConverters().set(1, new StringHttpMessageConverter(StandardCharsets.UTF_8));
|
||||
restTemplate.setInterceptors(Collections.singletonList(new ContentTypeTextToTextJson()));
|
||||
|
||||
restTemplate.setInterceptors(Collections.singletonList((request, body, execution) -> {
|
||||
ClientHttpResponse response = execution.execute(request, body);
|
||||
HttpHeaders headers = response.getHeaders();
|
||||
headers.put("Content-Type", Collections.singletonList("application/text"));
|
||||
return response;
|
||||
}));
|
||||
|
||||
return restTemplate;
|
||||
}
|
||||
|
||||
|
||||
107
src/main/java/im/zhaojun/zfile/context/DriveContext.java
Normal file
107
src/main/java/im/zhaojun/zfile/context/DriveContext.java
Normal file
@@ -0,0 +1,107 @@
|
||||
package im.zhaojun.zfile.context;
|
||||
|
||||
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 org.springframework.beans.BeansException;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
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;
|
||||
|
||||
/**
|
||||
* 驱动器上下文环境
|
||||
* @author zhaojun
|
||||
*/
|
||||
@Component
|
||||
@DependsOn("springContextHolder")
|
||||
public class DriveContext implements ApplicationContextAware {
|
||||
|
||||
private static Map<Integer, AbstractBaseFileService> drivesServiceMap = new ConcurrentHashMap<>();
|
||||
|
||||
private static Map<StorageTypeEnum, Class<AbstractBaseFileService>> storageTypeEnumClassMap = new ConcurrentHashMap<>();
|
||||
|
||||
@Resource
|
||||
private DriveConfigService driveConfigService;
|
||||
|
||||
|
||||
/**
|
||||
* 初始化指定驱动器的 Service, 添加到上下文环境中.
|
||||
*
|
||||
* @param driveId
|
||||
* 驱动器 ID.
|
||||
*/
|
||||
public void initDrive(Integer driveId) {
|
||||
AbstractBaseFileService baseFileService = getBeanByDriveId(driveId);
|
||||
if (baseFileService != null) {
|
||||
baseFileService.init(driveId);
|
||||
drivesServiceMap.put(driveId, baseFileService);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取指定驱动器的 Service.
|
||||
*
|
||||
* @param driveId
|
||||
* 驱动器 ID
|
||||
*
|
||||
* @return 驱动器对应的 Service
|
||||
*/
|
||||
public AbstractBaseFileService getDriveService(Integer driveId) {
|
||||
return drivesServiceMap.get(driveId);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 销毁指定驱动器的 Service.
|
||||
*
|
||||
* @param driveId
|
||||
* 驱动器 ID
|
||||
*/
|
||||
public void destroyDrive(Integer driveId) {
|
||||
drivesServiceMap.remove(driveId);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取指定驱动器对应的 Service, 状态为未初始化
|
||||
*
|
||||
* @param driveId
|
||||
* 驱动器 ID
|
||||
*
|
||||
* @return 驱动器对应未初始化的 Service
|
||||
*/
|
||||
private AbstractBaseFileService getBeanByDriveId(Integer driveId) {
|
||||
StorageTypeEnum storageTypeEnum = driveConfigService.findStorageTypeById(driveId);
|
||||
Map<String, AbstractBaseFileService> beansOfType = SpringContextHolder.getBeansOfType(AbstractBaseFileService.class);
|
||||
for (AbstractBaseFileService value : beansOfType.values()) {
|
||||
if (Objects.equals(value.getStorageTypeEnum(), storageTypeEnum)) {
|
||||
return SpringContextHolder.getBean(value.getClass());
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 项目启动时, 自动调用所有驱动器进行初始化.
|
||||
*/
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
|
||||
List<DriveConfig> list = driveConfigService.list();
|
||||
for (DriveConfig driveConfig : list) {
|
||||
initDrive(driveConfig.getId());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package im.zhaojun.zfile.config;
|
||||
package im.zhaojun.zfile.context;
|
||||
|
||||
import im.zhaojun.zfile.model.enums.StorageTypeEnum;
|
||||
import im.zhaojun.zfile.service.base.AbstractBaseFileService;
|
||||
@@ -6,19 +6,21 @@ import org.springframework.beans.BeansException;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
/**
|
||||
* 存储类型工厂类
|
||||
* @author zhaojun
|
||||
*/
|
||||
@Component
|
||||
public class StorageTypeFactory implements ApplicationContextAware {
|
||||
public class StorageTypeContext implements ApplicationContextAware {
|
||||
|
||||
private static Map<String, AbstractBaseFileService> storageTypeEnumFileServiceMap;
|
||||
|
||||
private static ApplicationContext applicationContext;
|
||||
|
||||
|
||||
/**
|
||||
* 项目启动时执行
|
||||
*/
|
||||
@@ -30,6 +32,7 @@ public class StorageTypeFactory implements ApplicationContextAware {
|
||||
storageTypeEnumFileServiceMap = act.getBeansOfType(AbstractBaseFileService.class);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取指定存储类型 Service
|
||||
*/
|
||||
@@ -44,7 +47,9 @@ public class StorageTypeFactory implements ApplicationContextAware {
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
public static ApplicationContext getApplicationContext() {
|
||||
return applicationContext;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,200 +0,0 @@
|
||||
package im.zhaojun.zfile.controller;
|
||||
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.hutool.core.util.ZipUtil;
|
||||
import im.zhaojun.zfile.config.StorageTypeFactory;
|
||||
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.service.StorageConfigService;
|
||||
import im.zhaojun.zfile.service.SystemConfigService;
|
||||
import im.zhaojun.zfile.service.base.AbstractBaseFileService;
|
||||
import im.zhaojun.zfile.service.support.FileAsyncCacheService;
|
||||
import im.zhaojun.zfile.util.FileUtil;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
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.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.File;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* 后台管理
|
||||
* @author zhaojun
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/admin")
|
||||
public class AdminController {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(AdminController.class);
|
||||
|
||||
@Resource
|
||||
private StorageConfigService storageConfigService;
|
||||
|
||||
@Resource
|
||||
private SystemConfigService systemConfigService;
|
||||
|
||||
@Resource
|
||||
private FileAsyncCacheService fileAsyncCacheService;
|
||||
|
||||
/**
|
||||
* 获取系统配置
|
||||
*/
|
||||
@GetMapping("/config")
|
||||
public ResultBean getConfig() {
|
||||
SystemConfigDTO systemConfigDTO = systemConfigService.getSystemConfig();
|
||||
return ResultBean.success(systemConfigDTO);
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新系统配置
|
||||
*/
|
||||
@PostMapping("/config")
|
||||
public ResultBean updateConfig(SystemConfigDTO systemConfigDTO) throws Exception {
|
||||
StorageTypeEnum currentStorageStrategy = systemConfigService.getCurrentStorageStrategy();
|
||||
if (!Objects.equals(currentStorageStrategy, systemConfigDTO.getStorageStrategy())) {
|
||||
if (systemConfigService.getEnableCache()) {
|
||||
return ResultBean.error("不支持缓存开启状态下, 切换存储策略, 请先手动关闭缓存");
|
||||
}
|
||||
log.info("已将存储策略由 {} 切换为 {}",
|
||||
currentStorageStrategy.getDescription(),
|
||||
systemConfigDTO.getStorageStrategy().getDescription());
|
||||
refreshStorageStrategy();
|
||||
}
|
||||
|
||||
systemConfigDTO.setId(1);
|
||||
systemConfigService.updateSystemConfig(systemConfigDTO);
|
||||
|
||||
return ResultBean.success();
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改管理员登陆密码
|
||||
*/
|
||||
@PostMapping("/update-pwd")
|
||||
public ResultBean updatePwd(String username, String password) {
|
||||
systemConfigService.updateUsernameAndPwd(username, password);
|
||||
return ResultBean.success();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取指定存储策略的设置
|
||||
* @param storageType 存储策略
|
||||
* @return 所有设置
|
||||
*/
|
||||
@GetMapping("/strategy-form")
|
||||
public ResultBean getFormByStorageType(StorageTypeEnum storageType) {
|
||||
List<StorageConfig> storageConfigList = storageConfigService.selectStorageConfigByType(storageType);
|
||||
return ResultBean.success(storageConfigList);
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回支持的存储引擎.
|
||||
*/
|
||||
@GetMapping("/support-strategy")
|
||||
public ResultBean supportStrategy() {
|
||||
List<StorageStrategyDTO> result = new ArrayList<>();
|
||||
StorageTypeEnum[] values = StorageTypeEnum.values();
|
||||
for (StorageTypeEnum value : values) {
|
||||
AbstractBaseFileService storageTypeService = StorageTypeFactory.getStorageTypeService(value);
|
||||
result.add(new StorageStrategyDTO(value.getKey(),
|
||||
value.getDescription(),
|
||||
storageTypeService.getIsInitialized()));
|
||||
}
|
||||
return ResultBean.successData(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存存储策略
|
||||
* @param storageStrategyConfig 保存表单值
|
||||
* @param storageStrategy 所属策略
|
||||
* @return 操作结果
|
||||
*/
|
||||
@PostMapping("/storage-strategy")
|
||||
public ResultBean save(@RequestParam Map<String, String> storageStrategyConfig, StorageTypeEnum storageStrategy) {
|
||||
// 保存设置.
|
||||
List<StorageConfig> storageConfigList = storageConfigService.selectStorageConfigByType(storageStrategy);
|
||||
for (StorageConfig storageConfig : storageConfigList) {
|
||||
String key = storageConfig.getKey();
|
||||
String value = storageStrategyConfig.get(key);
|
||||
storageConfig.setValue(value);
|
||||
}
|
||||
storageConfigService.updateStorageConfig(storageConfigList);
|
||||
|
||||
// 获取当前修改的存储策略 Service, 尝试调用初始化.
|
||||
AbstractBaseFileService updateStorageStrategyService = StorageTypeFactory.getStorageTypeService(storageStrategy);
|
||||
updateStorageStrategyService.init();
|
||||
|
||||
// 如果修改的为当前启用的缓存, 则重新进行缓存.
|
||||
StorageTypeEnum currentStorageStrategy = systemConfigService.getCurrentStorageStrategy();
|
||||
if (Objects.equals(storageStrategy, currentStorageStrategy)) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("检测到更新了当前启用的存储策略 {}, 已清理缓存.", currentStorageStrategy);
|
||||
}
|
||||
|
||||
AbstractBaseFileService fileService = systemConfigService.getCurrentFileService();
|
||||
fileService.clearFileCache();
|
||||
fileAsyncCacheService.cacheGlobalFile();
|
||||
}
|
||||
|
||||
// 返回是否初始化成功.
|
||||
if (updateStorageStrategyService.getIsInitialized()) {
|
||||
return ResultBean.success();
|
||||
} else {
|
||||
return ResultBean.error("保存成功, 但尝试初始化异常, 请检查设置.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新存储策略
|
||||
*/
|
||||
public void refreshStorageStrategy() {
|
||||
StorageTypeEnum storageStrategy = systemConfigService.getCurrentStorageStrategy();
|
||||
refreshStorageStrategy(storageStrategy);
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新存储策略
|
||||
*/
|
||||
private void refreshStorageStrategy(StorageTypeEnum storageStrategy) {
|
||||
if (storageStrategy == null) {
|
||||
log.info("尚未配置存储策略.");
|
||||
} else {
|
||||
AbstractBaseFileService fileService = systemConfigService.getCurrentFileService();
|
||||
fileService.init();
|
||||
fileService.clearFileCache();
|
||||
log.info("切换至存储类型: {}", storageStrategy.getDescription());
|
||||
fileAsyncCacheService.cacheGlobalFile();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 系统日志下载
|
||||
*/
|
||||
@GetMapping("/log")
|
||||
public ResponseEntity<Object> downloadLog(HttpServletResponse response) {
|
||||
String userHome = System.getProperty("user.home");
|
||||
File fileZip = ZipUtil.zip(userHome + "/.zfile/logs");
|
||||
String currentDate = DateUtil.format(new Date(), "yyyy-MM-dd HH:mm:ss");
|
||||
return FileUtil.export(fileZip, "ZFile 诊断日志 - " + currentDate + ".zip");
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取系统监控信息
|
||||
*/
|
||||
@GetMapping("monitor")
|
||||
public ResultBean monitor() {
|
||||
return ResultBean.success(new SystemMonitorInfo());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,84 +0,0 @@
|
||||
package im.zhaojun.zfile.controller;
|
||||
|
||||
import im.zhaojun.zfile.cache.ZFileCache;
|
||||
import im.zhaojun.zfile.model.dto.CacheConfigDTO;
|
||||
import im.zhaojun.zfile.model.dto.ResultBean;
|
||||
import im.zhaojun.zfile.service.SystemConfigService;
|
||||
import im.zhaojun.zfile.service.base.AbstractBaseFileService;
|
||||
import im.zhaojun.zfile.service.support.FileAsyncCacheService;
|
||||
import im.zhaojun.zfile.service.support.FileCacheService;
|
||||
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;
|
||||
|
||||
/**
|
||||
* @author zhaojun
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/admin/cache")
|
||||
public class CacheController {
|
||||
|
||||
@Resource
|
||||
private SystemConfigService systemConfigService;
|
||||
|
||||
@Resource
|
||||
private FileAsyncCacheService fileAsyncCacheService;
|
||||
|
||||
@Resource
|
||||
private FileCacheService fileCacheService;
|
||||
|
||||
@Resource
|
||||
private ZFileCache zFileCache;
|
||||
|
||||
@PostMapping("/enable")
|
||||
public ResultBean enableCache() {
|
||||
fileCacheService.enableCache();
|
||||
return ResultBean.success();
|
||||
}
|
||||
|
||||
@PostMapping("/disable")
|
||||
public ResultBean disableCache() {
|
||||
fileCacheService.disableCache();
|
||||
return ResultBean.success();
|
||||
}
|
||||
|
||||
@GetMapping("/config")
|
||||
public ResultBean cacheConfig() {
|
||||
CacheConfigDTO cacheConfigDTO = new CacheConfigDTO();
|
||||
cacheConfigDTO.setEnableCache(systemConfigService.getEnableCache());
|
||||
cacheConfigDTO.setCacheFinish(fileAsyncCacheService.isCacheFinish());
|
||||
cacheConfigDTO.setCacheKeys(zFileCache.keySet());
|
||||
cacheConfigDTO.setCacheDirectoryCount(zFileCache.cacheCount());
|
||||
cacheConfigDTO.setLastCacheAutoRefreshDate(zFileCache.getLastCacheAutoRefreshDate());
|
||||
return ResultBean.success(cacheConfigDTO);
|
||||
}
|
||||
|
||||
|
||||
@PostMapping("/refresh")
|
||||
public ResultBean refreshCache(String key) throws Exception {
|
||||
AbstractBaseFileService fileService = systemConfigService.getCurrentFileService();
|
||||
fileService.refreshCache(key);
|
||||
return ResultBean.success();
|
||||
}
|
||||
|
||||
/*
|
||||
@PostMapping("/clear")
|
||||
public ResultBean clearCache(String key) {
|
||||
AbstractFileService fileService = systemConfigService.getCurrentFileService();
|
||||
fileService.clearFileCache();
|
||||
return ResultBean.success();
|
||||
}
|
||||
|
||||
|
||||
@PostMapping("/all")
|
||||
public ResultBean cacheAll() {
|
||||
AbstractFileService fileService = systemConfigService.getCurrentFileService();
|
||||
fileService.clearFileCache();
|
||||
fileAsyncCacheService.cacheGlobalFile();
|
||||
return ResultBean.success();
|
||||
}
|
||||
*/
|
||||
}
|
||||
@@ -9,21 +9,32 @@ import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
/**
|
||||
* 公共 Controller
|
||||
* @author zhaojun
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/common")
|
||||
public class CommonController {
|
||||
|
||||
|
||||
/**
|
||||
* 返回系统支持的所有存储策略
|
||||
*
|
||||
* @return 存储策略
|
||||
*/
|
||||
@GetMapping("/support-strategy")
|
||||
public ResultBean supportStrategy() {
|
||||
return ResultBean.successData(StorageTypeEnum.values());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取文件内容, 仅限用于, txt, md, ini 等普通文本文件.
|
||||
* @param url 文件路径
|
||||
* @return 文件内容
|
||||
* 获取文件内容, 仅限用于 txt, md, ini 等普通文本文件.
|
||||
*
|
||||
* @param url
|
||||
* 文件路径
|
||||
*
|
||||
* @return 文件内容
|
||||
*/
|
||||
@GetMapping("/content")
|
||||
public ResultBean getContent(String url) {
|
||||
@@ -31,35 +42,17 @@ public class CommonController {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取文件内容, 仅限用于, txt, md, ini 等普通文本文件.
|
||||
* @param url 文件路径
|
||||
* @return 文件内容
|
||||
*/
|
||||
@GetMapping("/content/origin")
|
||||
public String getContentOrigin(String url) {
|
||||
return HttpUtil.getTextContent(url);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 检测文件是否存在
|
||||
* @param url 文件路径
|
||||
* @return 是否存在
|
||||
*/
|
||||
@GetMapping("/content/exist")
|
||||
public boolean checkFileExist(String url) {
|
||||
return HttpUtil.checkUrlExist(url);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取音频文件信息
|
||||
* @param url 文件 URL
|
||||
* @return 音频信息, 标题封面等信息
|
||||
*
|
||||
* @param url
|
||||
* 文件 URL
|
||||
*
|
||||
* @return 音频信息, 标题封面等信息
|
||||
*/
|
||||
@GetMapping("/audio-info")
|
||||
public ResultBean getAudioInfo(String url) throws Exception {
|
||||
return ResultBean.success(AudioHelper.getAudioInfo(url));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,31 +1,31 @@
|
||||
package im.zhaojun.zfile.controller;
|
||||
|
||||
import cn.hutool.core.util.BooleanUtil;
|
||||
import cn.hutool.core.util.URLUtil;
|
||||
import im.zhaojun.zfile.model.annotation.CheckStorageStrategyInit;
|
||||
import im.zhaojun.zfile.exception.SearchDisableException;
|
||||
import im.zhaojun.zfile.model.support.FilePageModel;
|
||||
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.SiteConfigDTO;
|
||||
import im.zhaojun.zfile.model.dto.SystemConfigDTO;
|
||||
import im.zhaojun.zfile.service.base.AbstractBaseFileService;
|
||||
import im.zhaojun.zfile.service.support.FileAsyncCacheService;
|
||||
import im.zhaojun.zfile.model.dto.SystemFrontConfigDTO;
|
||||
import im.zhaojun.zfile.model.support.FilePageModel;
|
||||
import im.zhaojun.zfile.service.DriveConfigService;
|
||||
import im.zhaojun.zfile.service.SystemConfigService;
|
||||
import im.zhaojun.zfile.service.SystemService;
|
||||
import im.zhaojun.zfile.service.base.AbstractBaseFileService;
|
||||
import im.zhaojun.zfile.context.DriveContext;
|
||||
import im.zhaojun.zfile.util.FileComparator;
|
||||
import im.zhaojun.zfile.util.HttpUtil;
|
||||
import im.zhaojun.zfile.util.StringUtils;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.client.HttpClientErrorException;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* 前台文件管理
|
||||
@@ -36,34 +36,61 @@ import java.util.*;
|
||||
@RestController
|
||||
public class FileController {
|
||||
|
||||
@Resource
|
||||
private SystemService systemService;
|
||||
|
||||
@Resource
|
||||
private SystemConfigService systemConfigService;
|
||||
|
||||
@Resource
|
||||
private FileAsyncCacheService fileAsyncCacheService;
|
||||
private DriveContext driveContext;
|
||||
|
||||
@Resource
|
||||
private DriveConfigService driveConfigService;
|
||||
|
||||
/**
|
||||
* 滚动加载每页条数.
|
||||
*/
|
||||
private static final Integer PAGE_SIZE = 30;
|
||||
|
||||
@CheckStorageStrategyInit
|
||||
@GetMapping("/list")
|
||||
public ResultBean list(@RequestParam(defaultValue = "/") String path,
|
||||
@RequestParam(defaultValue = "name") String sortBy,
|
||||
@RequestParam(defaultValue = "asc") String order,
|
||||
|
||||
/**
|
||||
* 获取所有驱动器
|
||||
*
|
||||
* @return 所有驱动器
|
||||
*/
|
||||
@GetMapping("/drive/list")
|
||||
public ResultBean drives() {
|
||||
return ResultBean.success(driveConfigService.list());
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取某个驱动器下, 指定路径的数据, 每页固定 {@link #PAGE_SIZE} 条数据.
|
||||
*
|
||||
* @param driveId
|
||||
* 驱动器 ID
|
||||
*
|
||||
* @param path
|
||||
* 路径
|
||||
*
|
||||
* @param password
|
||||
* 文件夹密码, 某些文件夹需要密码才能访问, 当不需要密码时, 此参数可以为空
|
||||
*
|
||||
* @param page
|
||||
* 页数
|
||||
*
|
||||
* @return 当前路径下所有文件及文件夹
|
||||
*/
|
||||
@GetMapping("/list/{driveId}")
|
||||
public ResultBean list(@PathVariable(name = "driveId") Integer driveId,
|
||||
@RequestParam(defaultValue = "/") String path,
|
||||
@RequestParam(required = false) String password,
|
||||
@RequestParam(defaultValue = "1") Integer page) throws Exception {
|
||||
AbstractBaseFileService fileService = systemConfigService.getCurrentFileService();
|
||||
AbstractBaseFileService fileService = driveContext.getDriveService(driveId);
|
||||
List<FileItemDTO> fileItemList = fileService.fileList(StringUtils.removeDuplicateSeparator("/" + path + "/"));
|
||||
|
||||
for (FileItemDTO fileItemDTO : fileItemList) {
|
||||
if (ZFileConstant.PASSWORD_FILE_NAME.equals(fileItemDTO.getName())) {
|
||||
String expectedPasswordContent;
|
||||
try {
|
||||
expectedPasswordContent = HttpUtil.getTextContent(fileItemDTO.getUrl() + '1');
|
||||
expectedPasswordContent = HttpUtil.getTextContent(fileItemDTO.getUrl());
|
||||
} catch (HttpClientErrorException httpClientErrorException) {
|
||||
log.debug("尝试重新获取密码文件缓存中链接后仍失败", httpClientErrorException);
|
||||
try {
|
||||
@@ -86,45 +113,50 @@ public class FileController {
|
||||
return ResultBean.error("此文件夹需要密码.", ResultBean.REQUIRED_PASSWORD);
|
||||
}
|
||||
}
|
||||
|
||||
return ResultBean.successData(getSortedPagingData(fileItemList, page));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取系统配置信息和当前页的标题, 页面文档信息
|
||||
* @param path 路径
|
||||
*
|
||||
* @param driveId
|
||||
* 驱动器 ID
|
||||
*
|
||||
* @return 返回指定存储器的系统配置信息
|
||||
*/
|
||||
@CheckStorageStrategyInit
|
||||
@GetMapping("/config")
|
||||
public ResultBean getConfig(String path) throws Exception {
|
||||
SiteConfigDTO config = systemService.getConfig(StringUtils.removeDuplicateSeparator("/" + path + "/"));
|
||||
config.setSystemConfigDTO(systemConfigService.getSystemConfig());
|
||||
return ResultBean.successData(config);
|
||||
@GetMapping("/config/{driveId}")
|
||||
public ResultBean getConfig(@PathVariable(name = "driveId") Integer driveId, String path) {
|
||||
SystemFrontConfigDTO systemConfig = systemConfigService.getSystemFrontConfig(driveId);
|
||||
|
||||
AbstractBaseFileService fileService = driveContext.getDriveService(driveId);
|
||||
String fullPath = StringUtils.removeDuplicateSeparator(path + "/" + ZFileConstant.README_FILE_NAME);
|
||||
try {
|
||||
FileItemDTO fileItem = fileService.getFileItem(fullPath);
|
||||
String readme = HttpUtil.getTextContent(fileItem.getUrl());
|
||||
systemConfig.setReadme(readme);
|
||||
} catch (Exception e) {
|
||||
// ignore
|
||||
}
|
||||
|
||||
return ResultBean.successData(systemConfig);
|
||||
}
|
||||
|
||||
|
||||
@CheckStorageStrategyInit
|
||||
@GetMapping("/search")
|
||||
@GetMapping("/search/{driveId}")
|
||||
public ResultBean search(@RequestParam(value = "name", defaultValue = "/") String name,
|
||||
@RequestParam(defaultValue = "name") String sortBy,
|
||||
@RequestParam(defaultValue = "asc") String order,
|
||||
@RequestParam(defaultValue = "1") Integer page) {
|
||||
AbstractBaseFileService fileService = systemConfigService.getCurrentFileService();
|
||||
SystemConfigDTO systemConfigDTO = systemConfigService.getSystemConfig();
|
||||
if (BooleanUtil.isFalse(systemConfigDTO.getSearchEnable())) {
|
||||
throw new SearchDisableException("搜索功能未开启");
|
||||
}
|
||||
if (!fileAsyncCacheService.isCacheFinish()) {
|
||||
throw new SearchDisableException("搜索功能缓存预热中, 请稍后再试");
|
||||
}
|
||||
List<FileItemDTO> fileItemList = fileService.search(URLUtil.decode(name));
|
||||
return ResultBean.successData(getSortedPagingData(fileItemList, page));
|
||||
@RequestParam(defaultValue = "1") Integer page,
|
||||
@PathVariable("driveId") Integer driveId) {
|
||||
return ResultBean.error("暂不支持搜索功能");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 过滤文件列表, 不显示密码, 文档文件.
|
||||
* 过滤文件列表, 去除密码, 文档文件.
|
||||
*
|
||||
* @param fileItemList
|
||||
* 文件列表
|
||||
*/
|
||||
private void filterFileList(List<FileItemDTO> fileItemList) {
|
||||
if (fileItemList == null) {
|
||||
@@ -136,6 +168,17 @@ public class FileController {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 对传入的文件列表, 按照文件名进行排序, 然后取相应页数的文件
|
||||
*
|
||||
* @param fileItemList
|
||||
* 文件列表
|
||||
*
|
||||
* @param page
|
||||
* 要取的页数
|
||||
*
|
||||
* @return 排序及分页后的那段数据
|
||||
*/
|
||||
private FilePageModel getSortedPagingData(List<FileItemDTO> fileItemList, Integer page) {
|
||||
ArrayList<FileItemDTO> copy = new ArrayList<>(Arrays.asList(new FileItemDTO[fileItemList.size()]));
|
||||
Collections.copy(copy, fileItemList);
|
||||
@@ -148,25 +191,30 @@ public class FileController {
|
||||
int totalPage = (total + PAGE_SIZE - 1) / PAGE_SIZE;
|
||||
|
||||
if (page > totalPage) {
|
||||
return new FilePageModel(total, totalPage, Collections.emptyList());
|
||||
return new FilePageModel(totalPage, Collections.emptyList());
|
||||
}
|
||||
|
||||
int start = (page - 1) * PAGE_SIZE;
|
||||
int end = page * PAGE_SIZE;
|
||||
end = Math.min(end, total);
|
||||
return new FilePageModel(total, totalPage, copy.subList(start, end));
|
||||
return new FilePageModel(totalPage, copy.subList(start, end));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取指定路径下的文件信息内容
|
||||
* @param path 文件全路径
|
||||
* @return 该文件的名称, 路径, 大小, 下载地址等信息.
|
||||
*
|
||||
* @param driveId
|
||||
* 驱动器 ID
|
||||
*
|
||||
* @param path
|
||||
* 文件全路径
|
||||
*
|
||||
* @return 该文件的名称, 路径, 大小, 下载地址等信息.
|
||||
*/
|
||||
@CheckStorageStrategyInit
|
||||
@GetMapping("/directlink")
|
||||
public ResultBean directlink(String path) {
|
||||
AbstractBaseFileService fileService = systemConfigService.getCurrentFileService();
|
||||
@GetMapping("/directlink/{driveId}")
|
||||
public ResultBean directlink(@PathVariable(name = "driveId") Integer driveId, String path) {
|
||||
AbstractBaseFileService fileService = driveContext.getDriveService(driveId);
|
||||
return ResultBean.successData(fileService.getFileItem(path));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,20 +1,17 @@
|
||||
package im.zhaojun.zfile.controller;
|
||||
|
||||
import cn.hutool.crypto.SecureUtil;
|
||||
import im.zhaojun.zfile.model.entity.StorageConfig;
|
||||
import im.zhaojun.zfile.model.dto.InstallModelDTO;
|
||||
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.model.enums.StorageTypeEnum;
|
||||
import im.zhaojun.zfile.service.StorageConfigService;
|
||||
import im.zhaojun.zfile.service.SystemConfigService;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 系统安装初始化
|
||||
@@ -34,50 +31,23 @@ public class InstallController {
|
||||
|
||||
@GetMapping("/is-installed")
|
||||
public ResultBean isInstall() {
|
||||
if (systemConfigService.getCurrentStorageStrategy() == null) {
|
||||
return ResultBean.success();
|
||||
if (!StringUtils.isEmpty(systemConfigService.getAdminUsername())) {
|
||||
return ResultBean.error("请勿重复初始化");
|
||||
}
|
||||
return ResultBean.error("请勿重复初始化");
|
||||
}
|
||||
|
||||
|
||||
@PostMapping("/install")
|
||||
public ResultBean install(InstallModelDTO installModelDTO) throws Exception {
|
||||
SystemConfigDTO systemConfigDTO = systemConfigService.getSystemConfig();
|
||||
|
||||
if (systemConfigDTO.getStorageStrategy() != null) {
|
||||
return ResultBean.error("请勿重复初始化.");
|
||||
}
|
||||
|
||||
systemConfigDTO.setSiteName(installModelDTO.getSiteName());
|
||||
StorageTypeEnum storageTypeEnum = installModelDTO.getStorageStrategy();
|
||||
systemConfigDTO.setStorageStrategy(storageTypeEnum);
|
||||
systemConfigDTO.setUsername(installModelDTO.getUsername());
|
||||
systemConfigDTO.setPassword(SecureUtil.md5(installModelDTO.getPassword()));
|
||||
systemConfigDTO.setDomain(installModelDTO.getDomain());
|
||||
systemConfigService.updateSystemConfig(systemConfigDTO);
|
||||
|
||||
Map<String, String> storageStrategyConfig = installModelDTO.getStorageStrategyConfig();
|
||||
|
||||
List<StorageConfig> storageConfigList = storageConfigService.selectStorageConfigByType(storageTypeEnum);
|
||||
for (StorageConfig storageConfig : storageConfigList) {
|
||||
String key = storageConfig.getKey();
|
||||
String value = storageStrategyConfig.get(key);
|
||||
storageConfig.setValue(value);
|
||||
}
|
||||
|
||||
storageConfigService.updateStorageConfig(storageConfigList);
|
||||
adminController.refreshStorageStrategy();
|
||||
return ResultBean.success();
|
||||
}
|
||||
|
||||
|
||||
@GetMapping("/form")
|
||||
public ResultBean getFormByStorageType(String storageType) {
|
||||
StorageTypeEnum storageTypeEnum = StorageTypeEnum.getEnum(storageType);
|
||||
List<StorageConfig> storageConfigList = storageConfigService.selectStorageConfigByType(storageTypeEnum);
|
||||
storageConfigList.forEach(storageConfig -> storageConfig.setValue(null));
|
||||
return ResultBean.success(storageConfigList);
|
||||
@PostMapping("/install")
|
||||
public ResultBean install(SystemConfigDTO systemConfigDTO) {
|
||||
if (!StringUtils.isEmpty(systemConfigService.getAdminUsername())) {
|
||||
return ResultBean.error("请勿重复初始化.");
|
||||
}
|
||||
|
||||
systemConfigDTO.setPassword(SecureUtil.md5(systemConfigDTO.getPassword()));
|
||||
systemConfigService.updateSystemConfig(systemConfigDTO);
|
||||
|
||||
return ResultBean.success();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,12 +1,14 @@
|
||||
package im.zhaojun.zfile.controller;
|
||||
|
||||
import im.zhaojun.zfile.service.impl.LocalServiceImpl;
|
||||
import im.zhaojun.zfile.context.DriveContext;
|
||||
import im.zhaojun.zfile.util.FileUtil;
|
||||
import im.zhaojun.zfile.util.StringUtils;
|
||||
import im.zhaojun.zfile.service.impl.LocalServiceImpl;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.util.AntPathMatcher;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
import org.springframework.web.servlet.HandlerMapping;
|
||||
|
||||
@@ -15,23 +17,33 @@ import javax.servlet.http.HttpServletRequest;
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* 本地存储 Controller
|
||||
* @author zhaojun
|
||||
*/
|
||||
@Controller
|
||||
public class LocalController {
|
||||
|
||||
@Resource
|
||||
private LocalServiceImpl localServiceImpl;
|
||||
private DriveContext driveContext;
|
||||
|
||||
@GetMapping("/file/**")
|
||||
/**
|
||||
* 本地存储下载指定文件
|
||||
*
|
||||
* @param driveId
|
||||
* 驱动器 ID
|
||||
*
|
||||
* @return 文件
|
||||
*/
|
||||
@GetMapping("/file/{driveId}/**")
|
||||
@ResponseBody
|
||||
public ResponseEntity<Object> downAttachment(final HttpServletRequest request) {
|
||||
public ResponseEntity<Object> downAttachment(@PathVariable("driveId") Integer driveId, final HttpServletRequest request) {
|
||||
String path = (String) request.getAttribute(
|
||||
HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE);
|
||||
String bestMatchPattern = (String) request.getAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE);
|
||||
AntPathMatcher apm = new AntPathMatcher();
|
||||
String filePath = apm.extractPathWithinPattern(bestMatchPattern, path);
|
||||
|
||||
return FileUtil.export(new File(StringUtils.concatPath(localServiceImpl.getFilePath(), filePath)));
|
||||
LocalServiceImpl localService = (LocalServiceImpl) driveContext.getDriveService(driveId);
|
||||
return FileUtil.export(new File(StringUtils.concatPath(localService.getFilePath(), filePath)));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
package im.zhaojun.zfile.controller;
|
||||
|
||||
import im.zhaojun.zfile.service.impl.OneDriveChinaServiceImpl;
|
||||
import im.zhaojun.zfile.model.support.OneDriveToken;
|
||||
import im.zhaojun.zfile.service.impl.OneDriveChinaServiceImpl;
|
||||
import im.zhaojun.zfile.service.impl.OneDriveServiceImpl;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
@@ -24,7 +24,7 @@ public class OneDriveController {
|
||||
private OneDriveChinaServiceImpl oneDriveChinaServiceImpl;
|
||||
|
||||
@GetMapping("/callback")
|
||||
public String onedriveCallback(String code, Model model) {
|
||||
public String oneDriveCallback(String code, Model model) {
|
||||
OneDriveToken oneDriveToken = oneDriveServiceImpl.getToken(code);
|
||||
model.addAttribute("accessToken", oneDriveToken.getAccessToken());
|
||||
model.addAttribute("refreshToken", oneDriveToken.getRefreshToken());
|
||||
@@ -33,7 +33,7 @@ public class OneDriveController {
|
||||
|
||||
|
||||
@GetMapping("/china-callback")
|
||||
public String onedriveChinaCallback(String code, Model model) {
|
||||
public String oneDriveChinaCallback(String code, Model model) {
|
||||
OneDriveToken oneDriveToken = oneDriveChinaServiceImpl.getToken(code);
|
||||
model.addAttribute("accessToken", oneDriveToken.getAccessToken());
|
||||
model.addAttribute("refreshToken", oneDriveToken.getRefreshToken());
|
||||
|
||||
@@ -4,11 +4,12 @@ import cn.hutool.core.util.URLUtil;
|
||||
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.SystemConfigService;
|
||||
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;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.servlet.HandlerMapping;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
@@ -17,16 +18,22 @@ import java.util.Objects;
|
||||
|
||||
/**
|
||||
* @author Zhao Jun
|
||||
* 2020/2/9 11:17
|
||||
*/
|
||||
@Controller
|
||||
public class PageController {
|
||||
|
||||
@Resource
|
||||
private SystemConfigService systemConfigService;
|
||||
private DriveContext driveContext;
|
||||
|
||||
@GetMapping("/directlink/**")
|
||||
public String directlink(final HttpServletRequest request) {
|
||||
/**
|
||||
* 获取指定驱动器, 某个文件的直链, 然后重定向过去.
|
||||
* @param driveId
|
||||
* 驱动器 ID
|
||||
*
|
||||
* @return 重定向至文件直链
|
||||
*/
|
||||
@GetMapping("/directlink/{driveId}/**")
|
||||
public String directlink(@PathVariable("driveId") Integer driveId, final HttpServletRequest request) {
|
||||
String path = (String) request.getAttribute(
|
||||
HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE);
|
||||
String bestMatchPattern = (String) request.getAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE);
|
||||
@@ -37,7 +44,7 @@ public class PageController {
|
||||
filePath = "/" + filePath;
|
||||
}
|
||||
|
||||
AbstractBaseFileService fileService = systemConfigService.getCurrentFileService();
|
||||
AbstractBaseFileService fileService = driveContext.getDriveService(driveId);
|
||||
FileItemDTO fileItem = fileService.getFileItem(filePath);
|
||||
|
||||
String url = fileItem.getUrl();
|
||||
|
||||
@@ -0,0 +1,119 @@
|
||||
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.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;
|
||||
|
||||
/**
|
||||
* 管理后台接口
|
||||
* @author zhaojun
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/admin")
|
||||
@Slf4j
|
||||
public class AdminController {
|
||||
|
||||
@Resource
|
||||
private SystemConfigService systemConfigService;
|
||||
|
||||
/**
|
||||
* 获取系统配置
|
||||
*/
|
||||
@GetMapping("/config")
|
||||
public ResultBean getConfig() {
|
||||
SystemConfigDTO systemConfigDTO = systemConfigService.getSystemConfig();
|
||||
return ResultBean.success(systemConfigDTO);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 更新系统配置
|
||||
*/
|
||||
@PostMapping("/config")
|
||||
public ResultBean updateConfig(SystemConfigDTO systemConfigDTO) throws Exception {
|
||||
systemConfigDTO.setId(1);
|
||||
systemConfigService.updateSystemConfig(systemConfigDTO);
|
||||
return ResultBean.success();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 修改管理员登陆密码
|
||||
*/
|
||||
@PostMapping("/update-pwd")
|
||||
public ResultBean updatePwd(String username, String password) {
|
||||
systemConfigService.updateUsernameAndPwd(username, password);
|
||||
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());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package im.zhaojun.zfile.controller.admin;
|
||||
|
||||
import im.zhaojun.zfile.model.dto.ResultBean;
|
||||
import im.zhaojun.zfile.service.DriveConfigService;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
/**
|
||||
* 缓存 Controller
|
||||
*
|
||||
* @author zhaojun
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/admin/cache")
|
||||
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();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
package im.zhaojun.zfile.controller.admin;
|
||||
|
||||
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.service.DriveConfigService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 驱动器 Controller
|
||||
* @author zhaojun
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/admin")
|
||||
@Slf4j
|
||||
public class DriveController {
|
||||
|
||||
@Resource
|
||||
private DriveConfigService driveConfigService;
|
||||
|
||||
|
||||
/**
|
||||
* 获取所有驱动器列表
|
||||
*
|
||||
* @return 驱动器列表
|
||||
*/
|
||||
@GetMapping("drives")
|
||||
public ResultBean driveList() {
|
||||
List<DriveConfig> list = driveConfigService.list();
|
||||
return ResultBean.success(list);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取指定驱动器基本信息及其参数
|
||||
*
|
||||
* @param id
|
||||
* 驱动器 ID
|
||||
*
|
||||
* @return 驱动器基本信息信息
|
||||
*/
|
||||
@GetMapping("drive/{id}")
|
||||
public ResultBean driveItem(@PathVariable Integer id) {
|
||||
DriveConfigDTO driveConfig = driveConfigService.findDriveConfigDTOById(id);
|
||||
return ResultBean.success(driveConfig);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 保存驱动器设置
|
||||
*/
|
||||
@PostMapping("drive")
|
||||
public ResultBean saveDriveItem(@RequestBody DriveConfigDTO driveConfigDTO) {
|
||||
driveConfigService.save(driveConfigDTO);
|
||||
return ResultBean.success();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 删除驱动器设置
|
||||
*
|
||||
* @param id
|
||||
* 驱动器 ID
|
||||
*/
|
||||
@DeleteMapping("drive/{id}")
|
||||
public ResultBean deleteDriveItem(@PathVariable Integer id) {
|
||||
driveConfigService.deleteById(id);
|
||||
return ResultBean.success();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
package im.zhaojun.zfile.core;
|
||||
|
||||
import im.zhaojun.zfile.exception.StorageStrategyUninitializedException;
|
||||
import im.zhaojun.zfile.service.base.AbstractBaseFileService;
|
||||
import im.zhaojun.zfile.service.SystemConfigService;
|
||||
import im.zhaojun.zfile.util.SpringContextHolder;
|
||||
import org.aspectj.lang.annotation.Aspect;
|
||||
import org.aspectj.lang.annotation.Before;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* @author zhaojun
|
||||
*/
|
||||
@Aspect
|
||||
@Component
|
||||
public class StorageStrategyInitCheckAop {
|
||||
|
||||
@Before("@annotation(im.zhaojun.zfile.model.annotation.CheckStorageStrategyInit)")
|
||||
public void logStart() {
|
||||
SystemConfigService systemConfigService = SpringContextHolder.getBean(SystemConfigService.class);
|
||||
AbstractBaseFileService currentFileService = systemConfigService.getCurrentFileService();
|
||||
if (currentFileService == null) {
|
||||
throw new StorageStrategyUninitializedException("存储策略尚未初始化, 请联系管理员!");
|
||||
}
|
||||
if (currentFileService.getIsUnInitialized()) {
|
||||
throw new StorageStrategyUninitializedException("存储策略异常, 请联系管理员!");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -63,6 +63,15 @@ public class GlobleExceptionHandler {
|
||||
// }
|
||||
}
|
||||
|
||||
@ExceptionHandler({PreviewException.class})
|
||||
@ResponseBody
|
||||
@ResponseStatus
|
||||
public ResultBean previewException(PreviewException ex) {
|
||||
return ResultBean.error(ex.getMessage());
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ExceptionHandler
|
||||
@ResponseBody
|
||||
@ResponseStatus(code= HttpStatus.INTERNAL_SERVER_ERROR)
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
package im.zhaojun.zfile.exception;
|
||||
|
||||
/**
|
||||
* 文件预览异常类
|
||||
* @author zhaojun
|
||||
*/
|
||||
public class PreviewException extends RuntimeException {
|
||||
|
||||
public PreviewException() {
|
||||
}
|
||||
|
||||
public PreviewException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public PreviewException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
public PreviewException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
public PreviewException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
|
||||
super(message, cause, enableSuppression, writableStackTrace);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package im.zhaojun.zfile.config;
|
||||
package im.zhaojun.zfile.filter;
|
||||
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.web.cors.CorsUtils;
|
||||
@@ -23,7 +23,6 @@ public class CorsFilter extends GenericFilterBean {
|
||||
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
|
||||
HttpServletResponse httpServletResponse = (HttpServletResponse) response;
|
||||
|
||||
// Set customized header
|
||||
httpServletResponse.setHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN, httpServletRequest.getHeader(HttpHeaders.ORIGIN));
|
||||
httpServletResponse.setHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_HEADERS, "Origin, X-Requested-With, Content-Type, Accept");
|
||||
httpServletResponse.setHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_METHODS, "GET, POST, PUT, DELETE, OPTIONS");
|
||||
@@ -34,4 +33,5 @@ public class CorsFilter extends GenericFilterBean {
|
||||
chain.doFilter(httpServletRequest, httpServletResponse);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
package im.zhaojun.zfile.model.annotation;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* 标记注解, 用于在调用前检查是否已存储策略
|
||||
* @author zhaojun
|
||||
*/
|
||||
@Target(ElementType.METHOD)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface CheckStorageStrategyInit {
|
||||
}
|
||||
@@ -5,7 +5,7 @@ package im.zhaojun.zfile.model.constant;
|
||||
*/
|
||||
public class StorageConfigConstant {
|
||||
|
||||
public static final String BUCKET_NAME_KEY = "bucket-name";
|
||||
public static final String BUCKET_NAME_KEY = "bucketName";
|
||||
|
||||
public static final String SECRET_ID_KEY = "secretId";
|
||||
|
||||
@@ -15,7 +15,7 @@ public class StorageConfigConstant {
|
||||
|
||||
public static final String ENDPOINT_KEY = "endPoint";
|
||||
|
||||
public static final String BASE_PATH = "base-path";
|
||||
public static final String BASE_PATH = "basePath";
|
||||
|
||||
public static final String DOMAIN_KEY = "domain";
|
||||
|
||||
|
||||
@@ -7,8 +7,6 @@ public class SystemConfigConstant {
|
||||
|
||||
public static final String SITE_NAME = "siteName";
|
||||
|
||||
public static final String INFO_ENABLE = "infoEnable";
|
||||
|
||||
public static final String SEARCH_ENABLE = "searchEnable";
|
||||
|
||||
public static final String SEARCH_IGNORE_CASE = "searchIgnoreCase";
|
||||
|
||||
@@ -28,6 +28,17 @@ public class ZFileConstant {
|
||||
*/
|
||||
public static String PASSWORD_FILE_NAME = "password.txt";
|
||||
|
||||
/**
|
||||
* 最大支持文件大小为 ? MB 的音乐文件解析封面, 歌手等信息.
|
||||
*/
|
||||
public static Long AUDIO_MAX_FILE_SIZE_MB = 1L;
|
||||
|
||||
/**
|
||||
* 最大支持文本文件大小为 ? KB 的文件内容.
|
||||
*/
|
||||
public static Long TEXT_MAX_FILE_SIZE_KB = 100L;
|
||||
|
||||
|
||||
@Autowired(required = false)
|
||||
public void setHeaderFileName(@Value("${zfile.constant.readme}") String headerFileName) {
|
||||
ZFileConstant.README_FILE_NAME = headerFileName;
|
||||
@@ -38,4 +49,15 @@ public class ZFileConstant {
|
||||
ZFileConstant.PASSWORD_FILE_NAME = passwordFileName;
|
||||
}
|
||||
|
||||
@Autowired(required = false)
|
||||
public void setAudioMaxFileSizeMb(@Value("${zfile.preview.audio.maxFileSizeMb}") Long maxFileSizeMb) {
|
||||
ZFileConstant.AUDIO_MAX_FILE_SIZE_MB = maxFileSizeMb;
|
||||
}
|
||||
|
||||
@Autowired(required = false)
|
||||
public void setTextMaxFileSizeMb(@Value("${zfile.preview.text.maxFileSizeKb}") Long maxFileSizeKb) {
|
||||
ZFileConstant.TEXT_MAX_FILE_SIZE_KB = maxFileSizeKb;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -1,53 +1,27 @@
|
||||
package im.zhaojun.zfile.model.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @author zhaojun
|
||||
*/
|
||||
@Data
|
||||
public class AudioInfoDTO {
|
||||
|
||||
private String title;
|
||||
|
||||
private String artist;
|
||||
|
||||
private String cover;
|
||||
|
||||
private String src;
|
||||
|
||||
public String getTitle() {
|
||||
return title;
|
||||
public static AudioInfoDTO buildDefaultAudioInfoDTO() {
|
||||
AudioInfoDTO audioInfoDTO = new AudioInfoDTO();
|
||||
audioInfoDTO.setTitle("未知歌曲");
|
||||
audioInfoDTO.setArtist("未知");
|
||||
audioInfoDTO.setCover("http://c.jun6.net/audio.png");
|
||||
return audioInfoDTO;
|
||||
}
|
||||
|
||||
public void setTitle(String title) {
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
public String getArtist() {
|
||||
return artist;
|
||||
}
|
||||
|
||||
public void setArtist(String artist) {
|
||||
this.artist = artist;
|
||||
}
|
||||
|
||||
public String getCover() {
|
||||
return cover;
|
||||
}
|
||||
|
||||
public void setCover(String cover) {
|
||||
this.cover = cover;
|
||||
}
|
||||
|
||||
public String getSrc() {
|
||||
return src;
|
||||
}
|
||||
|
||||
public void setSrc(String src) {
|
||||
this.src = src;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "AudioInfoDTO{" +
|
||||
"title='" + title + '\'' +
|
||||
", artist='" + artist + '\'' +
|
||||
", cover='" + cover + '\'' +
|
||||
", src='" + src + '\'' +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
||||
33
src/main/java/im/zhaojun/zfile/model/dto/DriveConfigDTO.java
Normal file
33
src/main/java/im/zhaojun/zfile/model/dto/DriveConfigDTO.java
Normal file
@@ -0,0 +1,33 @@
|
||||
package im.zhaojun.zfile.model.dto;
|
||||
|
||||
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
|
||||
import im.zhaojun.zfile.model.enums.StorageTypeEnum;
|
||||
import im.zhaojun.zfile.model.enums.StorageTypeEnumJsonDeSerializerConvert;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @author zhaojun
|
||||
*/
|
||||
@Data
|
||||
public class DriveConfigDTO {
|
||||
|
||||
private Integer id;
|
||||
|
||||
private String name;
|
||||
|
||||
@JsonDeserialize(using = StorageTypeEnumJsonDeSerializerConvert.class)
|
||||
private StorageTypeEnum type;
|
||||
|
||||
private boolean enableCache;
|
||||
|
||||
private boolean autoRefreshCache;
|
||||
|
||||
private boolean searchEnable;
|
||||
|
||||
private boolean searchIgnoreCase;
|
||||
|
||||
private boolean searchContainEncryptedFile;
|
||||
|
||||
private StorageStrategyConfig storageStrategyConfig;
|
||||
|
||||
}
|
||||
@@ -1,23 +1,23 @@
|
||||
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;
|
||||
|
||||
}
|
||||
// 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;
|
||||
//
|
||||
// }
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
package im.zhaojun.zfile.model.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @author zhaojun
|
||||
*/
|
||||
@Data
|
||||
public class StorageStrategyConfig {
|
||||
|
||||
private String endPoint;
|
||||
|
||||
private String pathStyle;
|
||||
|
||||
private boolean isPrivate;
|
||||
|
||||
private String accessKey;
|
||||
|
||||
private String secretKey;
|
||||
|
||||
private String bucketName;
|
||||
|
||||
private String host;
|
||||
|
||||
private String port;
|
||||
|
||||
private String accessToken;
|
||||
|
||||
private String refreshToken;
|
||||
|
||||
private String secretId;
|
||||
|
||||
private String filePath;
|
||||
|
||||
private String username;
|
||||
|
||||
private String password;
|
||||
|
||||
private String domain;
|
||||
|
||||
private String basePath;
|
||||
|
||||
}
|
||||
@@ -9,6 +9,7 @@ import lombok.ToString;
|
||||
|
||||
/**
|
||||
* 系统设置传输类
|
||||
*
|
||||
* @author zhaojun
|
||||
*/
|
||||
@ToString
|
||||
@@ -20,26 +21,16 @@ public class SystemConfigDTO {
|
||||
|
||||
private String siteName;
|
||||
|
||||
private Boolean infoEnable;
|
||||
|
||||
private Boolean searchEnable;
|
||||
|
||||
private Boolean searchIgnoreCase;
|
||||
private String username;
|
||||
|
||||
@JsonSerialize(using = StorageTypeEnumSerializerConvert.class)
|
||||
private StorageTypeEnum storageStrategy;
|
||||
|
||||
private String username;
|
||||
|
||||
@JsonIgnore
|
||||
private String password;
|
||||
|
||||
private String domain;
|
||||
|
||||
private Boolean enableCache;
|
||||
|
||||
private Boolean searchContainEncryptedFile;
|
||||
|
||||
private String customJs;
|
||||
|
||||
private String customCss;
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
package im.zhaojun.zfile.model.dto;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import lombok.Data;
|
||||
import lombok.ToString;
|
||||
|
||||
/**
|
||||
* 系统设置传输类
|
||||
* @author zhaojun
|
||||
*/
|
||||
@ToString
|
||||
@Data
|
||||
public class SystemFrontConfigDTO {
|
||||
|
||||
@JsonIgnore
|
||||
private Integer id;
|
||||
|
||||
private String siteName;
|
||||
|
||||
private Boolean searchEnable;
|
||||
|
||||
// @JsonSerialize(using = StorageTypeEnumSerializerConvert.class)
|
||||
// private StorageTypeEnum storageStrategy;
|
||||
|
||||
private String username;
|
||||
|
||||
private String domain;
|
||||
|
||||
private String customJs;
|
||||
|
||||
private String customCss;
|
||||
|
||||
private String tableSize;
|
||||
|
||||
private Boolean showOperator;
|
||||
|
||||
private Boolean showDocument;
|
||||
|
||||
private String announcement;
|
||||
|
||||
private Boolean showAnnouncement;
|
||||
|
||||
private String layout;
|
||||
|
||||
private String readme;
|
||||
|
||||
}
|
||||
38
src/main/java/im/zhaojun/zfile/model/entity/DriveConfig.java
Normal file
38
src/main/java/im/zhaojun/zfile/model/entity/DriveConfig.java
Normal file
@@ -0,0 +1,38 @@
|
||||
package im.zhaojun.zfile.model.entity;
|
||||
|
||||
import im.zhaojun.zfile.model.enums.StorageTypeEnum;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
|
||||
/**
|
||||
* 驱动器
|
||||
*
|
||||
* @author zhaojun
|
||||
*/
|
||||
@Entity(name = "DRIVER_CONFIG")
|
||||
@Data
|
||||
public class DriveConfig {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private Integer id;
|
||||
|
||||
private String name;
|
||||
|
||||
private Boolean enableCache;
|
||||
|
||||
private Boolean autoRefreshCache;
|
||||
|
||||
private StorageTypeEnum type;
|
||||
|
||||
private Boolean searchEnable;
|
||||
|
||||
private Boolean searchIgnoreCase;
|
||||
|
||||
private Boolean searchContainEncryptedFile;
|
||||
|
||||
}
|
||||
@@ -30,6 +30,13 @@ public class StorageConfig {
|
||||
@Column(length = 4000)
|
||||
private String value;
|
||||
|
||||
private Integer driveId;
|
||||
|
||||
public StorageConfig(String key, String title) {
|
||||
this.key = key;
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
public Integer getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@@ -12,4 +12,5 @@ public class StorageTypeEnumDeSerializerConvert implements Converter<String, Sto
|
||||
public StorageTypeEnum convert(@NonNull String s) {
|
||||
return StorageTypeEnum.getEnum(s);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package im.zhaojun.zfile.model.enums;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.databind.DeserializationContext;
|
||||
import com.fasterxml.jackson.databind.JsonDeserializer;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* @author zhaojun
|
||||
*/
|
||||
public class StorageTypeEnumJsonDeSerializerConvert extends JsonDeserializer<StorageTypeEnum> {
|
||||
|
||||
@Override
|
||||
public StorageTypeEnum deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException {
|
||||
return StorageTypeEnum.getEnum(jsonParser.getText());
|
||||
}
|
||||
}
|
||||
@@ -13,10 +13,8 @@ import java.util.List;
|
||||
@AllArgsConstructor
|
||||
public class FilePageModel {
|
||||
|
||||
private int total;
|
||||
|
||||
private int totalPage;
|
||||
|
||||
private List<FileItemDTO> fileList;
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,5 @@
|
||||
package im.zhaojun.zfile.model.support;
|
||||
|
||||
import im.zhaojun.zfile.model.support.Jvm;
|
||||
import im.zhaojun.zfile.model.support.Mem;
|
||||
import im.zhaojun.zfile.model.support.Sys;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
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.stereotype.Repository;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author zhaojun
|
||||
*/
|
||||
@Repository
|
||||
public interface DriverConfigRepository extends JpaRepository<DriveConfig, Integer> {
|
||||
|
||||
/**
|
||||
* 根据存储策略类型获取所有驱动器
|
||||
*
|
||||
* @param type
|
||||
* 存储类型
|
||||
*
|
||||
* @return 指定存储类型的存储器
|
||||
*/
|
||||
List<DriveConfig> findByType(StorageTypeEnum type);
|
||||
|
||||
}
|
||||
@@ -15,16 +15,56 @@ public interface StorageConfigRepository extends JpaRepository<StorageConfig, In
|
||||
|
||||
/**
|
||||
* 根据存储类型找对应的配置信息
|
||||
* @param type 存储类型
|
||||
* @return 此类型所有的配置信息
|
||||
*
|
||||
* @param type
|
||||
* 存储类型
|
||||
*
|
||||
* @return 此类型所有的配置信息
|
||||
*/
|
||||
List<StorageConfig> findByTypeOrderById(StorageTypeEnum type);
|
||||
|
||||
|
||||
/**
|
||||
* 根据存储类型找对应的配置信息
|
||||
*
|
||||
* @param driveId
|
||||
* 驱动器 ID
|
||||
*
|
||||
* @return 此驱动器所有的配置信息
|
||||
*/
|
||||
List<StorageConfig> findByDriveIdOrderById(Integer driveId);
|
||||
|
||||
|
||||
/**
|
||||
* 根据驱动器找到对应的配置信息
|
||||
*
|
||||
* @param driveId
|
||||
* 驱动器 ID
|
||||
*
|
||||
* @return 此驱动器所有的配置信息
|
||||
*/
|
||||
List<StorageConfig> findByDriveId(Integer driveId);
|
||||
|
||||
|
||||
/**
|
||||
* 删除指定驱动器对应的配置信息
|
||||
*
|
||||
* @param driveId
|
||||
* 驱动器 ID
|
||||
*/
|
||||
void deleteByDriveId(Integer driveId);
|
||||
|
||||
|
||||
/**
|
||||
* 根据存储类型找到某个 KEY 的值
|
||||
* @param type 存储类型
|
||||
* @param key KEY
|
||||
* @return KEY 对应的对象
|
||||
*
|
||||
* @param type
|
||||
* 存储类型
|
||||
*
|
||||
* @param key
|
||||
* KEY 值
|
||||
*
|
||||
* @return KEY 对应的对象
|
||||
*/
|
||||
StorageConfig findByTypeAndKey(StorageTypeEnum type, String key);
|
||||
|
||||
|
||||
@@ -12,8 +12,12 @@ public interface SystemConfigRepository extends JpaRepository<SystemConfig, Inte
|
||||
|
||||
/**
|
||||
* 查找系统设置中, 某个设置项对应的值
|
||||
* @param key 设置项
|
||||
* @return 设置值
|
||||
*
|
||||
* @param key
|
||||
* 设置项
|
||||
*
|
||||
* @return 设置值
|
||||
*/
|
||||
SystemConfig findByKey(String key);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
package im.zhaojun.zfile.schedule;
|
||||
|
||||
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;
|
||||
|
||||
/**
|
||||
* 计划任务工具类
|
||||
* @author zhaojun
|
||||
*/
|
||||
@Configuration
|
||||
@EnableScheduling
|
||||
@Slf4j
|
||||
public class GlobalScheduleTask {
|
||||
|
||||
@Resource
|
||||
private OneDriveServiceImpl oneDriveServiceImpl;
|
||||
|
||||
@Resource
|
||||
private OneDriveChinaServiceImpl oneDriveChinaServiceImpl;
|
||||
|
||||
@Resource
|
||||
private DriveConfigService driveConfigService;
|
||||
|
||||
@Resource
|
||||
private DriveContext driveContext;
|
||||
|
||||
/**
|
||||
* 项目启动 30 秒后, 每 15 分钟执行一次刷新 OneDrive Token 的定时任务.
|
||||
*/
|
||||
@Scheduled(fixedRate = 1000 * 60 * 10, initialDelay = 1000 * 30)
|
||||
public void autoRefreshOneDriveToken() {
|
||||
|
||||
try {
|
||||
log.debug("尝试调用 OneDrive 自动刷新 AccessToken 定时任务");
|
||||
|
||||
List<DriveConfig> driveConfigList = driveConfigService.findByType(StorageTypeEnum.ONE_DRIVE);
|
||||
driveConfigList.addAll(driveConfigService.findByType(StorageTypeEnum.ONE_DRIVE_CHINA));
|
||||
|
||||
driveConfigList.forEach(driveConfig -> {
|
||||
StorageTypeEnum storageType = driveConfig.getType();
|
||||
String name = driveConfig.getName();
|
||||
|
||||
try {
|
||||
AbstractOneDriveServiceBase driveService = (AbstractOneDriveServiceBase) driveContext.getDriveService(driveConfig.getId());
|
||||
driveService.refreshOneDriveToken();
|
||||
log.info("刷新驱动器 {}, {} key 时间: {}", name, storageType.getDescription(), LocalDateTime.now());
|
||||
} catch (Exception e) {
|
||||
log.debug("刷新驱动器 " + name + " Token 失败.", e);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
} catch (Throwable e) {
|
||||
log.debug("尝试调用 OneDrive 自动刷新 AccessToken 定时任务出现未知异常", e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -30,4 +30,5 @@ public class MyUserDetailsServiceImpl implements UserDetailsService {
|
||||
}
|
||||
return new User(systemConfig.getUsername(), systemConfig.getPassword(), Collections.emptyList());
|
||||
}
|
||||
|
||||
}
|
||||
212
src/main/java/im/zhaojun/zfile/service/DriveConfigService.java
Normal file
212
src/main/java/im/zhaojun/zfile/service/DriveConfigService.java
Normal file
@@ -0,0 +1,212 @@
|
||||
package im.zhaojun.zfile.service;
|
||||
|
||||
import im.zhaojun.zfile.context.StorageTypeContext;
|
||||
import im.zhaojun.zfile.model.dto.DriveConfigDTO;
|
||||
import im.zhaojun.zfile.model.dto.StorageStrategyConfig;
|
||||
import im.zhaojun.zfile.model.entity.DriveConfig;
|
||||
import im.zhaojun.zfile.model.entity.StorageConfig;
|
||||
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.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 驱动器 Service 类
|
||||
* @author zhaojun
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
public class DriveConfigService {
|
||||
|
||||
@Resource
|
||||
private DriverConfigRepository driverConfigRepository;
|
||||
|
||||
@Resource
|
||||
private StorageConfigRepository storageConfigRepository;
|
||||
|
||||
@Resource
|
||||
private DriveContext driveContext;
|
||||
|
||||
public static final Class<StorageStrategyConfig> STORAGE_STRATEGY_CONFIG_CLASS = StorageStrategyConfig.class;
|
||||
|
||||
/**
|
||||
* 获取所有驱动器列表
|
||||
*
|
||||
* @return 驱动器列表
|
||||
*/
|
||||
public List<DriveConfig> list() {
|
||||
return driverConfigRepository.findAll();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取指定驱动器设置
|
||||
*
|
||||
* @param id
|
||||
* 驱动器 ID
|
||||
*
|
||||
* @return 驱动器设置
|
||||
*/
|
||||
public DriveConfig findById(Integer id) {
|
||||
return driverConfigRepository.getOne(id);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取指定驱动器 DTO 对象, 此对象包含详细的参数设置.
|
||||
*
|
||||
* @param id
|
||||
* 驱动器 ID
|
||||
*
|
||||
* @return 驱动器 DTO
|
||||
*/
|
||||
public DriveConfigDTO findDriveConfigDTOById(Integer id) {
|
||||
DriveConfig driveConfig = driverConfigRepository.getOne(id);
|
||||
|
||||
DriveConfigDTO driveConfigDTO = new DriveConfigDTO();
|
||||
|
||||
List<StorageConfig> storageConfigList = storageConfigRepository.findByDriveId(driveConfig.getId());
|
||||
BeanUtils.copyProperties(driveConfig, driveConfigDTO);
|
||||
|
||||
StorageStrategyConfig storageStrategyConfig = new StorageStrategyConfig();
|
||||
for (StorageConfig storageConfig : storageConfigList) {
|
||||
String key = storageConfig.getKey();
|
||||
String value = storageConfig.getValue();
|
||||
|
||||
Field declaredField;
|
||||
try {
|
||||
declaredField = STORAGE_STRATEGY_CONFIG_CLASS.getDeclaredField(key);
|
||||
declaredField.setAccessible(true);
|
||||
declaredField.set(storageStrategyConfig, value);
|
||||
} catch (NoSuchFieldException | IllegalAccessException e) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("通过反射, 将字段 {" + key + "}注入 DriveConfigDTO 时出现异常:", e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
driveConfigDTO.setStorageStrategyConfig(storageStrategyConfig);
|
||||
return driveConfigDTO;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取指定驱动器的存储策略.
|
||||
*
|
||||
* @param id
|
||||
* 驱动器 ID
|
||||
*
|
||||
* @return 驱动器对应的存储策略.
|
||||
*/
|
||||
public StorageTypeEnum findStorageTypeById(Integer id) {
|
||||
// return findById(id).getType();
|
||||
return driverConfigRepository.findById(id).get().getType();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 保存驱动器基本信息及其对应的参数设置
|
||||
*
|
||||
* @param driveConfigDTO 驱动器 DTO 对象
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void save(DriveConfigDTO driveConfigDTO) {
|
||||
|
||||
// 判断是新增还是修改
|
||||
boolean updateFlag = driveConfigDTO.getId() != null;
|
||||
|
||||
// 保存基本信息
|
||||
DriveConfig driveConfig = new DriveConfig();
|
||||
StorageTypeEnum storageType = driveConfigDTO.getType();
|
||||
BeanUtils.copyProperties(driveConfigDTO, driveConfig);
|
||||
driverConfigRepository.save(driveConfig);
|
||||
|
||||
// 保存存储策略设置.
|
||||
StorageStrategyConfig storageStrategyConfig = driveConfigDTO.getStorageStrategyConfig();
|
||||
|
||||
AbstractBaseFileService storageTypeService = StorageTypeContext.getStorageTypeService(storageType);
|
||||
|
||||
List<StorageConfig> storageConfigList;
|
||||
if (updateFlag) {
|
||||
storageConfigList = storageConfigRepository.findByDriveId(driveConfigDTO.getId());
|
||||
} else {
|
||||
storageConfigList = storageTypeService.storageStrategyConfigList();
|
||||
}
|
||||
|
||||
for (StorageConfig storageConfig : storageConfigList) {
|
||||
String key = storageConfig.getKey();
|
||||
|
||||
try {
|
||||
Field field = STORAGE_STRATEGY_CONFIG_CLASS.getDeclaredField(key);
|
||||
field.setAccessible(true);
|
||||
Object o = field.get(storageStrategyConfig);
|
||||
String value = o == null ? null : o.toString();
|
||||
storageConfig.setValue(value);
|
||||
storageConfig.setType(storageType);
|
||||
storageConfig.setDriveId(driveConfig.getId());
|
||||
} catch (IllegalAccessException | NoSuchFieldException e) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("通过反射, 从 StorageStrategyConfig 中获取字段 {" + key + "} 时出现异常:", e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
storageConfigRepository.saveAll(storageConfigList);
|
||||
|
||||
driveContext.initDrive(driveConfig.getId());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 删除指定驱动器设置, 会级联删除其参数设置
|
||||
*
|
||||
* @param id
|
||||
* 驱动器 ID
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void deleteById(Integer id) {
|
||||
driverConfigRepository.deleteById(id);
|
||||
storageConfigRepository.deleteByDriveId(id);
|
||||
driveContext.destroyDrive(id);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 根据存储策略类型获取所有驱动器
|
||||
*
|
||||
* @param type
|
||||
* 存储类型
|
||||
*
|
||||
* @return 指定存储类型的存储器
|
||||
*/
|
||||
public List<DriveConfig> findByType(StorageTypeEnum type) {
|
||||
return driverConfigRepository.findByType(type);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 更新指定驱动器的缓存启用状态
|
||||
*
|
||||
* @param driveId
|
||||
* 驱动器 ID
|
||||
*
|
||||
* @param cacheEnable
|
||||
* 是否启用缓存
|
||||
*/
|
||||
public void updateCacheStatus(Integer driveId, Boolean cacheEnable) {
|
||||
DriveConfig driveConfig = findById(driveId);
|
||||
if (driveConfig != null) {
|
||||
driveConfig.setEnableCache(cacheEnable);
|
||||
driverConfigRepository.save(driveConfig);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -23,6 +23,9 @@ public class StorageConfigService {
|
||||
return storageConfigRepository.findByTypeOrderById(storageTypeEnum);
|
||||
}
|
||||
|
||||
public List<StorageConfig> selectStorageConfigByDriveId(Integer driveId) {
|
||||
return storageConfigRepository.findByDriveIdOrderById(driveId);
|
||||
}
|
||||
|
||||
public StorageConfig selectByTypeAndKey(StorageTypeEnum storageType, String key) {
|
||||
return storageConfigRepository.findByTypeAndKey(storageType, key);
|
||||
@@ -38,8 +41,19 @@ public class StorageConfigService {
|
||||
}
|
||||
|
||||
|
||||
public Map<String, StorageConfig> selectStorageConfigMapByDriveId(Integer driveId) {
|
||||
Map<String, StorageConfig> map = new HashMap<>(24);
|
||||
for (StorageConfig storageConfig : selectStorageConfigByDriveId(driveId)) {
|
||||
map.put(storageConfig.getKey(), storageConfig);
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
|
||||
public void updateStorageConfig(List<StorageConfig> storageConfigList) {
|
||||
storageConfigRepository.saveAll(storageConfigList);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -1,17 +1,16 @@
|
||||
package im.zhaojun.zfile.service;
|
||||
|
||||
import cn.hutool.core.convert.Convert;
|
||||
import cn.hutool.core.util.BooleanUtil;
|
||||
import cn.hutool.crypto.SecureUtil;
|
||||
import im.zhaojun.zfile.cache.ZFileCache;
|
||||
import im.zhaojun.zfile.config.StorageTypeFactory;
|
||||
import im.zhaojun.zfile.model.constant.SystemConfigConstant;
|
||||
import im.zhaojun.zfile.model.dto.SystemConfigDTO;
|
||||
import im.zhaojun.zfile.model.dto.SystemFrontConfigDTO;
|
||||
import im.zhaojun.zfile.model.entity.DriveConfig;
|
||||
import im.zhaojun.zfile.model.entity.SystemConfig;
|
||||
import im.zhaojun.zfile.model.enums.StorageTypeEnum;
|
||||
import im.zhaojun.zfile.repository.SystemConfigRepository;
|
||||
import im.zhaojun.zfile.service.base.AbstractBaseFileService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
@@ -32,8 +31,17 @@ public class SystemConfigService {
|
||||
@Resource
|
||||
private SystemConfigRepository systemConfigRepository;
|
||||
|
||||
@Resource
|
||||
private DriveConfigService driveConfigService;
|
||||
|
||||
private Class<SystemConfigDTO> systemConfigClazz = SystemConfigDTO.class;
|
||||
|
||||
|
||||
/**
|
||||
* 获取系统设置, 如果缓存中有, 则去缓存取, 没有则查询数据库并写入到缓存中.
|
||||
*
|
||||
* @return 系统设置
|
||||
*/
|
||||
public SystemConfigDTO getSystemConfig() {
|
||||
SystemConfigDTO cacheConfig = zFileCache.getConfig();
|
||||
if (cacheConfig != null) {
|
||||
@@ -48,12 +56,10 @@ public class SystemConfigService {
|
||||
|
||||
try {
|
||||
Field field = systemConfigClazz.getDeclaredField(key);
|
||||
if (field != null) {
|
||||
field.setAccessible(true);
|
||||
String strVal = systemConfig.getValue();
|
||||
Object convertVal = Convert.convert(field.getType(), strVal);
|
||||
field.set(systemConfigDTO, convertVal);
|
||||
}
|
||||
field.setAccessible(true);
|
||||
String strVal = systemConfig.getValue();
|
||||
Object convertVal = Convert.convert(field.getType(), strVal);
|
||||
field.set(systemConfigDTO, convertVal);
|
||||
} catch (NoSuchFieldException | IllegalAccessException e) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("通过反射, 将字段 {" + key + "}注入 SystemConfigDTO 时出现异常:", e);
|
||||
@@ -66,7 +72,14 @@ public class SystemConfigService {
|
||||
}
|
||||
|
||||
|
||||
public void updateSystemConfig(SystemConfigDTO systemConfigDTO) throws Exception {
|
||||
/**
|
||||
* 更新系统设置, 并清空缓存中的内容.
|
||||
*
|
||||
* @param systemConfigDTO
|
||||
* 系统
|
||||
*
|
||||
*/
|
||||
public void updateSystemConfig(SystemConfigDTO systemConfigDTO) {
|
||||
List<SystemConfig> systemConfigList = new ArrayList<>();
|
||||
|
||||
Field[] fields = systemConfigClazz.getDeclaredFields();
|
||||
@@ -75,7 +88,16 @@ public class SystemConfigService {
|
||||
SystemConfig systemConfig = systemConfigRepository.findByKey(key);
|
||||
if (systemConfig != null) {
|
||||
field.setAccessible(true);
|
||||
Object val = field.get(systemConfigDTO);
|
||||
Object val = null;
|
||||
|
||||
try {
|
||||
val = field.get(systemConfigDTO);
|
||||
} catch (IllegalAccessException e) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("通过反射, 从 SystemConfigDTO 获取字段 {" + key + "} 时出现异常:", e);
|
||||
}
|
||||
}
|
||||
|
||||
if (val != null) {
|
||||
systemConfig.setValue(val.toString());
|
||||
systemConfigList.add(systemConfig);
|
||||
@@ -88,6 +110,34 @@ public class SystemConfigService {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 根据驱动器 ID, 获取对于前台页面的系统设置.
|
||||
*
|
||||
* @param driveId
|
||||
* 驱动器 ID
|
||||
*
|
||||
* @return 前台系统设置
|
||||
*/
|
||||
public SystemFrontConfigDTO getSystemFrontConfig(Integer driveId) {
|
||||
SystemConfigDTO systemConfig = getSystemConfig();
|
||||
SystemFrontConfigDTO systemFrontConfigDTO = new SystemFrontConfigDTO();
|
||||
BeanUtils.copyProperties(systemConfig, systemFrontConfigDTO);
|
||||
|
||||
DriveConfig driveConfig = driveConfigService.findById(driveId);
|
||||
systemFrontConfigDTO.setSearchEnable(driveConfig.getSearchEnable());
|
||||
return systemFrontConfigDTO;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 更新后台账号密码
|
||||
*
|
||||
* @param username
|
||||
* 用户名
|
||||
*
|
||||
* @param password
|
||||
* 密码
|
||||
*/
|
||||
public void updateUsernameAndPwd(String username, String password) {
|
||||
SystemConfig usernameConfig = systemConfigRepository.findByKey(SystemConfigConstant.USERNAME);
|
||||
usernameConfig.setValue(username);
|
||||
@@ -103,34 +153,14 @@ public class SystemConfigService {
|
||||
}
|
||||
|
||||
|
||||
public void updateCacheEnableConfig(Boolean isEnable) {
|
||||
SystemConfig enableConfig = systemConfigRepository.findByKey(SystemConfigConstant.ENABLE_CACHE);
|
||||
enableConfig.setValue(isEnable.toString());
|
||||
systemConfigRepository.save(enableConfig);
|
||||
zFileCache.removeConfig();
|
||||
}
|
||||
|
||||
|
||||
public AbstractBaseFileService getCurrentFileService() {
|
||||
StorageTypeEnum storageStrategy = getCurrentStorageStrategy();
|
||||
return StorageTypeFactory.getStorageTypeService(storageStrategy);
|
||||
}
|
||||
|
||||
|
||||
public StorageTypeEnum getCurrentStorageStrategy() {
|
||||
/**
|
||||
* 获取管理员名称
|
||||
*
|
||||
* @return 管理员名称
|
||||
*/
|
||||
public String getAdminUsername() {
|
||||
SystemConfigDTO systemConfigDTO = getSystemConfig();
|
||||
return systemConfigDTO.getStorageStrategy();
|
||||
return systemConfigDTO.getUsername();
|
||||
}
|
||||
|
||||
public boolean getEnableCache() {
|
||||
SystemConfigDTO systemConfigDTO = getSystemConfig();
|
||||
return BooleanUtil.isTrue(systemConfigDTO.getEnableCache());
|
||||
}
|
||||
|
||||
public boolean getSearchIgnoreCase() {
|
||||
SystemConfigDTO systemConfigDTO = getSystemConfig();
|
||||
return BooleanUtil.isTrue(systemConfigDTO.getSearchIgnoreCase());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,67 +1,69 @@
|
||||
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.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 SystemConfigService systemConfigService;
|
||||
|
||||
/**
|
||||
* 构建指定路径下标题, 页面文档信息
|
||||
* @param path 路径
|
||||
*/
|
||||
public SiteConfigDTO getConfig(String path) throws Exception {
|
||||
|
||||
SiteConfigDTO siteConfigDTO = new SiteConfigDTO();
|
||||
AbstractBaseFileService fileService = systemConfigService.getCurrentFileService();
|
||||
|
||||
List<FileItemDTO> fileItemList;
|
||||
|
||||
if (Objects.equals(systemConfigService.getSystemConfig().getStorageStrategy(), 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;
|
||||
}
|
||||
|
||||
}
|
||||
// package im.zhaojun.zfile.service;
|
||||
//
|
||||
// import im.zhaojun.zfile.model.constant.ZFileConstant;
|
||||
// import im.zhaojun.zfile.model.dto.FileItemDTO;
|
||||
// import im.zhaojun.zfile.model.dto.SiteConfigDTO;
|
||||
// import im.zhaojun.zfile.model.enums.StorageTypeEnum;
|
||||
// import im.zhaojun.zfile.service.base.AbstractBaseFileService;
|
||||
// import im.zhaojun.zfile.context.DriveContext;
|
||||
// import im.zhaojun.zfile.util.HttpUtil;
|
||||
// import im.zhaojun.zfile.util.StringUtils;
|
||||
// import lombok.extern.slf4j.Slf4j;
|
||||
// import org.springframework.stereotype.Service;
|
||||
// import org.springframework.web.client.HttpClientErrorException;
|
||||
//
|
||||
// import javax.annotation.Resource;
|
||||
// import java.util.ArrayList;
|
||||
// import java.util.List;
|
||||
// import java.util.Objects;
|
||||
//
|
||||
// /**
|
||||
// * @author zhaojun
|
||||
// */
|
||||
// @Slf4j
|
||||
// @Service
|
||||
// public class SystemService {
|
||||
//
|
||||
// @Resource
|
||||
// private DriveContext driveContext;
|
||||
//
|
||||
// /**
|
||||
// * 构建指定路径下标题, 页面文档信息
|
||||
// * @param path 路径
|
||||
// */
|
||||
// public SiteConfigDTO getConfig(Integer driveId, String path) throws Exception {
|
||||
//
|
||||
// SiteConfigDTO siteConfigDTO = new SiteConfigDTO();
|
||||
//
|
||||
// AbstractBaseFileService fileService = driveContext.getDriveService(driveId);
|
||||
//
|
||||
// List<FileItemDTO> fileItemList;
|
||||
//
|
||||
// if (Objects.equals(fileService.getStorageTypeEnum(), StorageTypeEnum.FTP)) {
|
||||
// fileItemList = new ArrayList<>();
|
||||
// } else {
|
||||
// fileItemList = fileService.fileList(path);
|
||||
// }
|
||||
//
|
||||
// for (FileItemDTO fileItemDTO : fileItemList) {
|
||||
// if (ZFileConstant.README_FILE_NAME.equalsIgnoreCase(fileItemDTO.getName())) {
|
||||
// String textContent = null;
|
||||
// try {
|
||||
// textContent = HttpUtil.getTextContent(fileItemDTO.getUrl());
|
||||
// } catch (HttpClientErrorException httpClientErrorException) {
|
||||
// log.debug("尝试重新获取文档区缓存中链接后仍失败", httpClientErrorException);
|
||||
// try {
|
||||
// String fullPath = StringUtils.removeDuplicateSeparator(fileItemDTO.getPath() + "/" + fileItemDTO.getName());
|
||||
// FileItemDTO fileItem = fileService.getFileItem(fullPath);
|
||||
// textContent = HttpUtil.getTextContent(fileItem.getUrl());
|
||||
// } catch (Exception e) {
|
||||
// log.debug("尝试重新获取文档区链接后仍失败, 已置为空", e);
|
||||
// }
|
||||
// }
|
||||
// siteConfigDTO.setReadme(textContent);
|
||||
// }
|
||||
// }
|
||||
// return siteConfigDTO;
|
||||
// }
|
||||
//
|
||||
// }
|
||||
|
||||
@@ -1,18 +1,14 @@
|
||||
package im.zhaojun.zfile.service.base;
|
||||
|
||||
import cn.hutool.core.util.BooleanUtil;
|
||||
import im.zhaojun.zfile.cache.ZFileCache;
|
||||
import im.zhaojun.zfile.model.dto.FileItemDTO;
|
||||
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.service.SystemConfigService;
|
||||
import im.zhaojun.zfile.service.support.FileAsyncCacheService;
|
||||
import im.zhaojun.zfile.service.support.FileCacheService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.aop.framework.AopContext;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
|
||||
@@ -20,49 +16,69 @@ import java.util.List;
|
||||
* @author zhaojun
|
||||
*/
|
||||
@Slf4j
|
||||
public abstract class AbstractBaseFileService extends FileCacheService implements BaseFileService {
|
||||
public abstract class AbstractBaseFileService implements BaseFileService {
|
||||
|
||||
/**
|
||||
* 下载链接过期时间, 目前只在兼容 S3 协议的存储策略中使用到.
|
||||
*/
|
||||
@Value("${zfile.cache.timeout}")
|
||||
protected Long timeout;
|
||||
|
||||
/**
|
||||
* 是否初始化成功
|
||||
*/
|
||||
protected boolean isInitialized = false;
|
||||
|
||||
/**
|
||||
* 基路径
|
||||
*/
|
||||
protected String basePath;
|
||||
|
||||
/**
|
||||
* 驱动器 ID
|
||||
*/
|
||||
public Integer driveId;
|
||||
|
||||
@Resource
|
||||
private SystemConfigService systemConfigService;
|
||||
|
||||
@Resource
|
||||
private FileAsyncCacheService fileAsyncCacheService;
|
||||
|
||||
@Resource
|
||||
private ZFileCache zFileCache;
|
||||
|
||||
|
||||
/***
|
||||
* 获取指定路径下的文件及文件夹, 默认缓存 60 分钟,每隔 30 分钟刷新一次.
|
||||
* @param path 文件路径
|
||||
* @return 文件及文件夹列表
|
||||
*
|
||||
* @param path
|
||||
* 文件路径
|
||||
*
|
||||
* @return 文件及文件夹列表
|
||||
*
|
||||
* @throws Exception 获取文件列表中出现的异常
|
||||
*/
|
||||
@Override
|
||||
public abstract List<FileItemDTO> fileList(String path) throws Exception;
|
||||
|
||||
|
||||
/**
|
||||
* 清理当前存储策略的缓存
|
||||
* 1. 删除全部缓存
|
||||
* 2. 标记为当前处于未完成缓存状态
|
||||
*/
|
||||
public void clearFileCache() {
|
||||
zFileCache.clear();
|
||||
fileAsyncCacheService.setCacheFinish(false);
|
||||
zFileCache.clear(driveId);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 初始化方法, 启动时自动调用实现类的此方法进行初始化.
|
||||
*/
|
||||
@PostConstruct
|
||||
public abstract void init();
|
||||
public abstract void init(Integer driveId);
|
||||
|
||||
|
||||
/**
|
||||
* 测试是否连接成功, 会尝试取调用获取根路径的文件, 如果没有抛出异常, 则认为连接成功, 某些存储策略需要复写此方法.
|
||||
*
|
||||
* @return 连接结果
|
||||
*/
|
||||
protected boolean testConnection() {
|
||||
boolean flag = true;
|
||||
try {
|
||||
@@ -74,55 +90,79 @@ public abstract class AbstractBaseFileService extends FileCacheService implement
|
||||
return flag;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取是否初始化成功
|
||||
* @return 初始化成功与否
|
||||
*
|
||||
* @return 初始化成功与否
|
||||
*/
|
||||
public boolean getIsUnInitialized() {
|
||||
return !isInitialized;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取是否初始化成功
|
||||
* @return 初始化成功与否
|
||||
*
|
||||
* @return 初始化成功与否
|
||||
*/
|
||||
public boolean getIsInitialized() {
|
||||
return isInitialized;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取存储策略类型
|
||||
* @return 存储策略类型枚举
|
||||
* 获取当前实现类的存储策略类型
|
||||
*
|
||||
* @return 存储策略类型枚举对象
|
||||
*/
|
||||
public abstract StorageTypeEnum getStorageTypeEnum();
|
||||
|
||||
|
||||
/**
|
||||
* 获取初始化当前存储策略, 所需要的参数信息 (表单填写)
|
||||
*
|
||||
* @return 初始化所需的参数列表
|
||||
*/
|
||||
public abstract List<StorageConfig> storageStrategyConfigList();
|
||||
|
||||
|
||||
/**
|
||||
* 搜索文件
|
||||
* @param name 文件名
|
||||
* @return 包含该文件名的所有文件或文件夹
|
||||
*
|
||||
* @param name
|
||||
* 文件名
|
||||
*
|
||||
* @return 包含该文件名的所有文件或文件夹
|
||||
*/
|
||||
public List<FileItemDTO> search(String name) {
|
||||
SystemConfigDTO systemConfig = systemConfigService.getSystemConfig();
|
||||
|
||||
boolean searchIgnoreCase = BooleanUtil.isTrue(systemConfig.getSearchIgnoreCase());
|
||||
boolean searchContainEncryptedFile = BooleanUtil.isTrue(systemConfig.getSearchContainEncryptedFile());
|
||||
return zFileCache.find(name, searchIgnoreCase, searchContainEncryptedFile);
|
||||
return zFileCache.find(driveId, name);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 刷新缓存
|
||||
* 刷新指定 key 的缓存:
|
||||
* 1. 清空此 key 的缓存.
|
||||
* 2. 重新调用方法写入缓存.
|
||||
*
|
||||
* @param key
|
||||
* 缓存 key (文件夹名称)
|
||||
*/
|
||||
public void refreshCache(String key) throws Exception {
|
||||
zFileCache.remove(key);
|
||||
zFileCache.remove(driveId, key);
|
||||
BaseFileService currentFileService = (BaseFileService) AopContext.currentProxy();
|
||||
currentFileService.fileList(key);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取单个文件信息
|
||||
* @param path 文件路径
|
||||
*
|
||||
* @param path
|
||||
* 文件路径
|
||||
*
|
||||
* @return 单个文件的内容.
|
||||
*/
|
||||
public abstract FileItemDTO getFileItem(String path);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -7,16 +7,17 @@ import cn.hutool.http.HttpUtil;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONArray;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import im.zhaojun.zfile.model.constant.ZFileConstant;
|
||||
import im.zhaojun.zfile.model.entity.StorageConfig;
|
||||
import im.zhaojun.zfile.model.constant.StorageConfigConstant;
|
||||
import im.zhaojun.zfile.model.constant.ZFileConstant;
|
||||
import im.zhaojun.zfile.model.dto.FileItemDTO;
|
||||
import im.zhaojun.zfile.model.entity.StorageConfig;
|
||||
import im.zhaojun.zfile.model.enums.FileTypeEnum;
|
||||
import im.zhaojun.zfile.model.support.OneDriveToken;
|
||||
import im.zhaojun.zfile.repository.StorageConfigRepository;
|
||||
import im.zhaojun.zfile.service.StorageConfigService;
|
||||
import im.zhaojun.zfile.util.StringUtils;
|
||||
import im.zhaojun.zfile.model.support.OneDriveToken;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.client.HttpClientErrorException;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
@@ -28,7 +29,6 @@ import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Zhao Jun
|
||||
* 2020/1/29 11:54
|
||||
*/
|
||||
@Slf4j
|
||||
public abstract class AbstractOneDriveServiceBase extends AbstractBaseFileService {
|
||||
@@ -46,6 +46,7 @@ public abstract class AbstractOneDriveServiceBase extends AbstractBaseFileServic
|
||||
private static final String ONE_DRIVE_FILE_FLAG = "file";
|
||||
|
||||
@Resource
|
||||
@Lazy
|
||||
private RestTemplate oneDriveRestTemplate;
|
||||
|
||||
@Resource
|
||||
@@ -54,6 +55,11 @@ public abstract class AbstractOneDriveServiceBase extends AbstractBaseFileServic
|
||||
@Resource
|
||||
private StorageConfigService storageConfigService;
|
||||
|
||||
/**
|
||||
* 根据 RefreshToken 刷新 AccessToken, 返回刷新后的 Token.
|
||||
*
|
||||
* @return 刷新后的 Token
|
||||
*/
|
||||
public OneDriveToken getRefreshToken() {
|
||||
StorageConfig refreshStorageConfig =
|
||||
storageConfigRepository.findByTypeAndKey(this.getStorageTypeEnum(), StorageConfigConstant.REFRESH_TOKEN_KEY);
|
||||
@@ -72,6 +78,14 @@ public abstract class AbstractOneDriveServiceBase extends AbstractBaseFileServic
|
||||
return JSONObject.parseObject(response.body(), OneDriveToken.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* OAuth2 协议中, 根据 code 换取 access_token 和 refresh_token.
|
||||
*
|
||||
* @param code
|
||||
* 代码
|
||||
*
|
||||
* @return 获取的 Token 信息.
|
||||
*/
|
||||
public OneDriveToken getToken(String code) {
|
||||
String param = "client_id=" + getClientId() +
|
||||
"&redirect_uri=" + getRedirectUri() +
|
||||
@@ -88,10 +102,6 @@ public abstract class AbstractOneDriveServiceBase extends AbstractBaseFileServic
|
||||
return JSONObject.parseObject(response.body(), OneDriveToken.class);
|
||||
}
|
||||
|
||||
public String getUserInfo() {
|
||||
return oneDriveRestTemplate.getForObject(DRIVER_INFO_URL, String.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<FileItemDTO> fileList(String path) {
|
||||
path = StringUtils.removeFirstSeparator(path);
|
||||
@@ -211,4 +221,14 @@ public abstract class AbstractOneDriveServiceBase extends AbstractBaseFileServic
|
||||
|
||||
storageConfigService.updateStorageConfig(Arrays.asList(accessTokenConfig, refreshTokenConfig));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<StorageConfig> storageStrategyConfigList() {
|
||||
return new ArrayList<StorageConfig>() {{
|
||||
add(new StorageConfig("accessToken", "访问令牌"));
|
||||
add(new StorageConfig("refreshToken", "刷新令牌"));
|
||||
add(new StorageConfig("basePath", "基路径"));
|
||||
}};
|
||||
}
|
||||
|
||||
}
|
||||
@@ -6,10 +6,10 @@ import com.amazonaws.services.s3.AmazonS3;
|
||||
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.service.StorageConfigService;
|
||||
import im.zhaojun.zfile.exception.NotExistFileException;
|
||||
import im.zhaojun.zfile.model.dto.FileItemDTO;
|
||||
import im.zhaojun.zfile.model.enums.FileTypeEnum;
|
||||
import im.zhaojun.zfile.service.StorageConfigService;
|
||||
import im.zhaojun.zfile.util.StringUtils;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
@@ -5,14 +5,15 @@ import com.amazonaws.auth.AWSStaticCredentialsProvider;
|
||||
import com.amazonaws.auth.BasicAWSCredentials;
|
||||
import com.amazonaws.client.builder.AwsClientBuilder;
|
||||
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
|
||||
import im.zhaojun.zfile.model.dto.StorageStrategyDTO;
|
||||
import im.zhaojun.zfile.model.entity.StorageConfig;
|
||||
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.base.AbstractS3BaseFileService;
|
||||
import im.zhaojun.zfile.service.base.BaseFileService;
|
||||
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 java.util.ArrayList;
|
||||
@@ -24,15 +25,17 @@ import java.util.Objects;
|
||||
* @author zhaojun
|
||||
*/
|
||||
@Service
|
||||
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
|
||||
public class AliyunServiceImpl extends AbstractS3BaseFileService implements BaseFileService {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(AliyunServiceImpl.class);
|
||||
|
||||
@Override
|
||||
public void init() {
|
||||
public void init(Integer driveId) {
|
||||
try {
|
||||
this.driveId = driveId;
|
||||
Map<String, StorageConfig> stringStorageConfigMap =
|
||||
storageConfigService.selectStorageConfigMapByKey(getStorageTypeEnum());
|
||||
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();
|
||||
@@ -64,14 +67,14 @@ public class AliyunServiceImpl extends AbstractS3BaseFileService implements Base
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<StorageConfig> storageStrategyList() {
|
||||
public List<StorageConfig> storageStrategyConfigList() {
|
||||
return new ArrayList<StorageConfig>() {{
|
||||
add(new StorageConfig("accessKey", "AccessKey"));
|
||||
add(new StorageConfig("secretKey", "SecretKey"));
|
||||
add(new StorageConfig("bucket-name", "Bucket 名称"));
|
||||
add(new StorageConfig("bucketName", "Bucket 名称"));
|
||||
add(new StorageConfig("domain", "Bucket 域名 / CDN 加速域名"));
|
||||
add(new StorageConfig("endPoint", "区域"));
|
||||
add(new StorageConfig("base-path", "基路径"));
|
||||
add(new StorageConfig("basePath", "基路径"));
|
||||
}};
|
||||
}
|
||||
}
|
||||
@@ -16,6 +16,8 @@ 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;
|
||||
@@ -29,6 +31,7 @@ import java.util.Objects;
|
||||
* @author zhaojun
|
||||
*/
|
||||
@Service
|
||||
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
|
||||
public class FtpServiceImpl extends AbstractBaseFileService implements BaseFileService {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(FtpServiceImpl.class);
|
||||
@@ -49,10 +52,11 @@ public class FtpServiceImpl extends AbstractBaseFileService implements BaseFileS
|
||||
private String password;
|
||||
|
||||
@Override
|
||||
public void init() {
|
||||
public void init(Integer driveId) {
|
||||
try {
|
||||
this.driveId = driveId;
|
||||
Map<String, StorageConfig> stringStorageConfigMap =
|
||||
storageConfigService.selectStorageConfigMapByKey(getStorageTypeEnum());
|
||||
storageConfigService.selectStorageConfigMapByDriveId(driveId);
|
||||
host = stringStorageConfigMap.get(StorageConfigConstant.HOST_KEY).getValue();
|
||||
port = stringStorageConfigMap.get(StorageConfigConstant.PORT_KEY).getValue();
|
||||
username = stringStorageConfigMap.get(StorageConfigConstant.USERNAME_KEY).getValue();
|
||||
@@ -131,14 +135,14 @@ public class FtpServiceImpl extends AbstractBaseFileService implements BaseFileS
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<StorageConfig> storageStrategyList() {
|
||||
public List<StorageConfig> storageStrategyConfigList() {
|
||||
return new ArrayList<StorageConfig>() {{
|
||||
add(new StorageConfig("host", "域名或IP"));
|
||||
add(new StorageConfig("port", "端口"));
|
||||
add(new StorageConfig("username", "用户名"));
|
||||
add(new StorageConfig("password", "密码"));
|
||||
add(new StorageConfig("domain", "加速域名"));
|
||||
add(new StorageConfig("base-path", "基路径"));
|
||||
add(new StorageConfig("basePath", "基路径"));
|
||||
}};
|
||||
}
|
||||
}
|
||||
@@ -5,13 +5,15 @@ import com.amazonaws.auth.AWSStaticCredentialsProvider;
|
||||
import com.amazonaws.auth.BasicAWSCredentials;
|
||||
import com.amazonaws.client.builder.AwsClientBuilder;
|
||||
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
|
||||
import im.zhaojun.zfile.model.entity.StorageConfig;
|
||||
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.base.AbstractS3BaseFileService;
|
||||
import im.zhaojun.zfile.service.base.BaseFileService;
|
||||
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 java.util.ArrayList;
|
||||
@@ -23,15 +25,17 @@ import java.util.Objects;
|
||||
* @author zhaojun
|
||||
*/
|
||||
@Service
|
||||
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
|
||||
public class HuaweiServiceImpl extends AbstractS3BaseFileService implements BaseFileService {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(HuaweiServiceImpl.class);
|
||||
|
||||
@Override
|
||||
public void init() {
|
||||
public void init(Integer driveId) {
|
||||
try {
|
||||
this.driveId = driveId;
|
||||
Map<String, StorageConfig> stringStorageConfigMap =
|
||||
storageConfigService.selectStorageConfigMapByKey(getStorageTypeEnum());
|
||||
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();
|
||||
@@ -63,14 +67,14 @@ public class HuaweiServiceImpl extends AbstractS3BaseFileService implements Base
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<StorageConfig> storageStrategyList() {
|
||||
public List<StorageConfig> storageStrategyConfigList() {
|
||||
return new ArrayList<StorageConfig>() {{
|
||||
add(new StorageConfig("accessKey", "AccessKey"));
|
||||
add(new StorageConfig("secretKey", "SecretKey"));
|
||||
add(new StorageConfig("bucket-name", "云存储服务名称"));
|
||||
add(new StorageConfig("bucketName", "云存储服务名称"));
|
||||
add(new StorageConfig("domain", "加速域名"));
|
||||
add(new StorageConfig("endPoint", "区域"));
|
||||
add(new StorageConfig("base-path", "基路径"));
|
||||
add(new StorageConfig("basePath", "基路径"));
|
||||
add(new StorageConfig("isPrivate", "是否是私有空间"));
|
||||
}};
|
||||
}
|
||||
|
||||
@@ -1,20 +1,22 @@
|
||||
package im.zhaojun.zfile.service.impl;
|
||||
|
||||
import im.zhaojun.zfile.exception.NotExistFileException;
|
||||
import im.zhaojun.zfile.model.entity.StorageConfig;
|
||||
import im.zhaojun.zfile.model.entity.SystemConfig;
|
||||
import im.zhaojun.zfile.model.constant.StorageConfigConstant;
|
||||
import im.zhaojun.zfile.model.constant.SystemConfigConstant;
|
||||
import im.zhaojun.zfile.model.dto.FileItemDTO;
|
||||
import im.zhaojun.zfile.model.entity.StorageConfig;
|
||||
import im.zhaojun.zfile.model.entity.SystemConfig;
|
||||
import im.zhaojun.zfile.model.enums.FileTypeEnum;
|
||||
import im.zhaojun.zfile.model.enums.StorageTypeEnum;
|
||||
import im.zhaojun.zfile.repository.SystemConfigRepository;
|
||||
import im.zhaojun.zfile.service.StorageConfigService;
|
||||
import im.zhaojun.zfile.service.base.AbstractBaseFileService;
|
||||
import im.zhaojun.zfile.service.base.BaseFileService;
|
||||
import im.zhaojun.zfile.service.StorageConfigService;
|
||||
import im.zhaojun.zfile.util.StringUtils;
|
||||
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;
|
||||
@@ -29,6 +31,7 @@ import java.util.Objects;
|
||||
* @author zhaojun
|
||||
*/
|
||||
@Service
|
||||
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
|
||||
public class LocalServiceImpl extends AbstractBaseFileService implements BaseFileService {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(LocalServiceImpl.class);
|
||||
@@ -42,10 +45,11 @@ public class LocalServiceImpl extends AbstractBaseFileService implements BaseFil
|
||||
private String filePath;
|
||||
|
||||
@Override
|
||||
public void init() {
|
||||
public void init(Integer driveId) {
|
||||
try {
|
||||
this.driveId = driveId;
|
||||
Map<String, StorageConfig> stringStorageConfigMap =
|
||||
storageConfigService.selectStorageConfigMapByKey(getStorageTypeEnum());
|
||||
storageConfigService.selectStorageConfigMapByDriveId(driveId);
|
||||
filePath = stringStorageConfigMap.get(StorageConfigConstant.FILE_PATH_KEY).getValue();
|
||||
if (Objects.isNull(filePath)) {
|
||||
log.debug("初始化存储策略 [{}] 失败: 参数不完整", getStorageTypeEnum().getDescription());
|
||||
@@ -89,7 +93,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/" + path);
|
||||
return StringUtils.removeDuplicateSeparator(usernameConfig.getValue() + "/file/" + driveId + "/" + path);
|
||||
}
|
||||
|
||||
public String getFilePath() {
|
||||
@@ -129,7 +133,7 @@ public class LocalServiceImpl extends AbstractBaseFileService implements BaseFil
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<StorageConfig> storageStrategyList() {
|
||||
public List<StorageConfig> storageStrategyConfigList() {
|
||||
return new ArrayList<StorageConfig>() {{
|
||||
add(new StorageConfig("filePath", "文件路径"));
|
||||
}};
|
||||
|
||||
@@ -5,13 +5,15 @@ import com.amazonaws.auth.AWSStaticCredentialsProvider;
|
||||
import com.amazonaws.auth.BasicAWSCredentials;
|
||||
import com.amazonaws.client.builder.AwsClientBuilder;
|
||||
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
|
||||
import im.zhaojun.zfile.model.entity.StorageConfig;
|
||||
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.base.AbstractS3BaseFileService;
|
||||
import im.zhaojun.zfile.service.base.BaseFileService;
|
||||
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 java.util.ArrayList;
|
||||
@@ -23,15 +25,17 @@ import java.util.Objects;
|
||||
* @author zhaojun
|
||||
*/
|
||||
@Service
|
||||
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
|
||||
public class MinIOServiceImpl extends AbstractS3BaseFileService implements BaseFileService {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(MinIOServiceImpl.class);
|
||||
|
||||
@Override
|
||||
public void init() {
|
||||
public void init(Integer driveId) {
|
||||
try {
|
||||
this.driveId = driveId;
|
||||
Map<String, StorageConfig> stringStorageConfigMap =
|
||||
storageConfigService.selectStorageConfigMapByKey(getStorageTypeEnum());
|
||||
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();
|
||||
@@ -64,13 +68,13 @@ public class MinIOServiceImpl extends AbstractS3BaseFileService implements BaseF
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<StorageConfig> storageStrategyList() {
|
||||
public List<StorageConfig> storageStrategyConfigList() {
|
||||
return new ArrayList<StorageConfig>() {{
|
||||
add(new StorageConfig("accessKey", "AccessKey"));
|
||||
add(new StorageConfig("secretKey", "SecretKey"));
|
||||
add(new StorageConfig("endPoint", "服务地址"));
|
||||
add(new StorageConfig("bucket-name", "存储空间名称"));
|
||||
add(new StorageConfig("base-path", "基路径"));
|
||||
add(new StorageConfig("bucketName", "存储空间名称"));
|
||||
add(new StorageConfig("basePath", "基路径"));
|
||||
add(new StorageConfig("isPrivate", "是否是私有空间"));
|
||||
}};
|
||||
}
|
||||
|
||||
@@ -8,6 +8,8 @@ import im.zhaojun.zfile.service.base.AbstractOneDriveServiceBase;
|
||||
import im.zhaojun.zfile.service.base.BaseFileService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
|
||||
import org.springframework.context.annotation.Scope;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
@@ -19,6 +21,7 @@ import java.util.Map;
|
||||
*/
|
||||
@Service
|
||||
@Slf4j
|
||||
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
|
||||
public class OneDriveChinaServiceImpl extends AbstractOneDriveServiceBase implements BaseFileService {
|
||||
|
||||
@Resource
|
||||
@@ -37,10 +40,11 @@ public class OneDriveChinaServiceImpl extends AbstractOneDriveServiceBase implem
|
||||
private String scope;
|
||||
|
||||
@Override
|
||||
public void init() {
|
||||
public void init(Integer driveId) {
|
||||
try {
|
||||
this.driveId = driveId;
|
||||
Map<String, StorageConfig> stringStorageConfigMap =
|
||||
storageConfigService.selectStorageConfigMapByKey(getStorageTypeEnum());
|
||||
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();
|
||||
|
||||
@@ -8,6 +8,8 @@ import im.zhaojun.zfile.service.base.AbstractOneDriveServiceBase;
|
||||
import im.zhaojun.zfile.service.base.BaseFileService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
|
||||
import org.springframework.context.annotation.Scope;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
@@ -19,6 +21,7 @@ import java.util.Map;
|
||||
*/
|
||||
@Service
|
||||
@Slf4j
|
||||
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
|
||||
public class OneDriveServiceImpl extends AbstractOneDriveServiceBase implements BaseFileService {
|
||||
|
||||
@Resource
|
||||
@@ -37,10 +40,11 @@ public class OneDriveServiceImpl extends AbstractOneDriveServiceBase implements
|
||||
protected String scope;
|
||||
|
||||
@Override
|
||||
public void init() {
|
||||
public void init(Integer driveId) {
|
||||
try {
|
||||
this.driveId = driveId;
|
||||
Map<String, StorageConfig> stringStorageConfigMap =
|
||||
storageConfigService.selectStorageConfigMapByKey(getStorageTypeEnum());
|
||||
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();
|
||||
|
||||
@@ -5,13 +5,15 @@ import com.amazonaws.auth.AWSStaticCredentialsProvider;
|
||||
import com.amazonaws.auth.BasicAWSCredentials;
|
||||
import com.amazonaws.client.builder.AwsClientBuilder;
|
||||
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
|
||||
import im.zhaojun.zfile.model.entity.StorageConfig;
|
||||
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.base.AbstractS3BaseFileService;
|
||||
import im.zhaojun.zfile.service.base.BaseFileService;
|
||||
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 java.util.ArrayList;
|
||||
@@ -23,15 +25,17 @@ import java.util.Objects;
|
||||
* @author zhaojun
|
||||
*/
|
||||
@Service
|
||||
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
|
||||
public class QiniuServiceImpl extends AbstractS3BaseFileService implements BaseFileService {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(QiniuServiceImpl.class);
|
||||
|
||||
@Override
|
||||
public void init() {
|
||||
public void init(Integer driveId) {
|
||||
try {
|
||||
this.driveId = driveId;
|
||||
Map<String, StorageConfig> stringStorageConfigMap =
|
||||
storageConfigService.selectStorageConfigMapByKey(getStorageTypeEnum());
|
||||
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();
|
||||
@@ -63,14 +67,14 @@ public class QiniuServiceImpl extends AbstractS3BaseFileService implements BaseF
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<StorageConfig> storageStrategyList() {
|
||||
public List<StorageConfig> storageStrategyConfigList() {
|
||||
return new ArrayList<StorageConfig>() {{
|
||||
add(new StorageConfig("accessKey", "AccessKey"));
|
||||
add(new StorageConfig("secretKey", "SecretKey"));
|
||||
add(new StorageConfig("bucket-name", "存储空间名称"));
|
||||
add(new StorageConfig("bucketName", "存储空间名称"));
|
||||
add(new StorageConfig("domain", "加速域名"));
|
||||
add(new StorageConfig("endPoint", "区域"));
|
||||
add(new StorageConfig("base-path", "基路径"));
|
||||
add(new StorageConfig("basePath", "基路径"));
|
||||
add(new StorageConfig("isPrivate", "是否是私有空间"));
|
||||
}};
|
||||
}
|
||||
|
||||
@@ -5,15 +5,19 @@ import com.amazonaws.auth.AWSStaticCredentialsProvider;
|
||||
import com.amazonaws.auth.BasicAWSCredentials;
|
||||
import com.amazonaws.client.builder.AwsClientBuilder;
|
||||
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
|
||||
import im.zhaojun.zfile.model.entity.StorageConfig;
|
||||
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.base.AbstractS3BaseFileService;
|
||||
import im.zhaojun.zfile.service.base.BaseFileService;
|
||||
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 java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
@@ -21,15 +25,17 @@ import java.util.Objects;
|
||||
* @author zhaojun
|
||||
*/
|
||||
@Service
|
||||
public abstract class AbstractS3Service extends AbstractS3BaseFileService implements BaseFileService {
|
||||
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
|
||||
public class S3ServiceImpl extends AbstractS3BaseFileService implements BaseFileService {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(AbstractS3Service.class);
|
||||
private static final Logger log = LoggerFactory.getLogger(S3ServiceImpl.class);
|
||||
|
||||
@Override
|
||||
public void init() {
|
||||
public void init(Integer driveId) {
|
||||
try {
|
||||
this.driveId = driveId;
|
||||
Map<String, StorageConfig> stringStorageConfigMap =
|
||||
storageConfigService.selectStorageConfigMapByKey(getStorageTypeEnum());
|
||||
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();
|
||||
@@ -65,4 +71,17 @@ public abstract class AbstractS3Service extends AbstractS3BaseFileService implem
|
||||
return StorageTypeEnum.S3;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<StorageConfig> storageStrategyConfigList() {
|
||||
return new ArrayList<StorageConfig>() {{
|
||||
add(new StorageConfig("accessKey", "AccessKey"));
|
||||
add(new StorageConfig("secretKey", "SecretKey"));
|
||||
add(new StorageConfig("endPoint", "服务地址(EndPoint)"));
|
||||
add(new StorageConfig("bucketName", "存储空间名称"));
|
||||
add(new StorageConfig("basePath", "基路径"));
|
||||
add(new StorageConfig("domain", "加速域名"));
|
||||
add(new StorageConfig("pathStyle", "域名风格"));
|
||||
add(new StorageConfig("isPrivate", "是否是私有空间"));
|
||||
}};
|
||||
}
|
||||
}
|
||||
@@ -5,13 +5,15 @@ import com.amazonaws.auth.AWSStaticCredentialsProvider;
|
||||
import com.amazonaws.auth.BasicAWSCredentials;
|
||||
import com.amazonaws.client.builder.AwsClientBuilder;
|
||||
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
|
||||
import im.zhaojun.zfile.model.entity.StorageConfig;
|
||||
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.base.AbstractS3BaseFileService;
|
||||
import im.zhaojun.zfile.service.base.BaseFileService;
|
||||
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 java.util.ArrayList;
|
||||
@@ -23,15 +25,17 @@ import java.util.Objects;
|
||||
* @author zhaojun
|
||||
*/
|
||||
@Service
|
||||
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
|
||||
public class TencentServiceImpl extends AbstractS3BaseFileService implements BaseFileService {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(TencentServiceImpl.class);
|
||||
|
||||
@Override
|
||||
public void init() {
|
||||
public void init(Integer driveId) {
|
||||
try {
|
||||
this.driveId = driveId;
|
||||
Map<String, StorageConfig> stringStorageConfigMap =
|
||||
storageConfigService.selectStorageConfigMapByKey(getStorageTypeEnum());
|
||||
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();
|
||||
@@ -63,14 +67,14 @@ public class TencentServiceImpl extends AbstractS3BaseFileService implements Bas
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<StorageConfig> storageStrategyList() {
|
||||
public List<StorageConfig> storageStrategyConfigList() {
|
||||
return new ArrayList<StorageConfig>() {{
|
||||
add(new StorageConfig("secretId", "SecretId"));
|
||||
add(new StorageConfig("secretKey", "SecretKey"));
|
||||
add(new StorageConfig("bucket-name", "云存储服务名称"));
|
||||
add(new StorageConfig("bucketName", "云存储服务名称"));
|
||||
add(new StorageConfig("domain", "加速域名"));
|
||||
add(new StorageConfig("endPoint", "区域"));
|
||||
add(new StorageConfig("base-path", "基路径"));
|
||||
add(new StorageConfig("basePath", "基路径"));
|
||||
add(new StorageConfig("isPrivate", "是否是私有空间"));
|
||||
}};
|
||||
}
|
||||
|
||||
@@ -1,12 +1,15 @@
|
||||
package im.zhaojun.zfile.service.impl;
|
||||
|
||||
import im.zhaojun.zfile.model.enums.StorageTypeEnum;
|
||||
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
|
||||
import org.springframework.context.annotation.Scope;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* @author zhaojun
|
||||
*/
|
||||
@Service
|
||||
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
|
||||
public class UFileServiceImpl extends UpYunServiceImpl {
|
||||
|
||||
@Override
|
||||
|
||||
@@ -3,21 +3,26 @@ package im.zhaojun.zfile.service.impl;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.core.util.URLUtil;
|
||||
import com.UpYun;
|
||||
import com.upyun.UpException;
|
||||
import im.zhaojun.zfile.exception.NotExistFileException;
|
||||
import im.zhaojun.zfile.model.entity.StorageConfig;
|
||||
import im.zhaojun.zfile.model.constant.StorageConfigConstant;
|
||||
import im.zhaojun.zfile.model.dto.FileItemDTO;
|
||||
import im.zhaojun.zfile.model.entity.StorageConfig;
|
||||
import im.zhaojun.zfile.model.enums.FileTypeEnum;
|
||||
import im.zhaojun.zfile.model.enums.StorageTypeEnum;
|
||||
import im.zhaojun.zfile.service.StorageConfigService;
|
||||
import im.zhaojun.zfile.service.base.AbstractBaseFileService;
|
||||
import im.zhaojun.zfile.service.base.BaseFileService;
|
||||
import im.zhaojun.zfile.service.StorageConfigService;
|
||||
import im.zhaojun.zfile.util.StringUtils;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
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.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -28,6 +33,7 @@ import java.util.Objects;
|
||||
*/
|
||||
@Service
|
||||
@Slf4j
|
||||
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
|
||||
public class UpYunServiceImpl extends AbstractBaseFileService implements BaseFileService {
|
||||
|
||||
private static final String END_MARK = "g2gCZAAEbmV4dGQAA2VvZg";
|
||||
@@ -42,10 +48,11 @@ public class UpYunServiceImpl extends AbstractBaseFileService implements BaseFil
|
||||
private String basePath;
|
||||
|
||||
@Override
|
||||
public void init() {
|
||||
public void init(Integer driveId) {
|
||||
try {
|
||||
this.driveId = driveId;
|
||||
Map<String, StorageConfig> stringStorageConfigMap =
|
||||
storageConfigService.selectStorageConfigMapByKey(getStorageTypeEnum());
|
||||
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();
|
||||
@@ -111,32 +118,44 @@ public class UpYunServiceImpl extends AbstractBaseFileService implements BaseFil
|
||||
|
||||
@Override
|
||||
public FileItemDTO getFileItem(String path) {
|
||||
List<FileItemDTO> list;
|
||||
try {
|
||||
int end = path.lastIndexOf("/");
|
||||
list = fileList(path.substring(0, end));
|
||||
} catch (Exception e) {
|
||||
throw new NotExistFileException();
|
||||
}
|
||||
int lastDelimiterIndex = path.lastIndexOf("/");
|
||||
String name = path.substring(lastDelimiterIndex + 1);
|
||||
|
||||
for (FileItemDTO fileItemDTO : list) {
|
||||
String fullPath = StringUtils.concatUrl(fileItemDTO.getPath(), fileItemDTO.getName());
|
||||
if (Objects.equals(fullPath, path)) {
|
||||
return fileItemDTO;
|
||||
Map<String, String> fileInfo = upYun.getFileInfo(StringUtils.removeDuplicateSeparator(basePath + "/" + path));
|
||||
|
||||
if (fileInfo == null) {
|
||||
throw new NotExistFileException();
|
||||
}
|
||||
|
||||
FileItemDTO fileItemDTO = new FileItemDTO();
|
||||
fileItemDTO.setName(name);
|
||||
fileItemDTO.setSize(Long.valueOf(fileInfo.get("size")));
|
||||
fileItemDTO.setTime(new Date(Long.parseLong(fileInfo.get("date")) * 1000));
|
||||
fileItemDTO.setPath(path);
|
||||
|
||||
if ("folder".equals(fileInfo.get("type"))) {
|
||||
fileItemDTO.setType(FileTypeEnum.FOLDER);
|
||||
} else {
|
||||
fileItemDTO.setType(FileTypeEnum.FILE);
|
||||
fileItemDTO.setUrl(getDownloadUrl(StringUtils.removeDuplicateSeparator(basePath + "/" + path)));
|
||||
}
|
||||
return fileItemDTO;
|
||||
} catch (IOException | UpException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
throw new NotExistFileException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<StorageConfig> storageStrategyList() {
|
||||
public List<StorageConfig> storageStrategyConfigList() {
|
||||
return new ArrayList<StorageConfig>() {{
|
||||
add(new StorageConfig("bucket-name", "云存储服务名称"));
|
||||
add(new StorageConfig("bucketName", "云存储服务名称"));
|
||||
add(new StorageConfig("username", "操作员名称"));
|
||||
add(new StorageConfig("password", "操作员密码"));
|
||||
add(new StorageConfig("domain", "加速域名"));
|
||||
add(new StorageConfig("base-path", "基路径"));
|
||||
add(new StorageConfig("basePath", "基路径"));
|
||||
}};
|
||||
}
|
||||
|
||||
|
||||
@@ -1,191 +0,0 @@
|
||||
package im.zhaojun.zfile.service.support;
|
||||
|
||||
import im.zhaojun.zfile.cache.ZFileCache;
|
||||
import im.zhaojun.zfile.config.StorageTypeFactory;
|
||||
import im.zhaojun.zfile.model.dto.FileItemDTO;
|
||||
import im.zhaojun.zfile.model.enums.FileTypeEnum;
|
||||
import im.zhaojun.zfile.model.enums.StorageTypeEnum;
|
||||
import im.zhaojun.zfile.service.SystemConfigService;
|
||||
import im.zhaojun.zfile.service.base.AbstractBaseFileService;
|
||||
import im.zhaojun.zfile.service.base.BaseFileService;
|
||||
import im.zhaojun.zfile.util.StringUtils;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.scheduling.annotation.Async;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* @author zhaojun
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
public class FileAsyncCacheService {
|
||||
|
||||
public static final String CACHE_PROCESS_PREFIX = "zfile-process-cache:";
|
||||
|
||||
private boolean cacheFinish;
|
||||
|
||||
@Resource
|
||||
private SystemConfigService systemConfigService;
|
||||
|
||||
private volatile boolean stopFlag = false;
|
||||
|
||||
@Resource
|
||||
private ZFileCache zFileCache;
|
||||
|
||||
@Value("${zfile.cache.auto-refresh.enable}")
|
||||
protected boolean enableAutoRefreshCache;
|
||||
|
||||
@Value("${zfile.cache.auto-refresh.delay}")
|
||||
protected Long delay;
|
||||
|
||||
@Value("${zfile.cache.auto-refresh.interval}")
|
||||
protected Long interval;
|
||||
|
||||
@Async
|
||||
public void cacheGlobalFile() {
|
||||
stopFlag = false;
|
||||
StorageTypeEnum storageStrategy = systemConfigService.getCurrentStorageStrategy();
|
||||
|
||||
if (storageStrategy == null) {
|
||||
log.debug("尚未配置存储策略. 跳过启动缓存.");
|
||||
return;
|
||||
}
|
||||
|
||||
boolean enableCache = systemConfigService.getEnableCache();
|
||||
if (!enableCache) {
|
||||
log.debug("存储策略 {} 未启用缓存, 跳过缓存.", storageStrategy.getDescription());
|
||||
return;
|
||||
}
|
||||
|
||||
AbstractBaseFileService fileService = StorageTypeFactory.getStorageTypeService(storageStrategy);
|
||||
|
||||
if (fileService.getIsUnInitialized()) {
|
||||
log.debug("存储策略 {} 未初始化成功, 跳过缓存.", storageStrategy.getDescription());
|
||||
return;
|
||||
}
|
||||
|
||||
log.info("缓存 {} 所有文件开始", storageStrategy.getDescription());
|
||||
long startTime = System.currentTimeMillis();
|
||||
try {
|
||||
BaseFileService currentFileService = systemConfigService.getCurrentFileService();
|
||||
List<FileItemDTO> rootFileItems = currentFileService.fileList("/");
|
||||
ArrayDeque<FileItemDTO> queue = new ArrayDeque<>(rootFileItems);
|
||||
|
||||
while (!queue.isEmpty()) {
|
||||
FileItemDTO fileItemDTO = queue.pop();
|
||||
|
||||
if (stopFlag) {
|
||||
zFileCache.clear();
|
||||
break;
|
||||
}
|
||||
|
||||
if (fileItemDTO.getType() == FileTypeEnum.FOLDER) {
|
||||
String filePath = StringUtils.removeDuplicateSeparator("/" + fileItemDTO.getPath() + "/" + fileItemDTO.getName() + "/");
|
||||
|
||||
List<FileItemDTO> fileItems = currentFileService.fileList(filePath);
|
||||
queue.addAll(fileItems);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("缓存所有文件失败", e);
|
||||
e.printStackTrace();
|
||||
}
|
||||
long endTime = System.currentTimeMillis();
|
||||
|
||||
if (stopFlag) {
|
||||
log.info("缓存 {} 所有文件被强制结束, 用时: {} 秒", storageStrategy.getDescription(), ((endTime - startTime) / 1000));
|
||||
cacheFinish = false;
|
||||
stopFlag = false;
|
||||
} else {
|
||||
log.info("缓存 {} 所有文件结束, 用时: {} 秒", storageStrategy.getDescription(), ((endTime - startTime) / 1000));
|
||||
enableCacheAutoRefreshTask();
|
||||
cacheFinish = true;
|
||||
stopFlag = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void enableCacheAutoRefreshTask() {
|
||||
StorageTypeEnum currentStorageStrategy = systemConfigService.getCurrentStorageStrategy();
|
||||
|
||||
if (enableAutoRefreshCache) {
|
||||
ScheduledExecutorService scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();
|
||||
scheduledExecutorService.scheduleWithFixedDelay(() -> {
|
||||
zFileCache.setLastCacheAutoRefreshDate(new Date());
|
||||
|
||||
boolean enableCache = systemConfigService.getEnableCache();
|
||||
|
||||
if (!enableCache) {
|
||||
log.debug("当前存储引擎未开启缓存, 跳过自动刷新缓存");
|
||||
zFileCache.clear();
|
||||
return;
|
||||
}
|
||||
|
||||
log.debug("开始调用自动刷新缓存");
|
||||
|
||||
Set<String> keySet = zFileCache.keySet();
|
||||
|
||||
ArrayList<String> keys = new ArrayList<>(keySet);
|
||||
|
||||
|
||||
for (String key : keys) {
|
||||
try {
|
||||
Thread.sleep(300);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
if (stopFlag) {
|
||||
break;
|
||||
}
|
||||
|
||||
zFileCache.remove(key);
|
||||
AbstractBaseFileService currentFileService = systemConfigService.getCurrentFileService();
|
||||
try {
|
||||
if (Objects.equals(currentStorageStrategy, systemConfigService.getCurrentStorageStrategy())) {
|
||||
currentFileService.fileList(key);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("刷新过程中出错 : [" + key + "]", e);
|
||||
}
|
||||
}
|
||||
|
||||
if (stopFlag) {
|
||||
log.debug("检测到停止 [{}] 缓存指令, 已停止自动刷新任务", currentStorageStrategy);
|
||||
scheduledExecutorService.shutdownNow();
|
||||
stopFlag = false;
|
||||
} else {
|
||||
log.debug("自动刷新缓存完成");
|
||||
}
|
||||
}, delay, interval, TimeUnit.SECONDS);
|
||||
}
|
||||
}
|
||||
|
||||
public void stopScheduled() {
|
||||
this.stopFlag = true;
|
||||
}
|
||||
|
||||
public void enableScheduled() {
|
||||
this.stopFlag = false;
|
||||
}
|
||||
|
||||
public boolean isCacheFinish() {
|
||||
return cacheFinish;
|
||||
}
|
||||
|
||||
public void setCacheFinish(boolean cacheFinish) {
|
||||
this.cacheFinish = cacheFinish;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
package im.zhaojun.zfile.service.support;
|
||||
|
||||
import im.zhaojun.zfile.cache.ZFileCache;
|
||||
import im.zhaojun.zfile.service.SystemConfigService;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
/**
|
||||
* @author zhaojun
|
||||
*/
|
||||
@Service
|
||||
public class FileCacheService {
|
||||
|
||||
@Resource
|
||||
private SystemConfigService systemConfigService;
|
||||
|
||||
@Resource
|
||||
@Lazy
|
||||
private FileAsyncCacheService fileAsyncCacheService;
|
||||
|
||||
@Resource
|
||||
private ZFileCache zFileCache;
|
||||
|
||||
public void enableCache() {
|
||||
systemConfigService.updateCacheEnableConfig(true);
|
||||
fileAsyncCacheService.cacheGlobalFile();
|
||||
}
|
||||
|
||||
public void disableCache() {
|
||||
systemConfigService.updateCacheEnableConfig(false);
|
||||
zFileCache.clear();
|
||||
fileAsyncCacheService.setCacheFinish(false);
|
||||
fileAsyncCacheService.stopScheduled();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -35,6 +35,12 @@ public class AudioHelper {
|
||||
url = url.replace(query, URLUtil.encode(query));
|
||||
}
|
||||
|
||||
// 如果音乐文件大小超出 5M, 则不解析此音乐
|
||||
if (im.zhaojun.zfile.util.HttpUtil.getRemoteFileSize(url)
|
||||
> (1024 * 1024 * ZFileConstant.AUDIO_MAX_FILE_SIZE_MB)) {
|
||||
return AudioInfoDTO.buildDefaultAudioInfoDTO();
|
||||
}
|
||||
|
||||
File file = new File(ZFileConstant.USER_HOME + ZFileConstant.AUDIO_TMP_PATH + UUID.fastUUID());
|
||||
FileUtil.mkParentDirs(file);
|
||||
HttpUtil.downloadFile(url, file);
|
||||
@@ -45,10 +51,7 @@ public class AudioHelper {
|
||||
}
|
||||
|
||||
private static AudioInfoDTO parseAudioInfo(File file) throws IOException, UnsupportedTagException {
|
||||
AudioInfoDTO audioInfoDTO = new AudioInfoDTO();
|
||||
audioInfoDTO.setTitle("未知歌曲");
|
||||
audioInfoDTO.setArtist("未知");
|
||||
audioInfoDTO.setCover("http://c.jun6.net/audio.png");
|
||||
AudioInfoDTO audioInfoDTO = AudioInfoDTO.buildDefaultAudioInfoDTO();
|
||||
|
||||
Mp3File mp3File = null;
|
||||
try {
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
package im.zhaojun.zfile.util;
|
||||
|
||||
import im.zhaojun.zfile.exception.PreviewException;
|
||||
import im.zhaojun.zfile.model.constant.ZFileConstant;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.web.client.RestClientException;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
/**
|
||||
@@ -10,20 +12,26 @@ import org.springframework.web.client.RestTemplate;
|
||||
@Slf4j
|
||||
public class HttpUtil {
|
||||
|
||||
/**
|
||||
* 最大支持文件预览大小: 1M
|
||||
*/
|
||||
public static String getTextContent(String url) {
|
||||
RestTemplate restTemplate = SpringContextHolder.getBean("restTemplate");
|
||||
|
||||
if (getRemoteFileSize(url) > (1024 * ZFileConstant.TEXT_MAX_FILE_SIZE_KB)) {
|
||||
throw new PreviewException("存储源跨域请求失败, 服务器中转状态, 预览文件超出大小, 最大支持 1M");
|
||||
}
|
||||
|
||||
String result = restTemplate.getForObject(url, String.class);
|
||||
return result == null ? "" : result;
|
||||
}
|
||||
|
||||
public static boolean checkUrlExist(String url) {
|
||||
RestTemplate restTemplate = SpringContextHolder.getBean("restTemplate");
|
||||
try {
|
||||
restTemplate.headForHeaders(url);
|
||||
return true;
|
||||
} catch (RestClientException ignored) {
|
||||
}
|
||||
return false;
|
||||
/**
|
||||
* 获取远程文件大小
|
||||
*/
|
||||
public static Long getRemoteFileSize(String url) {
|
||||
HttpHeaders httpHeaders = new RestTemplate().headForHeaders(url);
|
||||
return httpHeaders.getContentLength();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -6,15 +6,15 @@ import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.DisposableBean;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.lang.NonNull;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author zhaojun
|
||||
*/
|
||||
@Service
|
||||
@Lazy(false)
|
||||
public class SpringContextHolder implements ApplicationContextAware, DisposableBean {
|
||||
|
||||
private static ApplicationContext applicationContext = null;
|
||||
@@ -67,4 +67,8 @@ public class SpringContextHolder implements ApplicationContextAware, DisposableB
|
||||
SpringContextHolder.applicationContext = applicationContext;
|
||||
}
|
||||
|
||||
public static <T> Map<String, T> getBeansOfType(Class<T> classz) {
|
||||
return applicationContext.getBeansOfType(classz);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,8 +1,6 @@
|
||||
package im.zhaojun.zfile.util;
|
||||
|
||||
import cn.hutool.core.net.NetUtil;
|
||||
import im.zhaojun.zfile.exception.InitializeException;
|
||||
import im.zhaojun.zfile.service.support.FileAsyncCacheService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.boot.context.event.ApplicationStartedEvent;
|
||||
import org.springframework.context.ApplicationListener;
|
||||
@@ -21,16 +19,12 @@ import java.util.LinkedHashSet;
|
||||
@Slf4j
|
||||
public class StartupListener implements ApplicationListener<ApplicationStartedEvent> {
|
||||
|
||||
@Resource
|
||||
private FileAsyncCacheService fileAsyncCacheService;
|
||||
|
||||
@Resource
|
||||
private Environment environment;
|
||||
|
||||
@Override
|
||||
public void onApplicationEvent(@NonNull ApplicationStartedEvent event) {
|
||||
printStartInfo();
|
||||
cacheAllFile();
|
||||
}
|
||||
|
||||
|
||||
@@ -49,11 +43,11 @@ public class StartupListener implements ApplicationListener<ApplicationStartedEv
|
||||
log.info("ZFile Admin started at " + indexAdminAddr);
|
||||
}
|
||||
|
||||
private void cacheAllFile() {
|
||||
try {
|
||||
fileAsyncCacheService.cacheGlobalFile();
|
||||
} catch (Exception e) {
|
||||
throw new InitializeException("初始化缓存异常.", e);
|
||||
}
|
||||
}
|
||||
// private void cacheAllFile() {
|
||||
// try {
|
||||
// fileAsyncCacheService.cacheGlobalFile();
|
||||
// } catch (Exception e) {
|
||||
// throw new InitializeException("初始化缓存异常.", e);
|
||||
// }
|
||||
// }
|
||||
}
|
||||
Reference in New Issue
Block a user