import { Injectable, Logger } from '@nestjs/common'; import { Cron, CronExpression } from '@nestjs/schedule'; import * as fs from 'fs/promises'; import * as path from 'path'; import { UploadService } from './upload.service'; @Injectable() export class CleanService { private readonly logger = new Logger(CleanService.name); private readonly tempDir: string; private readonly TEMP_FILE_EXPIRATION_TIME = 24 * 60 * 60 * 1000; // 24 hours constructor(private uploadService: UploadService) { this.tempDir = process.env.UPLOAD_TEMP_DIR || path.join(process.cwd(), 'uploads', 'temp'); } @Cron(CronExpression.EVERY_6_HOURS) async cleanExpiredTemporaryFiles(): Promise { try { const files = await fs.readdir(this.tempDir); for (const identifier of files) { const chunkDir = path.join(this.tempDir, identifier); try { const stat = await fs.stat(chunkDir); // 检查目录是否超过过期时间 const isExpired = (Date.now() - stat.mtime.getTime()) > this.TEMP_FILE_EXPIRATION_TIME; // 检查上传是否不在进行中 const status = this.uploadService.checkUploadStatusInfo(identifier); const isNotInProgress = !status || status.status === 'completed' || status.status === 'error' || status.status === 'paused'; if (isExpired && isNotInProgress) { await fs.rm(chunkDir, { recursive: true, force: true }); this.logger.log(`Cleaned up expired temporary files for identifier: ${identifier}`); this.uploadService.deleteUploadStatusInfo(identifier); } } catch (statError) { // 处理可能的文件系统错误 this.logger.error(`Error processing directory ${identifier}: ${statError}`); } } } catch (error) { this.logger.error(`Error during temporary file cleanup: ${error instanceof Error ? error.message : error}`); } } }