Compare commits

..

18 Commits
1.9 ... 2.2

Author SHA1 Message Date
zhaojun1998
3249266cd1 🔖 发布 2.2 版 2020-03-08 11:48:48 +08:00
zhaojun1998
1a6235df73 🔨 重构代码, 去除无效引用。 2020-03-08 11:46:31 +08:00
zhaojun1998
430aee2b7f 🔨 重构代码, 去除无效引用。 2020-03-08 11:43:42 +08:00
zhaojun1998
de2f7e4b80 🔨 重构代码, 优化目录结构 2020-03-08 11:11:12 +08:00
zhaojun1998
6dfcc409ac 更新页面 2020-03-08 11:07:01 +08:00
zhaojun1998
78f795e1cb 🔖 发布 2.1 版 2020-03-07 18:39:33 +08:00
zhaojun1998
c69ee0f356 🐛 修复 S3 协议对象存储, 在私有空间下, 无法下载的 BUG. 2020-03-07 13:10:42 +08:00
zhaojun1998
39475de789 🐛 修复 S3 协议对象存储, 在私有空间下, 无法下载的 BUG. 2020-03-07 13:10:21 +08:00
zhaojun1998
bd71712765 🐛 修复无法刷新单个缓存的 BUG 2020-03-07 13:08:42 +08:00
赵俊
8698686a47 Update application.yml 2020-03-01 14:04:14 +08:00
zhaojun1998
762c67ee37 更新文档 2020-02-29 16:04:19 +08:00
zhaojun1998
7bf3a29c17 🔖 发布 2.0 版 2020-02-29 15:48:57 +08:00
zhaojun1998
6ee5002f0c 🔒 修复任意用户名均可登陆后台的安全问题. 2020-02-29 15:47:24 +08:00
zhaojun1998
fadc64add4 💄 更新页面, 修复滚动分页 BUG. 2020-02-29 15:46:56 +08:00
zhaojun1998
234f43846f 优化分页功能 2020-02-29 15:45:34 +08:00
zhaojun1998
67e42d9753 🐛 修复 OneDrive 获取文档区或文件夹密码时, 链接超时导致异常的 BUG. 2020-02-29 15:45:11 +08:00
zhaojun1998
04f94b4bf5 🏗️ 缓存架构调整, 增强稳定性 2020-02-29 15:43:56 +08:00
zhaojun1998
d29c498457 更新配置自描述文件 2020-02-27 23:01:38 +08:00
134 changed files with 1038 additions and 930 deletions

View File

@@ -40,15 +40,15 @@ apt update
apt install -y openjdk-8-jre-headless unzip
```
> 如为更新程序, 则请先执行 `rm -rf ~/zfile` 清理旧程序. 首次安装请忽略此选项.
> 如为更新程序, 则请先执行 `~/zfile/bin/stop.sh && rm -rf ~/zfile` 清理旧程序. 首次安装请忽略此选项.
下载项目:
```bash
wget -P ~ https://c.jun6.net/ZFILE/zfile-release.war
cd ~
wget https://c.jun6.net/ZFILE/zfile-release.war
mkdir zfile && unzip zfile-release.war -d zfile && rm -rf zfile-release.war
chmod +x ~/zfile/bin/*.sh
chmod +x zfile/bin/*.sh
```
程序的目录结构为:

View File

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

View File

@@ -1,82 +0,0 @@
package im.zhaojun.common.config;
import im.zhaojun.common.cache.ZFileCache;
import im.zhaojun.common.model.enums.StorageTypeEnum;
import im.zhaojun.common.service.AbstractFileService;
import im.zhaojun.common.service.StorageConfigService;
import im.zhaojun.common.service.SystemConfigService;
import im.zhaojun.onedrive.china.service.OneDriveChinaServiceImpl;
import im.zhaojun.onedrive.international.service.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 ZFileCache zFileCache;
@Resource
private StorageConfigService storageConfigService;
@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() {
AbstractFileService 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);
}
}
/**
* 调用刷新 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());
}
}

View File

@@ -1,89 +0,0 @@
package im.zhaojun.common.service;
import im.zhaojun.common.config.StorageTypeFactory;
import im.zhaojun.common.model.dto.FileItemDTO;
import im.zhaojun.common.model.enums.FileTypeEnum;
import im.zhaojun.common.model.enums.StorageTypeEnum;
import im.zhaojun.common.util.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.ArrayDeque;
import java.util.List;
/**
* @author zhaojun
*/
@Slf4j
@Service
public class FileAsyncCacheService {
public static final String CACHE_PROCESS_PREFIX = "zfile-process-cache:";
private boolean cacheFinish;
@Resource
private SystemConfigService systemConfigService;
@Async
public void cacheGlobalFile() {
StorageTypeEnum storageStrategy = systemConfigService.getCurrentStorageStrategy();
if (storageStrategy == null) {
log.debug("尚未配置存储策略. 跳过启动缓存.");
return;
}
boolean enableCache = systemConfigService.getEnableCache();
if (!enableCache) {
log.debug("存储策略 {} 未启用缓存, 跳过缓存.", storageStrategy.getDescription());
return;
}
AbstractFileService fileService = StorageTypeFactory.getStorageTypeService(storageStrategy);
if (fileService.getIsUnInitialized()) {
log.debug("存储策略 {} 未初始化成功, 跳过缓存.", storageStrategy.getDescription());
return;
}
Integer cacheDirectoryCount = 0;
log.info("缓存 {} 所有文件开始", storageStrategy.getDescription());
long startTime = System.currentTimeMillis();
try {
FileService currentFileService = systemConfigService.getCurrentFileService();
List<FileItemDTO> rootFileItems = currentFileService.fileList("/");
ArrayDeque<FileItemDTO> queue = new ArrayDeque<>(rootFileItems);
while (!queue.isEmpty()) {
FileItemDTO fileItemDTO = queue.pop();
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();
log.info("缓存 {} 所有文件结束, 用时: {} 秒", storageStrategy.getDescription(), ((endTime - startTime) / 1000));
cacheFinish = true;
}
public boolean isCacheFinish() {
return cacheFinish;
}
public void setCacheFinish(boolean cacheFinish) {
this.cacheFinish = cacheFinish;
}
}

View File

@@ -1,49 +0,0 @@
package im.zhaojun.common.service;
import im.zhaojun.common.model.constant.ZFileConstant;
import im.zhaojun.common.model.dto.FileItemDTO;
import im.zhaojun.common.model.dto.SiteConfigDTO;
import im.zhaojun.common.model.enums.StorageTypeEnum;
import im.zhaojun.common.util.HttpUtil;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
/**
* @author zhaojun
*/
@Service
public class SystemService {
@Resource
private SystemConfigService systemConfigService;
/**
* 构建指定路径下标题, 页面文档信息
* @param path 路径
*/
public SiteConfigDTO getConfig(String path) throws Exception {
SiteConfigDTO siteConfigDTO = new SiteConfigDTO();
AbstractFileService 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())) {
siteConfigDTO.setReadme(HttpUtil.getTextContent(fileItemDTO.getUrl()));
}
}
return siteConfigDTO;
}
}

View File

@@ -1,4 +1,4 @@
package im.zhaojun;
package im.zhaojun.zfile;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

View File

