parent
9218a5c787
commit
2a33fc9d8a
@ -0,0 +1,180 @@ |
||||
package com.keyware.shandan.control; |
||||
|
||||
import cn.hutool.core.date.DateUtil; |
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
||||
import com.keyware.shandan.bianmu.entity.DirectoryVo; |
||||
import com.keyware.shandan.bianmu.service.DirectoryService; |
||||
import com.keyware.shandan.frame.properties.CustomProperties; |
||||
import com.keyware.shandan.system.entity.SysFile; |
||||
import com.keyware.shandan.system.entity.SysUser; |
||||
import com.keyware.shandan.system.service.SysFileService; |
||||
import com.keyware.shandan.system.service.SysUserService; |
||||
import lombok.Builder; |
||||
import lombok.Data; |
||||
import lombok.extern.slf4j.Slf4j; |
||||
import org.springframework.stereotype.Component; |
||||
import org.springframework.util.Assert; |
||||
import org.springframework.util.StringUtils; |
||||
|
||||
import java.io.File; |
||||
import java.util.ArrayList; |
||||
import java.util.HashSet; |
||||
import java.util.List; |
||||
import java.util.Set; |
||||
import java.util.concurrent.ConcurrentHashMap; |
||||
import java.util.stream.Collectors; |
||||
|
||||
/** |
||||
* 用于对文件进行失效验证 |
||||
*/ |
||||
@Slf4j |
||||
@Component |
||||
public class InvalidFileHandler { |
||||
private final String storagePath; |
||||
private final SysUserService userService; |
||||
private final DirectoryService directoryService; |
||||
private final SysFileService fileService; |
||||
|
||||
private final ConcurrentHashMap<String, InvalidItem> cache = new ConcurrentHashMap<>(); |
||||
|
||||
public InvalidFileHandler(CustomProperties customProperties, |
||||
SysUserService userService, |
||||
DirectoryService directoryService, |
||||
SysFileService fileService) { |
||||
this.userService = userService; |
||||
this.directoryService = directoryService; |
||||
this.fileService = fileService; |
||||
this.storagePath = customProperties.getFileStorage().getPath(); |
||||
} |
||||
|
||||
/** |
||||
* 开始验证 |
||||
*/ |
||||
public void startValid() { |
||||
log.info("文件校验处理器启动成功"); |
||||
new Thread(() -> { |
||||
while (true) { |
||||
refreshInvalidCache("ROOT"); |
||||
try { |
||||
Thread.sleep(1000 * 10);// 1小时执行一次
|
||||
} catch (InterruptedException e) { |
||||
throw new RuntimeException(e); |
||||
} |
||||
} |
||||
}).start(); |
||||
} |
||||
|
||||
/** |
||||
* 刷新失效文件的缓存 |
||||
* |
||||
* @param dirId 指定目录ID |
||||
*/ |
||||
public void refreshInvalidCache(String dirId) { |
||||
if (!StringUtils.hasText(dirId)) { |
||||
dirId = "ROOT"; |
||||
} |
||||
Set<String> idSet = new HashSet<>(); |
||||
directoryService.handlerAllChildrenListById(dirId, (context) -> { |
||||
DirectoryVo dir = context.getResultObject(); |
||||
if (StringUtils.hasText(dir.getResourceId())) { |
||||
// 查询对应的文件资源
|
||||
SysFile sf = fileService.getById(dir.getResourceId()); |
||||
if (sf != null) { |
||||
File file = new File(storagePath + File.separator + sf.getPath()); |
||||
if (!file.exists()) { |
||||
SysUser user = userService.getById(sf.getModifyUser()); |
||||
InvalidItem item = InvalidItem.builder() |
||||
.id(sf.getId()) |
||||
.dirId(dir.getId()) |
||||
.directoryPath(dir.getDirectoryPath()) |
||||
.fileName(sf.getFileName()) |
||||
.fileType(sf.getFileType()) |
||||
.fileSize(sf.getFileSize()) |
||||
.createTime(DateUtil.format(sf.getModifyTime(), "yyyy-MM-dd HH:mm")) |
||||
.createUser(user == null ? sf.getModifyUser() : user.getUserName()) |
||||
.build(); |
||||
cache.put(sf.getId(), item); |
||||
idSet.add(sf.getId()); |
||||
} |
||||
} |
||||
} |
||||
}); |
||||
|
||||
// 与新的结果进行比对,将结果中不存在的缓存清除掉
|
||||
List<String> keys = new ArrayList<>(); |
||||
cache.forEachKey(1, keys::add); |
||||
keys.forEach(key -> { |
||||
if (!idSet.contains(key)) { |
||||
cache.remove(key); |
||||
} |
||||
}); |
||||
} |
||||
|
||||
/** |
||||
* 检索指定目录下的失效文件 |
||||
* |
||||
* @param dirId 目录ID |
||||
* @param refresh 是否重新刷新 |
||||
* @return |
||||
*/ |
||||
public List<InvalidItem> listByDir(String dirId, boolean refresh) { |
||||
DirectoryVo dir = directoryService.getById(dirId); |
||||
Assert.notNull(dir, "查询的目录不存在"); |
||||
if (refresh) { |
||||
refreshInvalidCache(dirId); |
||||
} |
||||
String path = dir.getDirectoryPath(); |
||||
return cache.values().stream().filter(item -> item.getDirectoryPath().startsWith(path + "/")).collect(Collectors.toList()); |
||||
} |
||||
|
||||
/** |
||||
* 清理文件数据 |
||||
* |
||||
* @param fileId 文件ID |
||||
*/ |
||||
public void clean(String fileId) { |
||||
fileService.deleteById(fileId); |
||||
cleanDirectory(fileId); |
||||
cache.remove(fileId); |
||||
} |
||||
|
||||
/** |
||||
* 移除指定文件的缓存 |
||||
* |
||||
* @param fileId 文件ID |
||||
*/ |
||||
public void removeCache(String fileId) { |
||||
cache.remove(fileId); |
||||
} |
||||
|
||||
/** |
||||
* 递归清理文件管理的目录资源,以及引用的资源 |
||||
* |
||||
* @param resourceId |
||||
*/ |
||||
private void cleanDirectory(String resourceId) { |
||||
LambdaQueryWrapper<DirectoryVo> query = new LambdaQueryWrapper<>(); |
||||
query.eq(DirectoryVo::getResourceId, resourceId); |
||||
List<DirectoryVo> dirs = directoryService.list(query); |
||||
dirs.forEach(dir -> { |
||||
cleanDirectory(dir.getId()); |
||||
directoryService.deleteById(dir.getId()); |
||||
}); |
||||
} |
||||
|
||||
/** |
||||
* 失效的缓存项 |
||||
*/ |
||||
@Data |
||||
@Builder |
||||
public static class InvalidItem { |
||||
private String id; |
||||
private String dirId; |
||||
private String directoryPath; |
||||
private String fileName; |
||||
private String fileType; |
||||
private Double fileSize; |
||||
private String createTime; |
||||
private String createUser; |
||||
} |
||||
} |
Reference in new issue