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