完成品牌部分改造

This commit is contained in:
super
2026-03-24 22:22:37 +08:00
parent 7ffe5279a3
commit 2cd0fcff93
37 changed files with 2086 additions and 11 deletions
@@ -96,7 +96,7 @@ public class LocalFileStorageService {
}
}
private File findLocalSourceFile(String fileKey) {
public File findLocalSourceFile(String fileKey) {
File baseDir = FileUtil.file(storageProperties.getLocalTempDir());
if (!baseDir.exists()) {
return null;
@@ -0,0 +1,116 @@
package com.nanri.aiimage.modules.file.service;
import cn.hutool.core.io.FileUtil;
import com.nanri.aiimage.config.StorageProperties;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import java.io.File;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.List;
import java.util.regex.Pattern;
@Slf4j
@Service
@RequiredArgsConstructor
public class LocalTempCleanupService {
private static final Pattern ROOT_TEMP_FILE_PATTERN = Pattern.compile("^[a-fA-F0-9]{32}(\\.[^.]+)?$");
private static final List<String> RESULT_DIR_NAMES = List.of(
"dedupe-result",
"convert-result",
"split-result",
"brand-source-download",
"brand-result"
);
private final StorageProperties storageProperties;
@Scheduled(cron = "${aiimage.storage.cleanup-cron:0 0 */6 * * *}")
public void cleanupLocalTempDir() {
if (!storageProperties.isCleanupEnabled()) {
return;
}
File tempDir = FileUtil.file(storageProperties.getLocalTempDir());
if (!tempDir.exists() || !tempDir.isDirectory()) {
return;
}
Instant sourceExpireBefore = Instant.now().minus(storageProperties.getSourceRetentionHours(), ChronoUnit.HOURS);
Instant resultExpireBefore = Instant.now().minus(storageProperties.getResultRetentionHours(), ChronoUnit.HOURS);
int deletedSourceCount = 0;
int deletedResultCount = 0;
File[] children = tempDir.listFiles();
if (children == null || children.length == 0) {
return;
}
for (File child : children) {
try {
if (child.isFile() && isManagedRootTempFile(child) && isExpired(child, sourceExpireBefore)) {
if (FileUtil.del(child)) {
deletedSourceCount++;
}
continue;
}
if (child.isDirectory() && RESULT_DIR_NAMES.contains(child.getName())) {
deletedResultCount += deleteExpiredChildrenRecursively(child, resultExpireBefore);
deleteEmptyDirectories(child, tempDir);
}
} catch (Exception ex) {
log.warn("清理本地临时文件失败: path={}", child.getAbsolutePath(), ex);
}
}
if (deletedSourceCount > 0 || deletedResultCount > 0) {
log.info("本地临时目录清理完成: sourceDeleted={}, resultDeleted={}, tempDir={}", deletedSourceCount, deletedResultCount, tempDir.getAbsolutePath());
}
}
private int deleteExpiredChildrenRecursively(File file, Instant expireBefore) {
int deletedCount = 0;
if (file.isDirectory()) {
File[] children = file.listFiles();
if (children != null) {
for (File child : children) {
deletedCount += deleteExpiredChildrenRecursively(child, expireBefore);
}
}
if (isExpired(file, expireBefore) && isDirectoryEmpty(file) && FileUtil.del(file)) {
deletedCount++;
}
return deletedCount;
}
if (isExpired(file, expireBefore) && FileUtil.del(file)) {
return 1;
}
return 0;
}
private void deleteEmptyDirectories(File directory, File stopAt) {
File current = directory;
while (current != null && !current.equals(stopAt) && isDirectoryEmpty(current)) {
if (!FileUtil.del(current)) {
return;
}
current = current.getParentFile();
}
}
private boolean isManagedRootTempFile(File file) {
return ROOT_TEMP_FILE_PATTERN.matcher(file.getName()).matches();
}
private boolean isExpired(File file, Instant expireBefore) {
return Instant.ofEpochMilli(file.lastModified()).isBefore(expireBefore);
}
private boolean isDirectoryEmpty(File directory) {
File[] children = directory.listFiles();
return children == null || children.length == 0;
}
}