@@ -1,15 +1,12 @@
package im.zhaojun.common.cache;
package im.zhaojun.zfile.cache;
import cn.hutool.core.util.StrUtil;
import im.zhaojun.common.model.dto.FileItemDTO;
import im.zhaojun.common.model.dto.SystemConfigDTO;
import im.zhaojun.common.model.enums.FileTypeEnum;
import im.zhaojun.zfile.model.constant.ZFileConstant;
import im.zhaojun.zfile.model.dto.FileItemDTO;
import im.zhaojun.zfile.model.dto.SystemConfigDTO;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Set;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
@@ -21,22 +18,11 @@ public class ZFileCache {
private ConcurrentMap<String, List<FileItemDTO>> fileCache = new ConcurrentHashMap<>();
private ConcurrentMap<String, Integer> fileCountCache = new ConcurrentHashMap<>();
private SystemConfigDTO systemConfigCache;
public static final String CACHE_FILE_COUNT_KEY = "file-count";
public static final String CACHE_DIRECTORY_COUNT_KEY = "directory-count";
public Date lastCacheAutoRefreshDate;
public synchronized void put(String key, List<FileItemDTO> value) {
for (FileItemDTO fileItemDTO : value) {
if (FileTypeEnum.FILE.equals(fileItemDTO.getType())) {
incrCacheFileCount();
} else {
incrCacheDirectoryCount();
}
}
fileCache.put(key, value);
}
@@ -46,18 +32,23 @@ public class ZFileCache {
public void clear() {
fileCache.clear();
fileCountCache.clear();
}
public long cacheCount() {
public int cacheCount() {
return fileCache.size();
}
public List<FileItemDTO> find(String key, boolean ignoreCase) {
public List<FileItemDTO> find(String key, boolean ignoreCase, boolean searchContainEncryptedFile) {
List<FileItemDTO> result = new ArrayList<>();
Collection<List<FileItemDTO>> values = fileCache.values();
for (List<FileItemDTO> fileItemList : values) {
// 如果开启了 "搜索包含加密文件" 选项, 则直接返回 true.
if (!searchContainEncryptedFile && isEncryptedFolder(fileItemList)) {
continue;
}
for (FileItemDTO fileItemDTO : fileItemList) {
boolean testResult;
@@ -83,24 +74,6 @@ public class ZFileCache {
fileCache.remove(key);
}
private void incrCacheFileCount() {
Integer originValue = fileCountCache.getOrDefault(CACHE_FILE_COUNT_KEY, 0);
fileCountCache.put(CACHE_FILE_COUNT_KEY, originValue + 1);
}
private void incrCacheDirectoryCount() {
Integer originValue = fileCountCache.getOrDefault(CACHE_DIRECTORY_COUNT_KEY, 0);
fileCountCache.put(CACHE_DIRECTORY_COUNT_KEY, originValue + 1);
}
public int getCacheFileCount() {
return fileCountCache.getOrDefault(CACHE_FILE_COUNT_KEY, 0);
}
public int getCacheDirectorCount() {
return fileCountCache.getOrDefault(CACHE_DIRECTORY_COUNT_KEY, 0);
}
public void updateConfig(SystemConfigDTO systemConfigCache) {
this.systemConfigCache = systemConfigCache;
}
@@ -112,4 +85,28 @@ public class ZFileCache {
public void removeConfig() {
this.systemConfigCache = null;
}
public Date getLastCacheAutoRefreshDate() {
return lastCacheAutoRefreshDate;
}
public void setLastCacheAutoRefreshDate(Date lastCacheAutoRefreshDate) {
this.lastCacheAutoRefreshDate = lastCacheAutoRefreshDate;
}
/**
* 不是加密文件夹
* @param list 文件夹中的内容
* @return 返回此文件夹是否加密.
*/
private boolean isEncryptedFolder(List<FileItemDTO> list) {
// 遍历文件判断是否包含
for (FileItemDTO fileItemDTO : list) {
if (Objects.equals(ZFileConstant.PASSWORD_FILE_NAME, fileItemDTO.getName())) {
return true;
}
}
return false;
}
}

View File

@@ -1,6 +1,6 @@
package im.zhaojun.common.config;
package im.zhaojun.zfile.config;
import im.zhaojun.common.model.dto.FileItemDTO;
import im.zhaojun.zfile.model.dto.FileItemDTO;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

View File

@@ -1,7 +1,5 @@
package im.zhaojun.common.config;
package im.zhaojun.zfile.config;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpRequest;
import org.springframework.http.client.ClientHttpRequestExecution;
@@ -9,17 +7,16 @@ import org.springframework.http.client.ClientHttpRequestInterceptor;
import org.springframework.http.client.ClientHttpResponse;
import java.io.IOException;
import java.net.URI;
import java.util.Collections;
/**
* @author zhaojun
*/
public class ContentTypeTextToTextJson implements ClientHttpRequestInterceptor {
private static final Logger LOG = LoggerFactory.getLogger(ContentTypeTextToTextJson.class);
@Override
public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution)
throws IOException {
URI uri = request.getURI();
ClientHttpResponse response = execution.execute(request, body);
HttpHeaders headers = response.getHeaders();
headers.put("Content-Type", Collections.singletonList("application/text"));

View File

@@ -1,4 +1,4 @@
package im.zhaojun.common.config;
package im.zhaojun.zfile.config;
import org.springframework.http.HttpHeaders;
import org.springframework.web.cors.CorsUtils;

View File

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

View File

@@ -1,11 +1,11 @@
package im.zhaojun.onedrive.common.config;
package im.zhaojun.zfile.config;
import im.zhaojun.common.model.StorageConfig;
import im.zhaojun.common.model.constant.StorageConfigConstant;
import im.zhaojun.common.model.enums.StorageTypeEnum;
import im.zhaojun.common.service.StorageConfigService;
import im.zhaojun.onedrive.china.service.OneDriveChinaServiceImpl;
import im.zhaojun.onedrive.international.service.OneDriveServiceImpl;
import im.zhaojun.zfile.model.entity.StorageConfig;
import im.zhaojun.zfile.model.constant.StorageConfigConstant;
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;

View File

@@ -1,7 +1,7 @@
package im.zhaojun.common.config;
package im.zhaojun.zfile.config;
import im.zhaojun.common.model.enums.StorageTypeEnum;
import im.zhaojun.common.service.AbstractFileService;
import im.zhaojun.zfile.model.enums.StorageTypeEnum;
import im.zhaojun.zfile.service.base.AbstractBaseFileService;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
@@ -15,7 +15,7 @@ import java.util.Map;
@Component
public class StorageTypeFactory implements ApplicationContextAware {
private static Map<String, AbstractFileService> storageTypeEnumFileServiceMap;
private static Map<String, AbstractBaseFileService> storageTypeEnumFileServiceMap;
private static ApplicationContext applicationContext;
@@ -27,15 +27,15 @@ public class StorageTypeFactory implements ApplicationContextAware {
applicationContext = act;
// 获取 Spring 容器中所有 FileService 类型的类
storageTypeEnumFileServiceMap = act.getBeansOfType(AbstractFileService.class);
storageTypeEnumFileServiceMap = act.getBeansOfType(AbstractBaseFileService.class);
}
/**
* 获取指定存储类型 Service
*/
public static AbstractFileService getStorageTypeService(StorageTypeEnum type) {
AbstractFileService result = null;
for (AbstractFileService fileService : storageTypeEnumFileServiceMap.values()) {
public static AbstractBaseFileService getStorageTypeService(StorageTypeEnum type) {
AbstractBaseFileService result = null;
for (AbstractBaseFileService fileService : storageTypeEnumFileServiceMap.values()) {
if (fileService.getStorageTypeEnum() == type) {
result = fileService;
break;

View File

@@ -1,6 +1,6 @@
package im.zhaojun.common.config;
package im.zhaojun.zfile.config;
import im.zhaojun.common.model.enums.StorageTypeEnumDeSerializerConvert;
import im.zhaojun.zfile.model.enums.StorageTypeEnumDeSerializerConvert;
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.boot.web.servlet.server.ServletWebServerFactory;
import org.springframework.context.annotation.Bean;

View File

@@ -1,4 +1,4 @@
package im.zhaojun.common.config;
package im.zhaojun.zfile.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

View File

@@ -1,19 +1,19 @@
package im.zhaojun.common.controller;
package im.zhaojun.zfile.controller;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ZipUtil;
import im.zhaojun.common.config.StorageTypeFactory;
import im.zhaojun.common.model.StorageConfig;
import im.zhaojun.common.model.SystemMonitorInfo;
import im.zhaojun.common.model.dto.ResultBean;
import im.zhaojun.common.model.dto.StorageStrategyDTO;
import im.zhaojun.common.model.dto.SystemConfigDTO;
import im.zhaojun.common.model.enums.StorageTypeEnum;
import im.zhaojun.common.service.AbstractFileService;
import im.zhaojun.common.service.FileAsyncCacheService;
import im.zhaojun.common.service.StorageConfigService;
import im.zhaojun.common.service.SystemConfigService;
import im.zhaojun.common.util.FileUtil;
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;
@@ -26,11 +26,7 @@ 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;
import java.util.Map;
import java.util.Objects;
import java.util.*;
/**
* 后台管理
@@ -65,18 +61,20 @@ public class AdminController {
*/
@PostMapping("/config")
public ResultBean updateConfig(SystemConfigDTO systemConfigDTO) throws Exception {
AbstractFileService currentFileService = systemConfigService.getCurrentFileService();
systemConfigDTO.setId(1);
systemConfigService.updateSystemConfig(systemConfigDTO);
StorageTypeEnum currentStorageStrategy = currentFileService.getStorageTypeEnum();
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();
}
@@ -108,7 +106,7 @@ public class AdminController {
List<StorageStrategyDTO> result = new ArrayList<>();
StorageTypeEnum[] values = StorageTypeEnum.values();
for (StorageTypeEnum value : values) {
AbstractFileService storageTypeService = StorageTypeFactory.getStorageTypeService(value);
AbstractBaseFileService storageTypeService = StorageTypeFactory.getStorageTypeService(value);
result.add(new StorageStrategyDTO(value.getKey(),
value.getDescription(),
storageTypeService.getIsInitialized()));
@@ -121,10 +119,9 @@ public class AdminController {
* @param storageStrategyConfig 保存表单值
* @param storageStrategy 所属策略
* @return 操作结果
* @throws Exception 表单解析出错异常
*/
@PostMapping("/storage-strategy")
public ResultBean save(@RequestParam Map<String, String> storageStrategyConfig, StorageTypeEnum storageStrategy) throws Exception {
public ResultBean save(@RequestParam Map<String, String> storageStrategyConfig, StorageTypeEnum storageStrategy) {
// 保存设置.
List<StorageConfig> storageConfigList = storageConfigService.selectStorageConfigByType(storageStrategy);
for (StorageConfig storageConfig : storageConfigList) {
@@ -135,7 +132,7 @@ public class AdminController {
storageConfigService.updateStorageConfig(storageConfigList);
// 获取当前修改的存储策略 Service, 尝试调用初始化.
AbstractFileService updateStorageStrategyService = StorageTypeFactory.getStorageTypeService(storageStrategy);
AbstractBaseFileService updateStorageStrategyService = StorageTypeFactory.getStorageTypeService(storageStrategy);
updateStorageStrategyService.init();
// 如果修改的为当前启用的缓存, 则重新进行缓存.
@@ -145,7 +142,7 @@ public class AdminController {
log.debug("检测到更新了当前启用的存储策略 {}, 已清理缓存.", currentStorageStrategy);
}
AbstractFileService fileService = systemConfigService.getCurrentFileService();
AbstractBaseFileService fileService = systemConfigService.getCurrentFileService();
fileService.clearFileCache();
fileAsyncCacheService.cacheGlobalFile();
}
@@ -161,7 +158,7 @@ public class AdminController {
/**
* 更新存储策略
*/
public void refreshStorageStrategy() throws Exception {
public void refreshStorageStrategy() {
StorageTypeEnum storageStrategy = systemConfigService.getCurrentStorageStrategy();
refreshStorageStrategy(storageStrategy);
}
@@ -169,11 +166,11 @@ public class AdminController {
/**
* 更新存储策略
*/
public void refreshStorageStrategy(StorageTypeEnum storageStrategy) throws Exception {
private void refreshStorageStrategy(StorageTypeEnum storageStrategy) {
if (storageStrategy == null) {
log.info("尚未配置存储策略.");
} else {
AbstractFileService fileService = systemConfigService.getCurrentFileService();
AbstractBaseFileService fileService = systemConfigService.getCurrentFileService();
fileService.init();
fileService.clearFileCache();
log.info("切换至存储类型: {}", storageStrategy.getDescription());

View File

@@ -1,19 +1,18 @@
package im.zhaojun.common.controller;
package im.zhaojun.zfile.controller;
import im.zhaojun.common.cache.ZFileCache;
import im.zhaojun.common.model.dto.CacheConfigDTO;
import im.zhaojun.common.model.dto.ResultBean;
import im.zhaojun.common.service.AbstractFileService;
import im.zhaojun.common.service.FileAsyncCacheService;
import im.zhaojun.common.service.FileCacheService;
import im.zhaojun.common.service.SystemConfigService;
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;
import java.util.Set;
/**
* @author zhaojun
@@ -35,48 +34,51 @@ public class CacheController {
private ZFileCache zFileCache;
@PostMapping("/enable")
public ResultBean enableCache() throws Exception {
public ResultBean enableCache() {
fileCacheService.enableCache();
return ResultBean.success();
}
@PostMapping("/disable")
public ResultBean disableCache() throws Exception {
public ResultBean disableCache() {
fileCacheService.disableCache();
return ResultBean.success();
}
@GetMapping("/config")
public ResultBean cacheConfig() {
AbstractFileService fileService = systemConfigService.getCurrentFileService();
CacheConfigDTO cacheConfigDTO = new CacheConfigDTO();
cacheConfigDTO.setEnableCache(systemConfigService.getEnableCache());
cacheConfigDTO.setCacheFinish(fileAsyncCacheService.isCacheFinish());
cacheConfigDTO.setCacheKeys(zFileCache.keySet());
cacheConfigDTO.setCacheDirectoryCount(zFileCache.getCacheDirectorCount());
cacheConfigDTO.setCacheFileCount(zFileCache.getCacheFileCount());
cacheConfigDTO.setCacheDirectoryCount(zFileCache.cacheCount());
cacheConfigDTO.setLastCacheAutoRefreshDate(zFileCache.getLastCacheAutoRefreshDate());
return ResultBean.success(cacheConfigDTO);
}
@PostMapping("/refresh")
public ResultBean refreshCache(String key) throws Exception {
AbstractFileService fileService = systemConfigService.getCurrentFileService();
AbstractBaseFileService fileService = systemConfigService.getCurrentFileService();
fileService.refreshCache(key);
return ResultBean.success();
}
/*
@PostMapping("/clear")
public ResultBean clearCache(String key) throws Exception {
public ResultBean clearCache(String key) {
AbstractFileService fileService = systemConfigService.getCurrentFileService();
fileService.clearFileCache();
return ResultBean.success();
}
@PostMapping("/all")
public ResultBean cacheAll() throws Exception {
public ResultBean cacheAll() {
AbstractFileService fileService = systemConfigService.getCurrentFileService();
fileService.clearFileCache();
fileAsyncCacheService.cacheGlobalFile();
return ResultBean.success();
}
*/
}

View File

@@ -1,9 +1,9 @@
package im.zhaojun.common.controller;
package im.zhaojun.zfile.controller;
import im.zhaojun.common.model.dto.ResultBean;
import im.zhaojun.common.model.enums.StorageTypeEnum;
import im.zhaojun.common.util.AudioHelper;
import im.zhaojun.common.util.HttpUtil;
import im.zhaojun.zfile.model.dto.ResultBean;
import im.zhaojun.zfile.model.enums.StorageTypeEnum;
import im.zhaojun.zfile.util.AudioHelper;
import im.zhaojun.zfile.util.HttpUtil;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

View File

@@ -1,36 +1,37 @@
package im.zhaojun.common.controller;
package im.zhaojun.zfile.controller;
import cn.hutool.core.util.BooleanUtil;
import cn.hutool.core.util.URLUtil;
import im.zhaojun.common.annotation.CheckStorageStrategyInit;
import im.zhaojun.common.exception.SearchDisableException;
import im.zhaojun.common.model.constant.ZFileConstant;
import im.zhaojun.common.model.dto.FileItemDTO;
import im.zhaojun.common.model.dto.ResultBean;
import im.zhaojun.common.model.dto.SiteConfigDTO;
import im.zhaojun.common.model.dto.SystemConfigDTO;
import im.zhaojun.common.service.AbstractFileService;
import im.zhaojun.common.service.FileAsyncCacheService;
import im.zhaojun.common.service.SystemConfigService;
import im.zhaojun.common.service.SystemService;
import im.zhaojun.common.util.FileComparator;
import im.zhaojun.common.util.HttpUtil;
import im.zhaojun.common.util.StringUtils;
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.service.SystemConfigService;
import im.zhaojun.zfile.service.SystemService;
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.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.HttpClientErrorException;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.*;
/**
* 前台文件管理
* @author zhaojun
*/
@Slf4j
@RequestMapping("/api")
@RestController
public class FileController {
@@ -56,20 +57,37 @@ public class FileController {
@RequestParam(defaultValue = "asc") String order,
@RequestParam(required = false) String password,
@RequestParam(defaultValue = "1") Integer page) throws Exception {
AbstractFileService fileService = systemConfigService.getCurrentFileService();
AbstractBaseFileService fileService = systemConfigService.getCurrentFileService();
List<FileItemDTO> fileItemList = fileService.fileList(StringUtils.removeDuplicateSeparator("/" + path + "/"));
for (FileItemDTO fileItemDTO : fileItemList) {
if (ZFileConstant.PASSWORD_FILE_NAME.equals(fileItemDTO.getName())
&& !HttpUtil.getTextContent(fileItemDTO.getUrl()).equals(password)) {
if (ZFileConstant.PASSWORD_FILE_NAME.equals(fileItemDTO.getName())) {
String expectedPasswordContent;
try {
expectedPasswordContent = HttpUtil.getTextContent(fileItemDTO.getUrl() + '1');
} catch (HttpClientErrorException httpClientErrorException) {
log.debug("尝试重新获取密码文件缓存中链接后仍失败", httpClientErrorException);
try {
String fullPath = StringUtils.removeDuplicateSeparator(fileItemDTO.getPath() + "/" + fileItemDTO.getName());
FileItemDTO fileItem = fileService.getFileItem(fullPath);
expectedPasswordContent = HttpUtil.getTextContent(fileItem.getUrl());
} catch (Exception e) {
log.debug("尝试重新获取密码文件链接后仍失败, 已暂时取消密码", e);
break;
}
}
if (Objects.equals(expectedPasswordContent, password)) {
break;
}
if (password != null && !"".equals(password)) {
return ResultBean.error("密码错误.");
return ResultBean.error("密码错误.", ResultBean.INVALID_PASSWORD);
}
return ResultBean.error("此文件夹需要密码.", ResultBean.REQUIRED_PASSWORD);
}
}
List<FileItemDTO> sortedPagingData = getSortedPagingData(fileItemList, page);
return ResultBean.successData(sortedPagingData);
return ResultBean.successData(getSortedPagingData(fileItemList, page));
}
@@ -92,7 +110,7 @@ public class FileController {
@RequestParam(defaultValue = "name") String sortBy,
@RequestParam(defaultValue = "asc") String order,
@RequestParam(defaultValue = "1") Integer page) {
AbstractFileService fileService = systemConfigService.getCurrentFileService();
AbstractBaseFileService fileService = systemConfigService.getCurrentFileService();
SystemConfigDTO systemConfigDTO = systemConfigService.getSystemConfig();
if (BooleanUtil.isFalse(systemConfigDTO.getSearchEnable())) {
throw new SearchDisableException("搜索功能未开启");
@@ -101,8 +119,7 @@ public class FileController {
throw new SearchDisableException("搜索功能缓存预热中, 请稍后再试");
}
List<FileItemDTO> fileItemList = fileService.search(URLUtil.decode(name));
List<FileItemDTO> sortedPagingData = getSortedPagingData(fileItemList, page);
return ResultBean.successData(sortedPagingData);
return ResultBean.successData(getSortedPagingData(fileItemList, page));
}
@@ -119,7 +136,7 @@ public class FileController {
}
private List<FileItemDTO> getSortedPagingData(List<FileItemDTO> fileItemList, Integer page) {
private FilePageModel getSortedPagingData(List<FileItemDTO> fileItemList, Integer page) {
ArrayList<FileItemDTO> copy = new ArrayList<>(Arrays.asList(new FileItemDTO[fileItemList.size()]));
Collections.copy(copy, fileItemList);
@@ -131,13 +148,13 @@ public class FileController {
int totalPage = (total + PAGE_SIZE - 1) / PAGE_SIZE;
if (page > totalPage) {
return new ArrayList<>();
return new FilePageModel(total, totalPage, Collections.emptyList());
}
int start = (page - 1) * PAGE_SIZE;
int end = page * PAGE_SIZE;
end = Math.min(end, total);
return new ArrayList<>(copy.subList(start, end));
return new FilePageModel(total, totalPage, copy.subList(start, end));
}
@@ -149,7 +166,7 @@ public class FileController {
@CheckStorageStrategyInit
@GetMapping("/directlink")
public ResultBean directlink(String path) {
AbstractFileService fileService = systemConfigService.getCurrentFileService();
AbstractBaseFileService fileService = systemConfigService.getCurrentFileService();
return ResultBean.successData(fileService.getFileItem(path));
}
}

View File

@@ -1,13 +1,13 @@
package im.zhaojun.common.controller;
package im.zhaojun.zfile.controller;
import cn.hutool.crypto.SecureUtil;
import im.zhaojun.common.model.StorageConfig;
import im.zhaojun.common.model.dto.InstallModelDTO;
import im.zhaojun.common.model.dto.ResultBean;
import im.zhaojun.common.model.dto.SystemConfigDTO;
import im.zhaojun.common.model.enums.StorageTypeEnum;
import im.zhaojun.common.service.StorageConfigService;
import im.zhaojun.common.service.SystemConfigService;
import im.zhaojun.zfile.model.entity.StorageConfig;
import im.zhaojun.zfile.model.dto.InstallModelDTO;
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.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;

View File

@@ -1,8 +1,8 @@
package im.zhaojun.local.controller;
package im.zhaojun.zfile.controller;
import im.zhaojun.common.util.FileUtil;
import im.zhaojun.common.util.StringUtils;
import im.zhaojun.local.service.LocalServiceImpl;
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;

View File

@@ -1,8 +1,8 @@
package im.zhaojun.onedrive.common.controller;
package im.zhaojun.zfile.controller;
import im.zhaojun.onedrive.china.service.OneDriveChinaServiceImpl;
import im.zhaojun.onedrive.common.model.OneDriveToken;
import im.zhaojun.onedrive.international.service.OneDriveServiceImpl;
import im.zhaojun.zfile.service.impl.OneDriveChinaServiceImpl;
import im.zhaojun.zfile.model.support.OneDriveToken;
import im.zhaojun.zfile.service.impl.OneDriveServiceImpl;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;

View File

@@ -1,10 +1,11 @@
package im.zhaojun.common.controller;
package im.zhaojun.zfile.controller;
import cn.hutool.core.util.URLUtil;
import im.zhaojun.common.model.dto.FileItemDTO;
import im.zhaojun.common.model.enums.FileTypeEnum;
import im.zhaojun.common.service.AbstractFileService;
import im.zhaojun.common.service.SystemConfigService;
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 org.springframework.stereotype.Controller;
import org.springframework.util.AntPathMatcher;
import org.springframework.web.bind.annotation.GetMapping;
@@ -12,7 +13,6 @@ import org.springframework.web.servlet.HandlerMapping;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.net.MalformedURLException;
import java.util.Objects;
/**
@@ -26,18 +26,18 @@ public class PageController {
private SystemConfigService systemConfigService;
@GetMapping("/directlink/**")
public String directlink(final HttpServletRequest request) throws MalformedURLException {
public String directlink(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);
if (filePath.length() > 0 && filePath.charAt(0) != '/') {
if (filePath.length() > 0 && filePath.charAt(0) != ZFileConstant.PATH_SEPARATOR_CHAR) {
filePath = "/" + filePath;
}
AbstractFileService fileService = systemConfigService.getCurrentFileService();
AbstractBaseFileService fileService = systemConfigService.getCurrentFileService();
FileItemDTO fileItem = fileService.getFileItem(filePath);
String url = fileItem.getUrl();

View File

@@ -1,12 +1,11 @@
package im.zhaojun.common.aop;
package im.zhaojun.zfile.core;
import im.zhaojun.common.cache.ZFileCache;
import im.zhaojun.common.model.dto.FileItemDTO;
import im.zhaojun.common.service.SystemConfigService;
import im.zhaojun.zfile.cache.ZFileCache;
import im.zhaojun.zfile.model.dto.FileItemDTO;
import im.zhaojun.zfile.service.SystemConfigService;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
@@ -14,11 +13,12 @@ import javax.annotation.Resource;
import java.util.List;
/**
* 操作日志切面.
* @author zhaojun
* 缓存切面类, 用于访问文件夹时, 缓存文件列表内容.
*/
@Aspect
@Component
public class FileListCacheAspect {
public class FileListCacheAop {
@Resource
private ZFileCache zFileCache;
@@ -26,11 +26,7 @@ public class FileListCacheAspect {
@Resource
private SystemConfigService systemConfigService;
@Pointcut("execution(public * im.zhaojun.common.service.AbstractFileService.fileList(..))")
public void pointcut() {
}
@Around(value = "pointcut()")
@Around(value = "execution(public * im.zhaojun.zfile.service.base.AbstractBaseFileService.fileList(..))")
public Object around(ProceedingJoinPoint point) throws Throwable {
List<FileItemDTO> result;

View File

@@ -1,9 +1,9 @@
package im.zhaojun.common.aspect;
package im.zhaojun.zfile.core;
import im.zhaojun.common.exception.StorageStrategyUninitializedException;
import im.zhaojun.common.service.AbstractFileService;
import im.zhaojun.common.service.SystemConfigService;
import im.zhaojun.common.util.SpringContextHolder;
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;
@@ -13,12 +13,12 @@ import org.springframework.stereotype.Component;
*/
@Aspect
@Component
public class StorageStrategyInitCheckAspect {
public class StorageStrategyInitCheckAop {
@Before("@annotation(im.zhaojun.common.annotation.CheckStorageStrategyInit)")
@Before("@annotation(im.zhaojun.zfile.model.annotation.CheckStorageStrategyInit)")
public void logStart() {
SystemConfigService systemConfigService = SpringContextHolder.getBean(SystemConfigService.class);
AbstractFileService currentFileService = systemConfigService.getCurrentFileService();
AbstractBaseFileService currentFileService = systemConfigService.getCurrentFileService();
if (currentFileService == null) {
throw new StorageStrategyUninitializedException("存储策略尚未初始化, 请联系管理员!");
}

View File

@@ -1,6 +1,6 @@
package im.zhaojun.common.exception;
package im.zhaojun.zfile.exception;
import im.zhaojun.common.model.dto.ResultBean;
import im.zhaojun.zfile.model.dto.ResultBean;
import org.apache.catalina.connector.ClientAbortException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

View File

@@ -1,4 +1,4 @@
package im.zhaojun.common.exception;
package im.zhaojun.zfile.exception;
/**
* 对象存储初始化异常

View File

@@ -1,4 +1,4 @@
package im.zhaojun.common.exception;
package im.zhaojun.zfile.exception;
/**
* @author zhaojun

View File

@@ -1,4 +1,4 @@
package im.zhaojun.common.exception;
package im.zhaojun.zfile.exception;
/**
* @author zhaojun

View File

@@ -1,4 +1,4 @@
package im.zhaojun.common.exception;
package im.zhaojun.zfile.exception;
/**
* 存储策略未初始化异常

View File

@@ -1,4 +1,4 @@
package im.zhaojun.common.exception;
package im.zhaojun.zfile.exception;
/**
* 未知的存储类型异常

View File

@@ -1,4 +1,4 @@
package im.zhaojun.common.security;
package im.zhaojun.zfile.filter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

View File

@@ -1,4 +1,4 @@
package im.zhaojun.common.annotation;
package im.zhaojun.zfile.model.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;

View File

@@ -1,4 +1,4 @@
package im.zhaojun.common.model.constant;
package im.zhaojun.zfile.model.constant;
/**
* @author zhaojun

View File

@@ -1,4 +1,4 @@
package im.zhaojun.common.model.constant;
package im.zhaojun.zfile.model.constant;
/**
* @author zhaojun

View File

@@ -1,4 +1,4 @@
package im.zhaojun.common.model.constant;
package im.zhaojun.zfile.model.constant;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
@@ -14,6 +14,10 @@ public class ZFileConstant {
public static final String AUDIO_TMP_PATH = "/.zfile/tmp/audio/";
public static final Character PATH_SEPARATOR_CHAR = '/';
public static final String PATH_SEPARATOR = "/";
/**
* 页面文档文件
*/

View File

@@ -1,4 +1,4 @@
package im.zhaojun.common.model.dto;
package im.zhaojun.zfile.model.dto;
/**
* @author zhaojun

View File

@@ -1,7 +1,8 @@
package im.zhaojun.common.model.dto;
package im.zhaojun.zfile.model.dto;
import lombok.Data;
import java.util.Date;
import java.util.Set;
/**
@@ -14,4 +15,5 @@ public class CacheConfigDTO {
private Set<String> cacheKeys;
private Integer cacheDirectoryCount;
private Integer cacheFileCount;
private Date lastCacheAutoRefreshDate;
}

View File

@@ -1,6 +1,6 @@
package im.zhaojun.common.model.dto;
package im.zhaojun.zfile.model.dto;
import im.zhaojun.common.model.enums.FileTypeEnum;
import im.zhaojun.zfile.model.enums.FileTypeEnum;
import java.io.Serializable;
import java.util.Date;

View File

@@ -1,6 +1,6 @@
package im.zhaojun.common.model.dto;
package im.zhaojun.zfile.model.dto;
import im.zhaojun.common.model.enums.StorageTypeEnum;
import im.zhaojun.zfile.model.enums.StorageTypeEnum;
import java.util.Map;

View File

@@ -1,4 +1,4 @@
package im.zhaojun.common.model.dto;
package im.zhaojun.zfile.model.dto;
import java.io.Serializable;
@@ -15,6 +15,8 @@ public class ResultBean implements Serializable {
public static final int REQUIRED_PASSWORD = -2;
public static final int INVALID_PASSWORD = -3;
private String msg = "操作成功";
private int code = SUCCESS;
@@ -43,6 +45,10 @@ public class ResultBean implements Serializable {
return success("操作成功", data);
}
public static ResultBean successPage(Object data, Long total) {
return success("操作成功", data);
}
public static ResultBean success(Object data) {
return success("操作成功", data);
}

View File

@@ -1,4 +1,4 @@
package im.zhaojun.common.model.dto;
package im.zhaojun.zfile.model.dto;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;

View File

@@ -1,5 +1,6 @@
package im.zhaojun.common.model.dto;
package im.zhaojun.zfile.model.dto;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@@ -16,6 +17,7 @@ public class StorageStrategyDTO {
private String description;
private boolean available;
@JsonProperty(defaultValue = "false")
private Boolean available;
}

View File

@@ -1,9 +1,9 @@
package im.zhaojun.common.model.dto;
package im.zhaojun.zfile.model.dto;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import im.zhaojun.common.model.enums.StorageTypeEnum;
import im.zhaojun.common.model.enums.StorageTypeEnumSerializerConvert;
import im.zhaojun.zfile.model.enums.StorageTypeEnum;
import im.zhaojun.zfile.model.enums.StorageTypeEnumSerializerConvert;
import lombok.Data;
import lombok.ToString;

View File

@@ -1,6 +1,6 @@
package im.zhaojun.common.model;
package im.zhaojun.zfile.model.entity;
import im.zhaojun.common.model.enums.StorageTypeEnum;
import im.zhaojun.zfile.model.enums.StorageTypeEnum;
import lombok.Data;
import javax.persistence.Column;

View File

@@ -1,4 +1,4 @@
package im.zhaojun.common.model;
package im.zhaojun.zfile.model.entity;
import lombok.Data;

View File

@@ -1,4 +1,4 @@
package im.zhaojun.common.model.enums;
package im.zhaojun.zfile.model.enums;
/**
* @author zhaojun

View File

@@ -1,4 +1,4 @@
package im.zhaojun.common.model.enums;
package im.zhaojun.zfile.model.enums;
import com.fasterxml.jackson.annotation.JsonFormat;

View File

@@ -1,4 +1,4 @@
package im.zhaojun.common.model.enums;
package im.zhaojun.zfile.model.enums;
import javax.persistence.AttributeConverter;
import javax.persistence.Converter;

View File

@@ -1,4 +1,4 @@
package im.zhaojun.common.model.enums;
package im.zhaojun.zfile.model.enums;
import org.springframework.core.convert.converter.Converter;
import org.springframework.lang.NonNull;

View File

@@ -1,4 +1,4 @@
package im.zhaojun.common.model.enums;
package im.zhaojun.zfile.model.enums;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;

View File

@@ -0,0 +1,22 @@
package im.zhaojun.zfile.model.support;
import im.zhaojun.zfile.model.dto.FileItemDTO;
import lombok.AllArgsConstructor;
import lombok.Data;
import java.util.List;
/**
* @author zhaojun
*/
@Data
@AllArgsConstructor
public class FilePageModel {
private int total;
private int totalPage;
private List<FileItemDTO> fileList;
}

View File

@@ -1,4 +1,4 @@
package im.zhaojun.common.model;
package im.zhaojun.zfile.model.support;
import lombok.Data;

View File

@@ -1,4 +1,4 @@
package im.zhaojun.common.model;
package im.zhaojun.zfile.model.support;
import com.sun.management.OperatingSystemMXBean;
import lombok.Data;
@@ -27,11 +27,11 @@ public class Mem {
private double free;
public Mem() {
OperatingSystemMXBean operatingSystemMXBean = (OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean();
OperatingSystemMXBean osb = (OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean();
// 总的物理内存+虚拟内存
long totalVirtualMemory = operatingSystemMXBean.getTotalSwapSpaceSize();
long totalVirtualMemory = osb.getTotalSwapSpaceSize();
// 剩余的物理内存
long freePhysicalMemorySize = operatingSystemMXBean.getFreePhysicalMemorySize();
long freePhysicalMemorySize = osb.getFreePhysicalMemorySize();
this.total = totalVirtualMemory;
this.free = freePhysicalMemorySize;
this.used = totalVirtualMemory - freePhysicalMemorySize;

View File

@@ -1,4 +1,4 @@
package im.zhaojun.onedrive.common.model;
package im.zhaojun.zfile.model.support;
import com.alibaba.fastjson.annotation.JSONField;
import lombok.Data;

View File

@@ -1,4 +1,4 @@
package im.zhaojun.common.model;
package im.zhaojun.zfile.model.support;
import cn.hutool.core.date.BetweenFormater;
import cn.hutool.core.date.DateUtil;

View File

@@ -1,5 +1,8 @@
package im.zhaojun.common.model;
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;

View File

@@ -1,7 +1,7 @@
package im.zhaojun.common.repository;
package im.zhaojun.zfile.repository;
import im.zhaojun.common.model.StorageConfig;
import im.zhaojun.common.model.enums.StorageTypeEnum;
import im.zhaojun.zfile.model.entity.StorageConfig;
import im.zhaojun.zfile.model.enums.StorageTypeEnum;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

View File

@@ -1,6 +1,6 @@
package im.zhaojun.common.repository;
package im.zhaojun.zfile.repository;
import im.zhaojun.common.model.SystemConfig;
import im.zhaojun.zfile.model.entity.SystemConfig;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

View File

@@ -1,4 +1,4 @@
package im.zhaojun.common.security;
package im.zhaojun.zfile.security;
import cn.hutool.crypto.SecureUtil;
import org.springframework.security.crypto.password.PasswordEncoder;

View File

@@ -1,7 +1,7 @@
package im.zhaojun.common.security;
package im.zhaojun.zfile.security;
import com.fasterxml.jackson.databind.ObjectMapper;
import im.zhaojun.common.model.dto.ResultBean;
import im.zhaojun.zfile.model.dto.ResultBean;
import org.springframework.context.annotation.Bean;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.BadCredentialsException;
@@ -21,6 +21,7 @@ import java.io.PrintWriter;
/**
* 自定义 Security 配置类
*
* @author zhaojun
*/
@EnableWebSecurity
@@ -34,7 +35,7 @@ public class MySecurityConfig extends WebSecurityConfigurerAdapter {
http
// .authenticationProvider(authenticationProvider())
.exceptionHandling()
//未登录时进行json格式的提示很喜欢这种写法不用单独写一个又一个的类
// 未登录时进行 json 格式的提示.
.authenticationEntryPoint((request, response, authException) -> {
response.setContentType("application/json;charset=utf-8");
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
@@ -48,8 +49,8 @@ public class MySecurityConfig extends WebSecurityConfigurerAdapter {
.antMatchers("/").permitAll()
.antMatchers("/admin/**").authenticated()
.and()
.formLogin() //使用自带的登录
//登录失败返回json
.formLogin() // 使用自带的登录
// 登录失败返回json
.failureHandler((request, response, ex) -> {
response.setContentType("application/json;charset=utf-8");
response.setStatus(HttpServletResponse.SC_FORBIDDEN);
@@ -64,7 +65,7 @@ public class MySecurityConfig extends WebSecurityConfigurerAdapter {
out.flush();
out.close();
})
//登录成功返回json
// 登录成功返回json
.successHandler((request, response, authentication) -> {
response.setContentType("application/json;charset=utf-8");
PrintWriter out = response.getWriter();
@@ -74,7 +75,7 @@ public class MySecurityConfig extends WebSecurityConfigurerAdapter {
})
.and()
.exceptionHandling()
//没有权限返回json
// 没有权限返回json
.accessDeniedHandler((request, response, ex) -> {
response.setContentType("application/json;charset=utf-8");
response.setStatus(HttpServletResponse.SC_FORBIDDEN);
@@ -85,7 +86,7 @@ public class MySecurityConfig extends WebSecurityConfigurerAdapter {
})
.and()
.logout()
//退出成功返回json
// 退出成功返回 json
.logoutSuccessHandler((request, response, authentication) -> {
response.setContentType("application/json;charset=utf-8");
PrintWriter out = response.getWriter();
@@ -120,7 +121,7 @@ public class MySecurityConfig extends WebSecurityConfigurerAdapter {
@Override
public void configure(WebSecurity web) {
//对于在header里面增加token等类似情况放行所有OPTIONS请求
// 对于在 header 里面增加 token 等类似情况放行所有 OPTIONS 请求
web.ignoring().antMatchers(HttpMethod.OPTIONS, "/**");
web.httpFirewall(allowUrlEncodedSlashHttpFirewall());
}

View File

@@ -1,7 +1,7 @@
package im.zhaojun.common.security;
package im.zhaojun.zfile.security;
import im.zhaojun.common.model.dto.SystemConfigDTO;
import im.zhaojun.common.service.SystemConfigService;
import im.zhaojun.zfile.model.dto.SystemConfigDTO;
import im.zhaojun.zfile.service.SystemConfigService;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
@@ -9,6 +9,7 @@ import org.springframework.security.core.userdetails.UsernameNotFoundException;
import javax.annotation.Resource;
import java.util.Collections;
import java.util.Objects;
/**
* @author zhaojun
@@ -24,6 +25,9 @@ public class MyUserDetailsServiceImpl implements UserDetailsService {
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
SystemConfigDTO systemConfig = systemConfigService.getSystemConfig();
if (!Objects.equals(systemConfig.getUsername(), username)) {
throw new UsernameNotFoundException("用户名不存在");
}
return new User(systemConfig.getUsername(), systemConfig.getPassword(), Collections.emptyList());
}
}

View File

@@ -1,8 +1,8 @@
package im.zhaojun.common.service;
package im.zhaojun.zfile.service;
import im.zhaojun.common.model.StorageConfig;
import im.zhaojun.common.model.enums.StorageTypeEnum;
import im.zhaojun.common.repository.StorageConfigRepository;
import im.zhaojun.zfile.model.entity.StorageConfig;
import im.zhaojun.zfile.model.enums.StorageTypeEnum;
import im.zhaojun.zfile.repository.StorageConfigRepository;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;

View File

@@ -1,15 +1,16 @@
package im.zhaojun.common.service;
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.common.cache.ZFileCache;
import im.zhaojun.common.config.StorageTypeFactory;
import im.zhaojun.common.model.SystemConfig;
import im.zhaojun.common.model.constant.SystemConfigConstant;
import im.zhaojun.common.model.dto.SystemConfigDTO;
import im.zhaojun.common.model.enums.StorageTypeEnum;
import im.zhaojun.common.repository.SystemConfigRepository;
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.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.stereotype.Service;
@@ -25,20 +26,13 @@ import java.util.List;
@Service
public class SystemConfigService {
public static final String SYSTEM_CONFIG_CACHE_PREFIX = "zfile-config-cache:";
public static final String SYSTEM_CONFIG_CACHE_KEY = "1";
@Resource
private ZFileCache zFileCache;
@Resource
private SystemConfigRepository systemConfigRepository;
@Resource
private FileCacheService fileCacheService;
private Class<SystemConfigDTO> systemConfigDTOClass = SystemConfigDTO.class;
private Class<SystemConfigDTO> systemConfigClazz = SystemConfigDTO.class;
public SystemConfigDTO getSystemConfig() {
SystemConfigDTO cacheConfig = zFileCache.getConfig();
@@ -53,7 +47,7 @@ public class SystemConfigService {
String key = systemConfig.getKey();
try {
Field field = systemConfigDTOClass.getDeclaredField(key);
Field field = systemConfigClazz.getDeclaredField(key);
if (field != null) {
field.setAccessible(true);
String strVal = systemConfig.getValue();
@@ -75,7 +69,7 @@ public class SystemConfigService {
public void updateSystemConfig(SystemConfigDTO systemConfigDTO) throws Exception {
List<SystemConfig> systemConfigList = new ArrayList<>();
Field[] fields = systemConfigDTOClass.getDeclaredFields();
Field[] fields = systemConfigClazz.getDeclaredFields();
for (Field field : fields) {
String key = field.getName();
SystemConfig systemConfig = systemConfigRepository.findByKey(key);
@@ -89,22 +83,8 @@ public class SystemConfigService {
}
}
boolean oldEnableCache = getEnableCache();
boolean curEnableCache = BooleanUtil.isTrue(systemConfigDTO.getEnableCache());
zFileCache.removeConfig();
systemConfigRepository.saveAll(systemConfigList);
if (!oldEnableCache && curEnableCache) {
log.debug("检测到开启了缓存, 开启预热缓存");
fileCacheService.enableCache();
}
if (oldEnableCache && !curEnableCache) {
log.debug("检测到关闭了缓存, 正在清理缓存数据及关闭自动刷新");
fileCacheService.disableCache();
}
}
@@ -131,7 +111,7 @@ public class SystemConfigService {
}
public AbstractFileService getCurrentFileService() {
public AbstractBaseFileService getCurrentFileService() {
StorageTypeEnum storageStrategy = getCurrentStorageStrategy();
return StorageTypeFactory.getStorageTypeService(storageStrategy);
}

View File

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

View File

@@ -1,11 +1,13 @@
package im.zhaojun.common.service;
package im.zhaojun.zfile.service.base;
import cn.hutool.core.util.BooleanUtil;
import im.zhaojun.common.cache.ZFileCache;
import im.zhaojun.common.model.constant.ZFileConstant;
import im.zhaojun.common.model.dto.FileItemDTO;
import im.zhaojun.common.model.dto.SystemConfigDTO;
import im.zhaojun.common.model.enums.StorageTypeEnum;
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.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;
@@ -13,16 +15,12 @@ import org.springframework.beans.factory.annotation.Value;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.List;
import java.util.Objects;
import java.util.Set;
/**
* @author zhaojun
*/
@Slf4j
public abstract class AbstractFileService extends FileCacheService implements FileService {
private static final String SYSTEM_CONFIG_CACHE_PREFIX = "zfile-cache:";
public abstract class AbstractBaseFileService extends FileCacheService implements BaseFileService {
@Value("${zfile.cache.timeout}")
protected Long timeout;
@@ -52,13 +50,10 @@ public abstract class AbstractFileService extends FileCacheService implements Fi
/**
* 清理当前存储策略的缓存
* 1. 删除全部缓存
* 2. 关闭自动刷新
* 3. 重置缓存个数
* 4. 标记为当前处于未完成缓存状态
* 2. 标记为当前处于未完成缓存状态
*/
public void clearFileCache() {
zFileCache.clear();
closeCacheAutoRefresh();
fileAsyncCacheService.setCacheFinish(false);
}
@@ -107,29 +102,11 @@ public abstract class AbstractFileService extends FileCacheService implements Fi
* @return 包含该文件名的所有文件或文件夹
*/
public List<FileItemDTO> search(String name) {
boolean searchIgnoreCase = systemConfigService.getSearchIgnoreCase();
return zFileCache.find(name, searchIgnoreCase);
}
/**
* 不是加密文件夹
* @param list 文件夹中的内容
* @return 返回此文件夹是否加密.
*/
private boolean isNotEncryptedFolder(List<FileItemDTO> list) {
// 如果开启了 "搜索包含加密文件" 选项, 则直接返回 true.
SystemConfigDTO systemConfig = systemConfigService.getSystemConfig();
if (BooleanUtil.isFalse(systemConfig.getSearchContainEncryptedFile())) {
return true;
}
// 遍历文件判断是否包含
for (FileItemDTO fileItemDTO : list) {
if (Objects.equals(ZFileConstant.PASSWORD_FILE_NAME, fileItemDTO.getName())) {
return false;
}
}
return true;
boolean searchIgnoreCase = BooleanUtil.isTrue(systemConfig.getSearchIgnoreCase());
boolean searchContainEncryptedFile = BooleanUtil.isTrue(systemConfig.getSearchContainEncryptedFile());
return zFileCache.find(name, searchIgnoreCase, searchContainEncryptedFile);
}
/**
@@ -137,19 +114,15 @@ public abstract class AbstractFileService extends FileCacheService implements Fi
*/
public void refreshCache(String key) throws Exception {
zFileCache.remove(key);
FileService currentFileService = (FileService) AopContext.currentProxy();
BaseFileService currentFileService = (BaseFileService) AopContext.currentProxy();
currentFileService.fileList(key);
}
public void closeCacheAutoRefresh() {
// cache.config().setRefreshPolicy(null);
}
public void openCacheAutoRefresh() {
// RefreshPolicy refreshPolicy = RefreshPolicy.newPolicy(30, TimeUnit.MINUTES);
// cache.config().setRefreshPolicy(refreshPolicy);
}
/**
* 获取单个文件信息
* @param path 文件路径
* @return 单个文件的内容.
*/
public abstract FileItemDTO getFileItem(String path);
}

View File

@@ -1,4 +1,4 @@
package im.zhaojun.onedrive.common.service;
package im.zhaojun.zfile.service.base;
import cn.hutool.core.util.URLUtil;
import cn.hutool.http.HttpRequest;
@@ -7,15 +7,15 @@ import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import im.zhaojun.common.model.StorageConfig;
import im.zhaojun.common.model.constant.StorageConfigConstant;
import im.zhaojun.common.model.dto.FileItemDTO;
import im.zhaojun.common.model.enums.FileTypeEnum;
import im.zhaojun.common.repository.StorageConfigRepository;
import im.zhaojun.common.service.AbstractFileService;
import im.zhaojun.common.service.StorageConfigService;
import im.zhaojun.common.util.StringUtils;
import im.zhaojun.onedrive.common.model.OneDriveToken;
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.dto.FileItemDTO;
import im.zhaojun.zfile.model.enums.FileTypeEnum;
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.http.ResponseEntity;
import org.springframework.web.client.HttpClientErrorException;
@@ -31,7 +31,7 @@ import java.util.List;
* 2020/1/29 11:54
*/
@Slf4j
public abstract class AbstractOneDriveService extends AbstractFileService {
public abstract class AbstractOneDriveServiceBase extends AbstractBaseFileService {
protected static final String DRIVER_INFO_URL = "https://{graphEndPoint}/v1.0/me/drives";
@@ -43,6 +43,8 @@ public abstract class AbstractOneDriveService extends AbstractFileService {
protected static final String AUTHENTICATE_URL = "https://{authenticateEndPoint}/common/oauth2/v2.0/token";
private static final String ONE_DRIVE_FILE_FLAG = "file";
@Resource
private RestTemplate oneDriveRestTemplate;
@@ -105,7 +107,7 @@ public abstract class AbstractOneDriveService extends AbstractFileService {
if (nextLink != null) {
nextLink = nextLink.replace("+", "%2B");
requestUrl = URLUtil.decode(nextLink);
}else if ("/".equalsIgnoreCase(fullPath) || "".equalsIgnoreCase(fullPath)) {
}else if (ZFileConstant.PATH_SEPARATOR.equalsIgnoreCase(fullPath) || "".equalsIgnoreCase(fullPath)) {
requestUrl = DRIVER_ROOT_URL;
} else {
requestUrl = DRIVER_ITEMS_URL;
@@ -169,7 +171,7 @@ public abstract class AbstractOneDriveService extends AbstractFileService {
fileItemDTO.setSize(fileItem.getLong("size"));
fileItemDTO.setTime(fileItem.getDate("lastModifiedDateTime"));
if (fileItem.containsKey("file")) {
if (fileItem.containsKey(ONE_DRIVE_FILE_FLAG)) {
fileItemDTO.setUrl(fileItem.getString("@microsoft.graph.downloadUrl"));
fileItemDTO.setType(FileTypeEnum.FILE);
} else {

View File

@@ -1,4 +1,4 @@
package im.zhaojun.common.service;
package im.zhaojun.zfile.service.base;
import cn.hutool.core.util.BooleanUtil;
import cn.hutool.core.util.URLUtil;
@@ -6,10 +6,11 @@ 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.common.exception.NotExistFileException;
import im.zhaojun.common.model.dto.FileItemDTO;
import im.zhaojun.common.model.enums.FileTypeEnum;
import im.zhaojun.common.util.StringUtils;
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.util.StringUtils;
import javax.annotation.Resource;
import java.net.URL;
@@ -21,7 +22,7 @@ import java.util.Objects;
/**
* @author zhaojun
*/
public abstract class AbstractS3FileService extends AbstractFileService {
public abstract class AbstractS3BaseFileService extends AbstractBaseFileService {
@Resource
protected StorageConfigService storageConfigService;

View File

@@ -1,13 +1,13 @@
package im.zhaojun.common.service;
package im.zhaojun.zfile.service.base;
import im.zhaojun.common.model.dto.FileItemDTO;
import im.zhaojun.zfile.model.dto.FileItemDTO;
import java.util.List;
/**
* @author zhaojun
*/
public interface FileService {
public interface BaseFileService {
/***
* 获取指定路径下的文件及文件夹

View File

@@ -1,14 +1,15 @@
package im.zhaojun.aliyun.service;
package im.zhaojun.zfile.service.impl;
import cn.hutool.core.convert.Convert;
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.common.model.StorageConfig;
import im.zhaojun.common.model.constant.StorageConfigConstant;
import im.zhaojun.common.model.enums.StorageTypeEnum;
import im.zhaojun.common.service.AbstractS3FileService;
import im.zhaojun.common.service.FileService;
import im.zhaojun.zfile.model.entity.StorageConfig;
import im.zhaojun.zfile.model.constant.StorageConfigConstant;
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.stereotype.Service;
@@ -20,7 +21,7 @@ import java.util.Objects;
* @author zhaojun
*/
@Service
public class AliyunServiceImpl extends AbstractS3FileService implements FileService {
public class AliyunServiceImpl extends AbstractS3BaseFileService implements BaseFileService {
private static final Logger log = LoggerFactory.getLogger(AliyunServiceImpl.class);
@@ -36,6 +37,7 @@ public class AliyunServiceImpl extends AbstractS3FileService implements FileServ
super.domain = stringStorageConfigMap.get(StorageConfigConstant.DOMAIN_KEY).getValue();
super.basePath = stringStorageConfigMap.get(StorageConfigConstant.BASE_PATH).getValue();
super.bucketName = stringStorageConfigMap.get(StorageConfigConstant.BUCKET_NAME_KEY).getValue();
super.isPrivate = Convert.toBool(stringStorageConfigMap.get(StorageConfigConstant.IS_PRIVATE).getValue(), true);
if (Objects.isNull(accessKey) || Objects.isNull(secretKey) || Objects.isNull(endPoint) || Objects.isNull(bucketName)) {
log.debug("初始化存储策略 [{}] 失败: 参数不完整", getStorageTypeEnum().getDescription());

View File

@@ -1,17 +1,19 @@
package im.zhaojun.ftp.service;
package im.zhaojun.zfile.service.impl;
import cn.hutool.core.util.URLUtil;
import cn.hutool.extra.ftp.Ftp;
import im.zhaojun.common.model.StorageConfig;
import im.zhaojun.common.model.constant.StorageConfigConstant;
import im.zhaojun.common.model.dto.FileItemDTO;
import im.zhaojun.common.model.enums.FileTypeEnum;
import im.zhaojun.common.model.enums.StorageTypeEnum;
import im.zhaojun.common.service.AbstractFileService;
import im.zhaojun.common.service.FileService;
import im.zhaojun.common.service.StorageConfigService;
import im.zhaojun.common.util.StringUtils;
import org.apache.commons.net.ftp.*;
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.util.StringUtils;
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClientConfig;
import org.apache.commons.net.ftp.FTPFile;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
@@ -27,7 +29,7 @@ import java.util.Objects;
* @author zhaojun
*/
@Service
public class FtpServiceImpl extends AbstractFileService implements FileService {
public class FtpServiceImpl extends AbstractBaseFileService implements BaseFileService {
private static final Logger log = LoggerFactory.getLogger(FtpServiceImpl.class);
@@ -56,7 +58,7 @@ public class FtpServiceImpl extends AbstractFileService implements FileService {
username = stringStorageConfigMap.get(StorageConfigConstant.USERNAME_KEY).getValue();
password = stringStorageConfigMap.get(StorageConfigConstant.PASSWORD_KEY).getValue();
domain = stringStorageConfigMap.get(StorageConfigConstant.DOMAIN_KEY).getValue();
super.basePath = stringStorageConfigMap.get(StorageConfigConstant.BASE_PATH).getValue();;
super.basePath = stringStorageConfigMap.get(StorageConfigConstant.BASE_PATH).getValue();
if (Objects.isNull(host) || Objects.isNull(port) || Objects.isNull(username) || Objects.isNull(password)) {
isInitialized = false;
} else {
@@ -127,34 +129,4 @@ public class FtpServiceImpl extends AbstractFileService implements FileService {
fileItemDTO.setUrl(getDownloadUrl(path));
return fileItemDTO;
}
@Override
protected boolean testConnection() {
// FTPClient ftpClient = ftp.getClient();
// try {
// ftpClient.connect(host, Integer.parseInt(port));
// return ftpClient.login(username, password);
// } catch (Exception e) {
// e.printStackTrace();
// return false;
// }
return true;
}
private void ifDisConnectionReConnection() {
FTPClient ftpClient = ftp.getClient();
try {
// 验证FTP服务器是否登录成功
int replyCode = ftpClient.getReplyCode();
// ftpClient.reinitialize();
if (!FTPReply.isPositiveCompletion(replyCode)) {
System.out.println("断开了连接, 已尝试重新连接.");
ftpClient.connect(host, Integer.parseInt(port));
ftpClient.login(username, password);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}

View File

@@ -1,14 +1,15 @@
package im.zhaojun.huawei.service;
package im.zhaojun.zfile.service.impl;
import cn.hutool.core.convert.Convert;
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.common.model.StorageConfig;
import im.zhaojun.common.model.constant.StorageConfigConstant;
import im.zhaojun.common.model.enums.StorageTypeEnum;
import im.zhaojun.common.service.AbstractS3FileService;
import im.zhaojun.common.service.FileService;
import im.zhaojun.zfile.model.entity.StorageConfig;
import im.zhaojun.zfile.model.constant.StorageConfigConstant;
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.stereotype.Service;
@@ -20,7 +21,7 @@ import java.util.Objects;
* @author zhaojun
*/
@Service
public class HuaweiServiceImpl extends AbstractS3FileService implements FileService {
public class HuaweiServiceImpl extends AbstractS3BaseFileService implements BaseFileService {
private static final Logger log = LoggerFactory.getLogger(HuaweiServiceImpl.class);
@@ -36,6 +37,7 @@ public class HuaweiServiceImpl extends AbstractS3FileService implements FileServ
bucketName = stringStorageConfigMap.get(StorageConfigConstant.BUCKET_NAME_KEY).getValue();
domain = stringStorageConfigMap.get(StorageConfigConstant.DOMAIN_KEY).getValue();
basePath = stringStorageConfigMap.get(StorageConfigConstant.BASE_PATH).getValue();
isPrivate = Convert.toBool(stringStorageConfigMap.get(StorageConfigConstant.IS_PRIVATE).getValue(), true);
if (Objects.isNull(accessKey) || Objects.isNull(secretKey) || Objects.isNull(endPoint) || Objects.isNull(bucketName)) {
log.debug("初始化存储策略 [{}] 失败: 参数不完整", getStorageTypeEnum().getDescription());

View File

@@ -1,18 +1,18 @@
package im.zhaojun.local.service;
package im.zhaojun.zfile.service.impl;
import im.zhaojun.common.exception.NotExistFileException;
import im.zhaojun.common.model.StorageConfig;
import im.zhaojun.common.model.SystemConfig;
import im.zhaojun.common.model.constant.StorageConfigConstant;
import im.zhaojun.common.model.constant.SystemConfigConstant;
import im.zhaojun.common.model.dto.FileItemDTO;
import im.zhaojun.common.model.enums.FileTypeEnum;
import im.zhaojun.common.model.enums.StorageTypeEnum;
import im.zhaojun.common.repository.SystemConfigRepository;
import im.zhaojun.common.service.AbstractFileService;
import im.zhaojun.common.service.FileService;
import im.zhaojun.common.service.StorageConfigService;
import im.zhaojun.common.util.StringUtils;
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.enums.FileTypeEnum;
import im.zhaojun.zfile.model.enums.StorageTypeEnum;
import im.zhaojun.zfile.repository.SystemConfigRepository;
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.stereotype.Service;
@@ -29,7 +29,7 @@ import java.util.Objects;
* @author zhaojun
*/
@Service
public class LocalServiceImpl extends AbstractFileService implements FileService {
public class LocalServiceImpl extends AbstractBaseFileService implements BaseFileService {
private static final Logger log = LoggerFactory.getLogger(LocalServiceImpl.class);

View File

@@ -1,14 +1,15 @@
package im.zhaojun.minio;
package im.zhaojun.zfile.service.impl;
import cn.hutool.core.convert.Convert;
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.common.model.StorageConfig;
import im.zhaojun.common.model.constant.StorageConfigConstant;
import im.zhaojun.common.model.enums.StorageTypeEnum;
import im.zhaojun.common.service.AbstractS3FileService;
import im.zhaojun.common.service.FileService;
import im.zhaojun.zfile.model.entity.StorageConfig;
import im.zhaojun.zfile.model.constant.StorageConfigConstant;
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.stereotype.Service;
@@ -20,7 +21,7 @@ import java.util.Objects;
* @author zhaojun
*/
@Service
public class MinIOServiceImpl extends AbstractS3FileService implements FileService {
public class MinIOServiceImpl extends AbstractS3BaseFileService implements BaseFileService {
private static final Logger log = LoggerFactory.getLogger(MinIOServiceImpl.class);
@@ -34,6 +35,7 @@ public class MinIOServiceImpl extends AbstractS3FileService implements FileServi
String endPoint = stringStorageConfigMap.get(StorageConfigConstant.ENDPOINT_KEY).getValue();
bucketName = stringStorageConfigMap.get(StorageConfigConstant.BUCKET_NAME_KEY).getValue();
basePath = stringStorageConfigMap.get(StorageConfigConstant.BASE_PATH).getValue();
isPrivate = Convert.toBool(stringStorageConfigMap.get(StorageConfigConstant.IS_PRIVATE).getValue(), true);
if (Objects.isNull(accessKey) || Objects.isNull(secretKey) || Objects.isNull(endPoint) || Objects.isNull(bucketName)) {
log.debug("初始化存储策略 [{}] 失败: 参数不完整", getStorageTypeEnum().getDescription());

View File

@@ -1,12 +1,11 @@
package im.zhaojun.onedrive.china.service;
package im.zhaojun.zfile.service.impl;
import im.zhaojun.common.config.GlobalScheduleTask;
import im.zhaojun.common.model.StorageConfig;
import im.zhaojun.common.model.constant.StorageConfigConstant;
import im.zhaojun.common.model.enums.StorageTypeEnum;
import im.zhaojun.common.service.FileService;
import im.zhaojun.common.service.StorageConfigService;
import im.zhaojun.onedrive.common.service.AbstractOneDriveService;
import im.zhaojun.zfile.model.constant.StorageConfigConstant;
import im.zhaojun.zfile.model.entity.StorageConfig;
import im.zhaojun.zfile.model.enums.StorageTypeEnum;
import im.zhaojun.zfile.service.StorageConfigService;
import im.zhaojun.zfile.service.base.AbstractOneDriveServiceBase;
import im.zhaojun.zfile.service.base.BaseFileService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
@@ -20,10 +19,7 @@ import java.util.Map;
*/
@Service
@Slf4j
public class OneDriveChinaServiceImpl extends AbstractOneDriveService implements FileService {
@Resource
private GlobalScheduleTask globalScheduleTask;
public class OneDriveChinaServiceImpl extends AbstractOneDriveServiceBase implements BaseFileService {
@Resource
private StorageConfigService storageConfigService;

View File

@@ -1,12 +1,11 @@
package im.zhaojun.onedrive.international.service;
package im.zhaojun.zfile.service.impl;
import im.zhaojun.common.config.GlobalScheduleTask;
import im.zhaojun.common.model.StorageConfig;
import im.zhaojun.common.model.constant.StorageConfigConstant;
import im.zhaojun.common.model.enums.StorageTypeEnum;
import im.zhaojun.common.service.FileService;
import im.zhaojun.common.service.StorageConfigService;
import im.zhaojun.onedrive.common.service.AbstractOneDriveService;
import im.zhaojun.zfile.model.constant.StorageConfigConstant;
import im.zhaojun.zfile.model.entity.StorageConfig;
import im.zhaojun.zfile.model.enums.StorageTypeEnum;
import im.zhaojun.zfile.service.StorageConfigService;
import im.zhaojun.zfile.service.base.AbstractOneDriveServiceBase;
import im.zhaojun.zfile.service.base.BaseFileService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
@@ -20,10 +19,7 @@ import java.util.Map;
*/
@Service
@Slf4j
public class OneDriveServiceImpl extends AbstractOneDriveService implements FileService {
@Resource
private GlobalScheduleTask globalScheduleTask;
public class OneDriveServiceImpl extends AbstractOneDriveServiceBase implements BaseFileService {
@Resource
private StorageConfigService storageConfigService;

View File

@@ -1,14 +1,15 @@
package im.zhaojun.qiniu.service;
package im.zhaojun.zfile.service.impl;
import cn.hutool.core.convert.Convert;
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.common.model.StorageConfig;
import im.zhaojun.common.model.constant.StorageConfigConstant;
import im.zhaojun.common.model.enums.StorageTypeEnum;
import im.zhaojun.common.service.AbstractS3FileService;
import im.zhaojun.common.service.FileService;
import im.zhaojun.zfile.model.entity.StorageConfig;
import im.zhaojun.zfile.model.constant.StorageConfigConstant;
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.stereotype.Service;
@@ -20,7 +21,7 @@ import java.util.Objects;
* @author zhaojun
*/
@Service
public class QiniuServiceImpl extends AbstractS3FileService implements FileService {
public class QiniuServiceImpl extends AbstractS3BaseFileService implements BaseFileService {
private static final Logger log = LoggerFactory.getLogger(QiniuServiceImpl.class);
@@ -36,6 +37,7 @@ public class QiniuServiceImpl extends AbstractS3FileService implements FileServi
bucketName = stringStorageConfigMap.get(StorageConfigConstant.BUCKET_NAME_KEY).getValue();
domain = stringStorageConfigMap.get(StorageConfigConstant.DOMAIN_KEY).getValue();
basePath = stringStorageConfigMap.get(StorageConfigConstant.BASE_PATH).getValue();
isPrivate = Convert.toBool(stringStorageConfigMap.get(StorageConfigConstant.IS_PRIVATE).getValue(), true);
if (Objects.isNull(accessKey) || Objects.isNull(secretKey) || Objects.isNull(endPoint) || Objects.isNull(bucketName)) {
log.debug("初始化存储策略 [{}] 失败: 参数不完整", getStorageTypeEnum().getDescription());

View File

@@ -1,15 +1,15 @@
package im.zhaojun.s3;
package im.zhaojun.zfile.service.impl;
import cn.hutool.core.convert.Convert;
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.common.model.StorageConfig;
import im.zhaojun.common.model.constant.StorageConfigConstant;
import im.zhaojun.common.model.enums.StorageTypeEnum;
import im.zhaojun.common.service.AbstractS3FileService;
import im.zhaojun.common.service.FileService;
import im.zhaojun.zfile.model.entity.StorageConfig;
import im.zhaojun.zfile.model.constant.StorageConfigConstant;
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.stereotype.Service;
@@ -21,7 +21,7 @@ import java.util.Objects;
* @author zhaojun
*/
@Service
public class S3ServiceImpl extends AbstractS3FileService implements FileService {
public class S3ServiceImpl extends AbstractS3BaseFileService implements BaseFileService {
private static final Logger log = LoggerFactory.getLogger(S3ServiceImpl.class);

View File

@@ -1,14 +1,15 @@
package im.zhaojun.tencent;
package im.zhaojun.zfile.service.impl;
import cn.hutool.core.convert.Convert;
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.common.model.StorageConfig;
import im.zhaojun.common.model.constant.StorageConfigConstant;
import im.zhaojun.common.model.enums.StorageTypeEnum;
import im.zhaojun.common.service.AbstractS3FileService;
import im.zhaojun.common.service.FileService;
import im.zhaojun.zfile.model.entity.StorageConfig;
import im.zhaojun.zfile.model.constant.StorageConfigConstant;
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.stereotype.Service;
@@ -20,7 +21,7 @@ import java.util.Objects;
* @author zhaojun
*/
@Service
public class TencentServiceImpl extends AbstractS3FileService implements FileService {
public class TencentServiceImpl extends AbstractS3BaseFileService implements BaseFileService {
private static final Logger log = LoggerFactory.getLogger(TencentServiceImpl.class);
@@ -35,6 +36,7 @@ public class TencentServiceImpl extends AbstractS3FileService implements FileSer
bucketName = stringStorageConfigMap.get(StorageConfigConstant.BUCKET_NAME_KEY).getValue();
domain = stringStorageConfigMap.get(StorageConfigConstant.DOMAIN_KEY).getValue();
basePath = stringStorageConfigMap.get(StorageConfigConstant.BASE_PATH).getValue();
isPrivate = Convert.toBool(stringStorageConfigMap.get(StorageConfigConstant.IS_PRIVATE).getValue(), true);
if (Objects.isNull(secretId) || Objects.isNull(secretKey) || Objects.isNull(endPoint) || Objects.isNull(bucketName)) {
log.debug("初始化存储策略 [{}] 失败: 参数不完整", getStorageTypeEnum().getDescription());

View File

@@ -1,7 +1,6 @@
package im.zhaojun.ufile.service;
package im.zhaojun.zfile.service.impl;
import im.zhaojun.common.model.enums.StorageTypeEnum;
import im.zhaojun.upyun.service.UpYunServiceImpl;
import im.zhaojun.zfile.model.enums.StorageTypeEnum;
import org.springframework.stereotype.Service;
/**

View File

@@ -1,18 +1,18 @@
package im.zhaojun.upyun.service;
package im.zhaojun.zfile.service.impl;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.URLUtil;
import com.UpYun;
import im.zhaojun.common.exception.NotExistFileException;
import im.zhaojun.common.model.StorageConfig;
import im.zhaojun.common.model.constant.StorageConfigConstant;
import im.zhaojun.common.model.dto.FileItemDTO;
import im.zhaojun.common.model.enums.FileTypeEnum;
import im.zhaojun.common.model.enums.StorageTypeEnum;
import im.zhaojun.common.service.AbstractFileService;
import im.zhaojun.common.service.FileService;
import im.zhaojun.common.service.StorageConfigService;
import im.zhaojun.common.util.StringUtils;
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.enums.FileTypeEnum;
import im.zhaojun.zfile.model.enums.StorageTypeEnum;
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.stereotype.Service;
@@ -28,7 +28,7 @@ import java.util.Objects;
*/
@Service
@Slf4j
public class UpYunServiceImpl extends AbstractFileService implements FileService {
public class UpYunServiceImpl extends AbstractBaseFileService implements BaseFileService {
private static final String END_MARK = "g2gCZAAEbmV4dGQAA2VvZg";

View File

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

View File

@@ -1,5 +1,7 @@
package im.zhaojun.common.service;
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;
@@ -18,19 +20,19 @@ public class FileCacheService {
@Lazy
private FileAsyncCacheService fileAsyncCacheService;
@Resource
private ZFileCache zFileCache;
public void enableCache() {
systemConfigService.updateCacheEnableConfig(true);
AbstractFileService currentFileService = systemConfigService.getCurrentFileService();
currentFileService.openCacheAutoRefresh();
fileAsyncCacheService.cacheGlobalFile();
}
public void disableCache() throws Exception {
public void disableCache() {
systemConfigService.updateCacheEnableConfig(false);
AbstractFileService currentFileService = systemConfigService.getCurrentFileService();
currentFileService.clearFileCache();
zFileCache.clear();
fileAsyncCacheService.setCacheFinish(false);
fileAsyncCacheService.stopScheduled();
}
}

View File

@@ -1,6 +1,6 @@
package im.zhaojun.common.service;
package im.zhaojun.zfile.service.support;
import im.zhaojun.common.model.SystemMonitorInfo;
import im.zhaojun.zfile.model.support.SystemMonitorInfo;
import org.springframework.stereotype.Service;
/**
@@ -12,4 +12,5 @@ public class SystemMonitorService {
public SystemMonitorInfo systemMonitorInfo() {
return new SystemMonitorInfo();
}
}
}

View File

@@ -1,4 +1,4 @@
package im.zhaojun.common.util;
package im.zhaojun.zfile.util;
import cn.hutool.core.codec.Base64;
import cn.hutool.core.io.FileUtil;
@@ -10,8 +10,8 @@ import com.mpatric.mp3agic.ID3v2;
import com.mpatric.mp3agic.InvalidDataException;
import com.mpatric.mp3agic.Mp3File;
import com.mpatric.mp3agic.UnsupportedTagException;
import im.zhaojun.common.model.constant.ZFileConstant;
import im.zhaojun.common.model.dto.AudioInfoDTO;
import im.zhaojun.zfile.model.constant.ZFileConstant;
import im.zhaojun.zfile.model.dto.AudioInfoDTO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

View File

@@ -1,7 +1,7 @@
package im.zhaojun.common.util;
package im.zhaojun.zfile.util;
import im.zhaojun.common.model.dto.FileItemDTO;
import im.zhaojun.common.model.enums.FileTypeEnum;
import im.zhaojun.zfile.model.dto.FileItemDTO;
import im.zhaojun.zfile.model.enums.FileTypeEnum;
import java.util.Comparator;

View File

@@ -1,4 +1,4 @@
package im.zhaojun.common.util;
package im.zhaojun.zfile.util;
import cn.hutool.core.util.URLUtil;
import org.springframework.core.io.FileSystemResource;

View File

@@ -1,4 +1,4 @@
package im.zhaojun.common.util;
package im.zhaojun.zfile.util;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.client.RestClientException;

View File

@@ -1,4 +1,4 @@
package im.zhaojun.common.util;
package im.zhaojun.zfile.util;
/*
NaturalOrderComparator.java -- Perform 'natural order' comparisons of strings in Java.
Copyright (C) 2003 by Pierre-Luc Paour <natorder@paour.com>
@@ -25,8 +25,13 @@ package im.zhaojun.common.util;
import java.util.Comparator;
/**
* @author zhaojun
*/
public class NaturalOrderComparator implements Comparator<String> {
private static final char ZERO_CHAR = '0';
private int compareRight(String a, String b) {
int bias = 0, ia = 0, ib = 0;
@@ -61,9 +66,10 @@ public class NaturalOrderComparator implements Comparator<String> {
}
}
@Override
public int compare(String a, String b) {
int ia = 0, ib = 0;
int nza = 0, nzb = 0;
int nza, nzb;
char ca, cb;
while (true) {
@@ -74,8 +80,8 @@ public class NaturalOrderComparator implements Comparator<String> {
cb = charAt(b, ib);
// skip over leading spaces or zeros
while (Character.isSpaceChar(ca) || ca == '0') {
if (ca == '0') {
while (Character.isSpaceChar(ca) || ca == ZERO_CHAR) {
if (ca == ZERO_CHAR) {
nza++;
} else {
// Only count consecutive zeroes
@@ -130,11 +136,13 @@ public class NaturalOrderComparator implements Comparator<String> {
}
private static int compareEqual(String a, String b, int nza, int nzb) {
if (nza - nzb != 0)
if (nza - nzb != 0) {
return nza - nzb;
}
if (a.length() == b.length())
if (a.length() == b.length()) {
return a.compareTo(b);
}
return a.length() - b.length();
}

View File

@@ -1,4 +1,4 @@
package im.zhaojun.common.util;
package im.zhaojun.zfile.util;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

View File

@@ -1,14 +1,9 @@
package im.zhaojun.common.util;
package im.zhaojun.zfile.util;
import cn.hutool.core.net.NetUtil;
import im.zhaojun.common.cache.ZFileCache;
import im.zhaojun.common.exception.InitializeException;
import im.zhaojun.common.service.AbstractFileService;
import im.zhaojun.common.service.FileAsyncCacheService;
import im.zhaojun.common.service.SystemConfigService;
import lombok.SneakyThrows;
import im.zhaojun.zfile.exception.InitializeException;
import im.zhaojun.zfile.service.support.FileAsyncCacheService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.event.ApplicationStartedEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.core.env.Environment;
@@ -17,9 +12,6 @@ import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.Timer;
import java.util.TimerTask;
/**
* 项目启动监听器, 当项目启动时, 遍历当前对象存储的所有内容, 添加到缓存中.
@@ -35,52 +27,12 @@ public class StartupListener implements ApplicationListener<ApplicationStartedEv
@Resource
private Environment environment;
@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;
@Resource
private SystemConfigService systemConfigService;
@Override
public void onApplicationEvent(@NonNull ApplicationStartedEvent event) {
printStartInfo();
cacheAllFile();
enableCacheAutoRefreshTask();
}
private void enableCacheAutoRefreshTask() {
if (enableAutoRefreshCache) {
new Timer("testTimer").schedule(new TimerTask() {
@SneakyThrows
@Override
public void run() {
boolean enableCache = systemConfigService.getEnableCache();
if (!enableCache) {
return;
}
log.debug("开始调用自动刷新缓存");
Set<String> keySet = zFileCache.keySet();
for (String key : keySet) {
zFileCache.remove(key);
AbstractFileService currentFileService = systemConfigService.getCurrentFileService();
currentFileService.fileList(key);
}
}
}, delay * 1000,interval * 1000);
}
}
private void printStartInfo() {
String serverPort = environment.getProperty("server.port", "8080");

View File

@@ -1,4 +1,4 @@
package im.zhaojun.common.util;
package im.zhaojun.zfile.util;
import cn.hutool.core.util.ObjectUtil;

View File

@@ -5,6 +5,21 @@
"type": "java.lang.Long",
"description": "目录缓存过期时间 和 下载地址过期时间. 单位为秒."
},
{
"name": "zfile.cache.auto-refresh.enable",
"type": "java.lang.Boolean",
"description": "是否开启自动刷新缓存."
},
{
"name": "zfile.cache.auto-refresh.delay",
"type": "java.lang.Long",
"description": "启动项目后多久开始自动刷新缓存, 推荐与 interval 一致, 因为项目启动时会缓存所有文件. 单位为秒.."
},
{
"name": "zfile.cache.auto-refresh.interval",
"type": "java.lang.Long",
"description": "任务间隔时间, 也就是每多长时间会自动刷新缓存一次.."
},
{
"name": "zfile.constant.readme",
"type": "java.lang.String",
@@ -36,6 +51,26 @@
"name": "zfile.onedrive.scope",
"type": "java.lang.String",
"description": "OneDrive 认证权限."
},
{
"name": "zfile.onedrive-china.clientId",
"type": "java.lang.String",
"description": "OneDrive China ClientId."
},
{
"name": "zfile.onedrive-china.clientSecret",
"type": "java.lang.String",
"description": "OneDrive China ClientSecret."
},
{
"name": "zfile.onedrive-china.redirectUri",
"type": "java.lang.String",
"description": "OneDrive China 认证重定向地址."
},
{
"name": "zfile.onedrive-china.scope",
"type": "java.lang.String",
"description": "OneDrive China 认证权限."
}
]
}

View File

@@ -30,9 +30,9 @@ spring:
# MySQL 配置
# driver-class-name: com.mysql.jdbc.Driver
# url: jdbc:mysql://127.0.0.1:3306/zfile?characterEncoding=utf8&serverTimezone=Asia/Shanghai&useSSL=false
# username: root
# password: 123456
# url: jdbc:mysql://127.0.0.1:3306/zfile?characterEncoding=utf8&serverTimezone=Asia/Shanghai&useSSL=false
# username: root
# password: 123456
jackson:
date-format: yyyy-MM-dd HH:mm
time-zone: GMT+8
@@ -52,9 +52,9 @@ spring:
zfile:
cache:
auto-refresh:
enable: true # 是否开启自动刷新缓存.
delay: 1800 # 启动项目后多久开始自动刷新缓存, 推荐与 interval 一致, 因为项目启动时会缓存所有文件.
interval: 1800 # 任务间隔时间, 也就是每多长时间会自动刷新缓存一次.
enable: true # 是否开启自动刷新缓存.
delay: 1800 # 启动项目后多久开始自动刷新缓存, 推荐与 interval 一致, 因为项目启动时会缓存所有文件.
interval: 1800 # 任务间隔时间, 也就是每多长时间会自动刷新缓存一次.
timeout: 1800
constant:
readme: readme.md
@@ -68,4 +68,4 @@ zfile:
clientId: 4a72d927-1907-488d-9eb2-1b465c53c1c5
clientSecret: Y9CEA=82da5n-y_]KAWAgLH3?R9xf7Uw
redirectUri: https://zfile.jun6.net/onedrive/china-callback
scope: offline_access User.Read Files.ReadWrite.All
scope: offline_access User.Read Files.ReadWrite.All

View File

@@ -77,3 +77,10 @@ INSERT INTO STORAGE_CONFIG (`ID`, `k`, `TITLE`, `TYPE`) VALUES (57, 'username',
INSERT INTO STORAGE_CONFIG (`ID`, `k`, `TITLE`, `TYPE`) VALUES (58, 'password', '操作员密码', 'ufile');
INSERT INTO STORAGE_CONFIG (`ID`, `k`, `TITLE`, `TYPE`) VALUES (59, 'domain', '加速域名', 'ufile');
INSERT INTO STORAGE_CONFIG (`ID`, `k`, `TITLE`, `TYPE`) VALUES (60, 'base-path', '基路径', 'ufile');
INSERT INTO STORAGE_CONFIG (`ID`, `k`, `TITLE`, `TYPE`) VALUES (61, 'isPrivate', '是否是私有空间', 'tencent');
INSERT INTO STORAGE_CONFIG (`ID`, `k`, `TITLE`, `TYPE`) VALUES (62, 'isPrivate', '是否是私有空间', 'aliyun');
INSERT INTO STORAGE_CONFIG (`ID`, `k`, `TITLE`, `TYPE`) VALUES (63, 'isPrivate', '是否是私有空间', 'huawei');
INSERT INTO STORAGE_CONFIG (`ID`, `k`, `TITLE`, `TYPE`) VALUES (64, 'isPrivate', '是否是私有空间', 'minio');
INSERT INTO STORAGE_CONFIG (`ID`, `k`, `TITLE`, `TYPE`) VALUES (65, 'isPrivate', '是否是私有空间', 'qiniu');

View File

@@ -0,0 +1 @@
.el-row[data-v-333298fb]{overflow-y:auto}#siteForm[data-v-333298fb]{margin-top:20px;margin-left:20px}.zfile-word-aux[data-v-333298fb]{margin-left:20px;color:#aaa}

View File

@@ -1 +0,0 @@
.el-row[data-v-0d37620b]{overflow-y:auto}#siteForm[data-v-0d37620b]{margin-top:20px;margin-left:20px}#siteForm[data-v-0d37620b] .el-select{width:70%}.zfile-word-aux[data-v-0d37620b]{margin-left:20px;color:#aaa}

View File

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

View File

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

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