后端改为使用日志记录器管理日志

This commit is contained in:
2025-08-31 18:55:22 +08:00
parent ad5dfc64cb
commit a09d6cab0e
30 changed files with 962 additions and 323 deletions
+20 -15
View File
@@ -2,6 +2,11 @@ const fs = require('fs').promises;
const path = require('path');
const crypto = require('crypto');
const CacheConfigManager = require('../config/cache-config');
const { defaultLogger } = require('../utils/logger');
// 创建logger实例
const logger = defaultLogger.child('ApiCacheService');
/**
* API缓存服务
@@ -72,9 +77,9 @@ class ApiCacheService {
// 启动定期清理任务
this.startCleanupTask();
// console.log('API缓存服务初始化完成');
// logger.info('API缓存服务初始化完成');
} catch (error) {
console.error('API缓存服务初始化失败:', error);
logger.error('API缓存服务初始化失败:', error);
}
}
@@ -84,9 +89,9 @@ class ApiCacheService {
async ensureCacheDir() {
try {
await fs.mkdir(this.cacheDir, { recursive: true });
// console.log('API缓存目录创建成功:', this.cacheDir);
// logger.info('API缓存目录创建成功:', this.cacheDir);
} catch (error) {
console.error('创建API缓存目录失败:', error);
logger.error('创建API缓存目录失败:', error);
}
}
@@ -188,7 +193,7 @@ class ApiCacheService {
return JSON.parse(data);
} catch (error) {
console.error('读取API缓存失败:', error);
logger.error('读取API缓存失败:', error);
return null;
}
}
@@ -208,7 +213,7 @@ class ApiCacheService {
// 检查缓存大小,如果超过限制则清理
await this.checkCacheSize();
} catch (error) {
console.error('保存API缓存失败:', error);
logger.error('保存API缓存失败:', error);
}
}
@@ -303,7 +308,7 @@ class ApiCacheService {
// 如果超过最大大小,删除最旧的文件
if (totalSize > this.config.maxSize) {
console.log(`API缓存大小 ${totalSize} 超过限制 ${this.config.maxSize},开始清理...`);
logger.info(`API缓存大小 ${totalSize} 超过限制 ${this.config.maxSize},开始清理...`);
// 按修改时间排序,删除最旧的文件
fileStats.sort((a, b) => a.mtime.getTime() - b.mtime.getTime());
@@ -317,10 +322,10 @@ class ApiCacheService {
}
}
console.log(`API缓存清理完成,当前大小: ${totalSize}`);
logger.info(`API缓存清理完成,当前大小: ${totalSize}`);
}
} catch (error) {
console.error('检查API缓存大小失败:', error);
logger.error('检查API缓存大小失败:', error);
}
}
@@ -345,10 +350,10 @@ class ApiCacheService {
}
if (cleanedCount > 0) {
console.log(`清理了 ${cleanedCount} 个过期API缓存文件`);
logger.info(`清理了 ${cleanedCount} 个过期API缓存文件`);
}
} catch (error) {
console.error('清理过期API缓存失败:', error);
logger.error('清理过期API缓存失败:', error);
}
}
@@ -358,7 +363,7 @@ class ApiCacheService {
startCleanupTask() {
setInterval(() => {
this.cleanupExpiredCache().catch(error => {
console.error('定期清理API缓存任务失败:', error);
logger.error('定期清理API缓存任务失败:', error);
});
}, this.config.cleanupInterval);
}
@@ -376,9 +381,9 @@ class ApiCacheService {
await fs.unlink(filePath);
}
console.log('所有API缓存已清理');
logger.info('所有API缓存已清理');
} catch (error) {
console.error('清理所有API缓存失败:', error);
logger.error('清理所有API缓存失败:', error);
throw error;
}
}
@@ -410,7 +415,7 @@ class ApiCacheService {
config: this.config
};
} catch (error) {
console.error('获取API缓存统计失败:', error);
logger.error('获取API缓存统计失败:', error);
return {
fileCount: 0,
totalSize: 0,
+14 -9
View File
@@ -1,6 +1,11 @@
const axios = require('axios');
const { stringify } = require('qs');
const ApiCacheService = require('./api-cache');
const { defaultLogger } = require('../utils/logger');
// 创建logger实例
const logger = defaultLogger.child('ArtistService');
class ArtistService {
constructor(auth) {
@@ -197,7 +202,7 @@ class ArtistService {
limit,
};
console.log(`请求关注列表: offset=${currentOffset}, limit=${limit}`);
logger.info(`请求关注列表: offset=${currentOffset}, limit=${limit}`);
const response = await this.makeRequest('GET', `/v1/user/following?${stringify(params)}`);
// 转换数据格式以匹配前端期望
@@ -210,12 +215,12 @@ class ArtistService {
}));
allArtists.push(...artists);
console.log(`本次获取到 ${artists.length} 个作者,累计 ${allArtists.length}`);
logger.info(`本次获取到 ${artists.length} 个作者,累计 ${allArtists.length}`);
// 如果返回的数量少于limit,说明已经获取完所有数据
if (artists.length < limit) {
hasMore = false;
console.log('已获取完所有关注的作者');
logger.info('已获取完所有关注的作者');
} else {
currentOffset += artists.length;
}
@@ -229,7 +234,7 @@ class ArtistService {
},
};
} catch (error) {
console.error('获取关注作者列表失败:', error.message);
logger.error('获取关注作者列表失败:', error.message);
return {
success: false,
error: error.message,
@@ -335,11 +340,11 @@ class ArtistService {
try {
const cachedData = await this.apiCache.get(method, endpoint, data || {});
if (cachedData) {
// console.log(`API缓存命中: ${method} ${endpoint}`);
// logger.info(`API缓存命中: ${method} ${endpoint}`);
return cachedData;
}
} catch (error) {
console.error('读取API缓存失败:', error);
logger.error('读取API缓存失败:', error);
}
}
@@ -378,15 +383,15 @@ class ArtistService {
if (method === 'GET') {
try {
await this.apiCache.set(method, endpoint, data || {}, responseData);
console.log(`API缓存已保存: ${method} ${endpoint}`);
logger.info(`API缓存已保存: ${method} ${endpoint}`);
} catch (error) {
console.error('保存API缓存失败:', error);
logger.error('保存API缓存失败:', error);
}
}
return responseData;
} catch (error) {
console.error('API请求失败:', {
logger.error('API请求失败:', {
method,
endpoint,
status: error.response?.status,
+14 -9
View File
@@ -1,6 +1,11 @@
const axios = require('axios');
const { stringify } = require('qs');
const ApiCacheService = require('./api-cache');
const { defaultLogger } = require('../utils/logger');
// 创建logger实例
const logger = defaultLogger.child('ArtworkService');
class ArtworkService {
constructor(auth) {
@@ -205,8 +210,8 @@ class ArtworkService {
},
};
} catch (error) {
console.error('Search error:', error.message);
console.error('Search error details:', error.response?.data);
logger.error('Search error:', error.message);
logger.error('Search error details:', error.response?.data);
return {
success: false,
@@ -293,7 +298,7 @@ class ArtworkService {
try {
// TODO: 需要研究新的 Pixiv API 端点
// 当前所有收藏相关的 API 端点都返回 404 错误
console.log(`尝试${action === 'add' ? '添加' : '删除'}收藏 ${artworkId},但API端点不可用`);
logger.info(`尝试${action === 'add' ? '添加' : '删除'}收藏 ${artworkId},但API端点不可用`);
return {
success: false,
@@ -348,7 +353,7 @@ class ArtworkService {
},
};
} catch (error) {
console.error('获取收藏列表失败:', {
logger.error('获取收藏列表失败:', {
message: error.message,
status: error.response?.status,
data: error.response?.data,
@@ -370,11 +375,11 @@ class ArtworkService {
try {
const cachedData = await this.apiCache.get(method, endpoint, data || {});
if (cachedData) {
// console.log(`API缓存命中: ${method} ${endpoint}`);
// logger.info(`API缓存命中: ${method} ${endpoint}`);
return cachedData;
}
} catch (error) {
console.error('读取API缓存失败:', error);
logger.error('读取API缓存失败:', error);
}
}
@@ -415,15 +420,15 @@ class ArtworkService {
if (method === 'GET') {
try {
await this.apiCache.set(method, endpoint, data || {}, responseData);
// console.log(`API缓存已保存: ${method} ${endpoint}`);
// logger.info(`API缓存已保存: ${method} ${endpoint}`);
} catch (error) {
console.error('保存API缓存失败:', error);
logger.error('保存API缓存失败:', error);
}
}
return responseData;
} catch (error) {
console.error('API request failed:', {
logger.error('API request failed:', {
method,
endpoint,
error: error.message,
+13 -8
View File
@@ -1,5 +1,10 @@
const path = require('path');
const fs = require('fs-extra');
const { defaultLogger } = require('../utils/logger');
// 创建logger实例
const logger = defaultLogger.child('DownloadExecutor');
/**
* 下载执行器 - 负责具体的下载逻辑执行
@@ -27,7 +32,7 @@ class DownloadExecutor {
// 检查是否应该暂停
if (this.shouldPause(task.id)) {
console.log('任务已暂停,停止下载:', task.id);
logger.info('任务已暂停,停止下载:', task.id);
break;
}
@@ -55,7 +60,7 @@ class DownloadExecutor {
// 确保imageUrl是字符串
if (typeof imageUrl !== 'string') {
console.error(`图片URL不是字符串:`, imageUrl);
logger.error(`图片URL不是字符串:`, imageUrl);
task.failed_files++;
this.progressManager.notifyProgressUpdate(task.id, task);
results.push({ success: false, error: '图片URL格式错误' });
@@ -78,7 +83,7 @@ class DownloadExecutor {
continue;
} else {
// 文件不完整,删除重新下载
console.log(`文件不完整,重新下载: ${filePath}`);
logger.info(`文件不完整,重新下载: ${filePath}`);
await this.fileManager.safeDeleteFile(filePath);
}
}
@@ -104,7 +109,7 @@ class DownloadExecutor {
results.push({ success: true, file: fileName });
} catch (error) {
task.failed_files++;
console.error(`下载图片失败 ${index + 1}: ${error.message}`);
logger.error(`下载图片失败 ${index + 1}: ${error.message}`);
this.progressManager.notifyProgressUpdate(task.id, task);
results.push({ success: false, error: error.message });
}
@@ -139,7 +144,7 @@ class DownloadExecutor {
await this.historyManager.addHistoryItem(historyItem);
} catch (error) {
console.error('异步下载执行失败:', error);
logger.error('异步下载执行失败:', error);
task.status = 'failed';
task.error = error.message;
task.end_time = new Date();
@@ -166,7 +171,7 @@ class DownloadExecutor {
// 检查是否应该暂停
if (this.shouldPause(task.id)) {
console.log('批量下载任务已暂停,停止下载:', task.id);
logger.info('批量下载任务已暂停,停止下载:', task.id);
break;
}
@@ -508,7 +513,7 @@ class DownloadExecutor {
*/
getFileExtension(url) {
if (typeof url !== 'string') {
console.warn('URL不是字符串,使用默认扩展名:', url);
logger.warn('URL不是字符串,使用默认扩展名:', url);
return 'jpg';
}
@@ -551,7 +556,7 @@ class DownloadExecutor {
} else if (task.type === 'batch' || task.type === 'artist') {
// 批量下载和作者下载的恢复逻辑
// 这里需要根据具体实现来恢复
console.log('恢复批量下载任务:', taskId);
logger.info('恢复批量下载任务:', taskId);
// TODO: 实现批量下载的恢复逻辑
}
+25 -20
View File
@@ -7,6 +7,11 @@ const ProgressManager = require('./progress-manager');
const HistoryManager = require('./history-manager');
const DownloadExecutor = require('./download-executor');
const fs = require('fs-extra'); // Added for fs-extra
const { defaultLogger } = require('../utils/logger');
// 创建logger实例
const logger = defaultLogger.child('DownloadService');
/**
* 下载服务 - 主服务类,协调各个管理器
@@ -56,7 +61,7 @@ class DownloadService {
this.initialized = true;
// 下载服务初始化完成
} catch (error) {
console.error('下载服务初始化失败:', error);
logger.error('下载服务初始化失败:', error);
this.initialized = false;
}
}
@@ -352,7 +357,7 @@ class DownloadService {
return files.sort((a, b) => new Date(b.created_at) - new Date(a.created_at));
} catch (error) {
console.error('获取下载文件列表失败:', error);
logger.error('获取下载文件列表失败:', error);
return [];
}
}
@@ -396,7 +401,7 @@ class DownloadService {
return Array.from(downloadedIds);
} catch (error) {
console.error('获取已下载作品ID列表失败:', error);
logger.error('获取已下载作品ID列表失败:', error);
return [];
}
}
@@ -430,7 +435,7 @@ class DownloadService {
const infoContent = await fs.readFile(infoPath, 'utf8');
artworkInfo = JSON.parse(infoContent);
} catch (error) {
console.log(`作品 ${artworkId} 缺少信息文件,认为未下载`);
logger.info(`作品 ${artworkId} 缺少信息文件,认为未下载`);
return false;
}
@@ -439,19 +444,19 @@ class DownloadService {
const imageFiles = files.filter(file => /\.(jpg|jpeg|png|gif|webp)$/i.test(file) && file !== 'artwork_info.json');
if (imageFiles.length === 0) {
console.log(`作品 ${artworkId} 有信息文件但没有图片文件,认为未下载`);
logger.info(`作品 ${artworkId} 有信息文件但没有图片文件,认为未下载`);
return false;
}
// 检查图片数量是否与artwork_info.json中记录的一致
const expectedImageCount = artworkInfo.page_count || 1;
if (imageFiles.length < expectedImageCount) {
console.log(`作品 ${artworkId} 图片数量不匹配: 期望 ${expectedImageCount} 个,实际 ${imageFiles.length}`);
logger.info(`作品 ${artworkId} 图片数量不匹配: 期望 ${expectedImageCount} 个,实际 ${imageFiles.length}`);
return false;
}
// 有信息文件、有图片文件且数量匹配,认为已下载
// console.log(`作品 ${artworkId} 已完整下载,有信息文件和 ${imageFiles.length}/${expectedImageCount} 个图片文件`);
// logger.info(`作品 ${artworkId} 已完整下载,有信息文件和 ${imageFiles.length}/${expectedImageCount} 个图片文件`);
return true;
}
}
@@ -459,7 +464,7 @@ class DownloadService {
return false;
} catch (error) {
console.error('检查作品下载状态失败:', error);
logger.error('检查作品下载状态失败:', error);
return false;
}
}
@@ -508,7 +513,7 @@ class DownloadService {
// 如果是重新下载,先删除现有目录
if (!skipExisting && (await this.fileManager.directoryExists(artworkDir))) {
console.log(`删除现有作品目录: ${artworkDir}`);
logger.info(`删除现有作品目录: ${artworkDir}`);
await this.fileManager.removeDirectory(artworkDir);
}
@@ -553,7 +558,7 @@ class DownloadService {
},
};
} catch (error) {
console.error('下载作品失败:', error);
logger.error('下载作品失败:', error);
return {
success: false,
error: error.message,
@@ -630,7 +635,7 @@ class DownloadService {
},
};
} catch (error) {
console.error('批量下载失败:', error);
logger.error('批量下载失败:', error);
return {
success: false,
error: error.message,
@@ -678,7 +683,7 @@ class DownloadService {
// 如果是重新下载,先删除现有目录
if (!skipExisting && (await this.fileManager.directoryExists(artworkDir))) {
console.log(`删除现有作品目录: ${artworkDir}`);
logger.info(`删除现有作品目录: ${artworkDir}`);
await this.fileManager.removeDirectory(artworkDir);
}
@@ -719,7 +724,7 @@ class DownloadService {
// 确保imageUrl是字符串
if (typeof imageUrl !== 'string') {
console.error(`图片URL不是字符串:`, imageUrl);
logger.error(`图片URL不是字符串:`, imageUrl);
results.push({ success: false, error: '图片URL格式错误' });
continue;
}
@@ -739,7 +744,7 @@ class DownloadService {
await this.fileManager.downloadFile(imageUrl, filePath);
results.push({ success: true, file: fileName });
} catch (error) {
console.error(`下载图片失败 ${index + 1}: ${error.message}`);
logger.error(`下载图片失败 ${index + 1}: ${error.message}`);
results.push({ success: false, error: error.message });
}
}
@@ -763,7 +768,7 @@ class DownloadService {
results: results,
};
} catch (error) {
console.error(`下载作品 ${artworkId} 失败:`, error);
logger.error(`下载作品 ${artworkId} 失败:`, error);
return {
success: false,
error: error.message,
@@ -777,7 +782,7 @@ class DownloadService {
*/
getFileExtension(url) {
if (typeof url !== 'string') {
console.warn('URL不是字符串,使用默认扩展名:', url);
logger.warn('URL不是字符串,使用默认扩展名:', url);
return 'jpg';
}
@@ -800,7 +805,7 @@ class DownloadService {
artistName = artistResult.data.name || `作者 ${artistId}`;
}
} catch (err) {
console.warn(`获取作者 ${artistId} 信息失败:`, err.message);
logger.warn(`获取作者 ${artistId} 信息失败:`, err.message);
}
// 创建任务记录
@@ -901,7 +906,7 @@ class DownloadService {
},
};
} catch (error) {
console.error('作者作品下载失败:', error);
logger.error('作者作品下载失败:', error);
return {
success: false,
error: error.message,
@@ -1013,7 +1018,7 @@ class DownloadService {
},
};
} catch (error) {
console.error('排行榜作品下载失败:', error);
logger.error('排行榜作品下载失败:', error);
return {
success: false,
error: error.message,
@@ -1046,7 +1051,7 @@ class DownloadService {
},
};
} catch (error) {
console.error('获取排行榜失败:', error);
logger.error('获取排行榜失败:', error);
return {
success: false,
error: error.message,
+11 -7
View File
@@ -5,6 +5,10 @@ const crypto = require('crypto');
const ConfigManager = require('../config/config-manager');
const FileUtils = require('../utils/file-utils');
const ErrorHandler = require('../utils/error-handler');
const { defaultLogger } = require('../utils/logger');
// 创建logger实例
const logger = defaultLogger.child('FileManager');
/**
* 文件管理器 - 负责文件下载、检查和目录管理
@@ -36,7 +40,7 @@ class FileManager {
? downloadDir
: path.resolve(process.cwd(), downloadDir);
} catch (error) {
console.error('获取下载路径失败:', error);
logger.error('获取下载路径失败:', error);
// 返回默认路径
return path.resolve(process.cwd(), 'downloads');
}
@@ -141,7 +145,7 @@ class FileManager {
fs.access(filePath)
.then(() => resolve())
.catch(error => {
console.error(`文件写入验证失败: ${filePath}`, error.message);
logger.error(`文件写入验证失败: ${filePath}`, error.message);
reject(error);
});
});
@@ -150,7 +154,7 @@ class FileManager {
try {
await this.safeDeleteFile(filePath);
} catch (removeError) {
console.warn('清理失败文件时出错:', removeError.message);
logger.warn('清理失败文件时出错:', removeError.message);
}
reject(error);
});
@@ -161,7 +165,7 @@ class FileManager {
// 处理文件系统错误
const errorResult = ErrorHandler.handleFileSystemError(error, filePath, 'download');
console.error(`下载文件失败 (尝试 ${attempt}/${maxRetries}): ${filePath}`, error.message);
logger.error(`下载文件失败 (尝试 ${attempt}/${maxRetries}): ${filePath}`, error.message);
// 如果不是可重试的错误,直接抛出
if (!errorResult.retryable) {
@@ -170,13 +174,13 @@ class FileManager {
// 如果是最后一次尝试,抛出错误
if (attempt === maxRetries) {
console.error(`下载文件最终失败: ${filePath}`, error.message);
logger.error(`下载文件最终失败: ${filePath}`, error.message);
throw error;
}
// 等待后重试
const retryDelay = ErrorHandler.getRetryDelay(error, attempt);
console.log(`等待 ${retryDelay}ms 后重试下载: ${filePath}`);
logger.info(`等待 ${retryDelay}ms 后重试下载: ${filePath}`);
await new Promise(resolve => setTimeout(resolve, retryDelay));
}
}
@@ -323,7 +327,7 @@ class FileManager {
await fs.unlink(filePath);
}
} catch (error) {
console.error(`文件删除失败: ${filePath}`, error.message);
logger.error(`文件删除失败: ${filePath}`, error.message);
// 不抛出错误,避免影响其他操作
}
}
+10 -5
View File
@@ -1,5 +1,10 @@
const fs = require('fs-extra');
const path = require('path');
const { defaultLogger } = require('../utils/logger');
// 创建logger实例
const logger = defaultLogger.child('HistoryManager');
/**
* 历史记录管理器 - 负责下载历史的管理
@@ -28,9 +33,9 @@ class HistoryManager {
await this.cleanupHistory();
this.initialized = true;
console.log('历史记录管理器初始化完成');
logger.info('历史记录管理器初始化完成');
} catch (error) {
console.error('历史记录管理器初始化失败:', error);
logger.error('历史记录管理器初始化失败:', error);
this.initialized = false;
}
}
@@ -44,7 +49,7 @@ class HistoryManager {
this.history = await fs.readJson(this.historyFile);
}
} catch (error) {
console.error('加载下载历史失败:', error);
logger.error('加载下载历史失败:', error);
this.history = [];
}
}
@@ -56,7 +61,7 @@ class HistoryManager {
try {
await fs.writeJson(this.historyFile, this.history, { spaces: 2 });
} catch (error) {
console.error('保存下载历史失败:', error);
logger.error('保存下载历史失败:', error);
}
}
@@ -98,7 +103,7 @@ class HistoryManager {
return;
}
console.log(`清理历史记录: ${this.history.length} -> ${this.maxHistoryItems}`);
logger.info(`清理历史记录: ${this.history.length} -> ${this.maxHistoryItems}`);
// 保留最新的记录
this.history = this.history.slice(0, this.maxHistoryItems);
+20 -16
View File
@@ -3,6 +3,10 @@ const path = require('path');
const crypto = require('crypto');
const axios = require('axios');
const CacheConfigManager = require('../config/cache-config');
const { defaultLogger } = require('../utils/logger');
// 创建logger实例
const logger = defaultLogger.child('ImageCache');
/**
* 图片缓存服务
@@ -61,9 +65,9 @@ class ImageCacheService {
// 启动定期清理任务
this.startCleanupTask();
console.log('图片缓存服务初始化完成');
logger.info('图片缓存服务初始化完成');
} catch (error) {
console.error('图片缓存服务初始化失败:', error);
logger.error('图片缓存服务初始化失败', error);
}
}
@@ -73,9 +77,9 @@ class ImageCacheService {
async ensureCacheDir() {
try {
await fs.mkdir(this.cacheDir, { recursive: true });
console.log('图片缓存目录创建成功:', this.cacheDir);
logger.info('图片缓存目录创建成功', { cacheDir: this.cacheDir });
} catch (error) {
console.error('创建图片缓存目录失败:', error);
logger.error('创建图片缓存目录失败', error);
}
}
@@ -153,7 +157,7 @@ class ImageCacheService {
return data;
} catch (error) {
console.error('读取缓存失败:', error);
logger.error('读取缓存失败:', error);
return null;
}
}
@@ -172,7 +176,7 @@ class ImageCacheService {
// 检查缓存大小,如果超过限制则清理
await this.checkCacheSize();
} catch (error) {
console.error('保存缓存失败:', error);
logger.error('保存缓存失败:', error);
}
}
@@ -202,7 +206,7 @@ class ImageCacheService {
// 异步保存到缓存(不等待完成)
if (this.config.enabled) {
this.saveToCache(url, data).catch(error => {
console.error('异步保存缓存失败:', error);
logger.error('异步保存缓存失败:', error);
});
}
@@ -270,7 +274,7 @@ class ImageCacheService {
// 如果超过最大大小,删除最旧的文件
if (totalSize > this.config.maxSize) {
console.log(`缓存大小 ${totalSize} 超过限制 ${this.config.maxSize},开始清理...`);
logger.info(`缓存大小 ${totalSize} 超过限制 ${this.config.maxSize},开始清理...`);
// 按修改时间排序,删除最旧的文件
fileStats.sort((a, b) => a.mtime.getTime() - b.mtime.getTime());
@@ -284,10 +288,10 @@ class ImageCacheService {
}
}
console.log(`缓存清理完成,当前大小: ${totalSize}`);
logger.info(`缓存清理完成,当前大小: ${totalSize}`);
}
} catch (error) {
console.error('检查缓存大小失败:', error);
logger.error('检查缓存大小失败:', error);
}
}
@@ -312,10 +316,10 @@ class ImageCacheService {
}
if (cleanedCount > 0) {
console.log(`清理了 ${cleanedCount} 个过期缓存文件`);
logger.info(`清理了 ${cleanedCount} 个过期缓存文件`);
}
} catch (error) {
console.error('清理过期缓存失败:', error);
logger.error('清理过期缓存失败:', error);
}
}
@@ -325,7 +329,7 @@ class ImageCacheService {
startCleanupTask() {
setInterval(() => {
this.cleanupExpiredCache().catch(error => {
console.error('定期清理任务失败:', error);
logger.error('定期清理任务失败:', error);
});
}, this.config.cleanupInterval);
}
@@ -343,9 +347,9 @@ class ImageCacheService {
await fs.unlink(filePath);
}
console.log('所有缓存已清理');
logger.info('所有缓存已清理');
} catch (error) {
console.error('清理所有缓存失败:', error);
logger.error('清理所有缓存失败:', error);
throw error;
}
}
@@ -376,7 +380,7 @@ class ImageCacheService {
config: this.config
};
} catch (error) {
console.error('获取缓存统计失败:', error);
logger.error('获取缓存统计失败:', error);
return {
fileCount: 0,
totalSize: 0,
+7 -1
View File
@@ -1,3 +1,9 @@
const { defaultLogger } = require('../utils/logger');
// 创建logger实例
const logger = defaultLogger.child('ProgressManager');
/**
* 进度管理器 - 负责处理下载进度的监听和通知
*/
@@ -89,7 +95,7 @@ class ProgressManager {
try {
listener(task);
} catch (error) {
console.error('进度监听器执行失败:', error);
logger.error('进度监听器执行失败:', error);
}
});
}
+29 -23
View File
@@ -4,6 +4,12 @@ const { promisify } = require('util')
const { exec } = require('child_process')
const ConfigManager = require('../config/config-manager')
const execAsync = promisify(exec)
const { defaultLogger } = require('../utils/logger');
// 创建logger实例
const logger = defaultLogger.child('RepositoryService');
class RepositoryService {
constructor() {
@@ -64,7 +70,7 @@ class RepositoryService {
try {
this.config = await this.configManager.readConfig()
} catch (error) {
console.error('加载配置失败:', error)
logger.error('加载配置失败:', error)
// 如果加载失败,使用默认配置对象
this.config = {
downloadDir: "./downloads",
@@ -266,10 +272,10 @@ class RepositoryService {
usagePercent: Math.round((used / total) * 100)
}
} catch (statfsError) {
console.log('fs.statfs 调用失败:', statfsError.message)
logger.info('fs.statfs 调用失败:', statfsError.message)
}
} else {
console.log('fs.statfs 在打包环境中不可用,尝试使用系统命令')
logger.info('fs.statfs 在打包环境中不可用,尝试使用系统命令')
}
// 如果 fs.statfs 不可用,尝试使用系统命令
@@ -305,7 +311,7 @@ class RepositoryService {
}
}
} catch (error) {
console.log('PowerShell 方法失败:', error.message)
logger.info('PowerShell 方法失败:', error.message)
throw error
}
},
@@ -340,7 +346,7 @@ class RepositoryService {
}
}
} catch (error) {
console.log('wmic 方法失败:', error.message)
logger.info('wmic 方法失败:', error.message)
throw error
}
}
@@ -357,7 +363,7 @@ class RepositoryService {
return result
}
} catch (error) {
console.log(`磁盘使用情况获取方法失败:`, error.message)
logger.info(`磁盘使用情况获取方法失败:`, error.message)
continue
}
}
@@ -383,7 +389,7 @@ class RepositoryService {
}
}
} catch (dfError) {
console.log('df 命令失败:', dfError.message)
logger.info('df 命令失败:', dfError.message)
}
}
@@ -391,7 +397,7 @@ class RepositoryService {
return await this.getCachedDiskUsage(currentBaseDir, forceRefresh)
} catch (error) {
console.error('获取磁盘使用情况失败:', error)
logger.error('获取磁盘使用情况失败:', error)
return {
total: 0,
used: 0,
@@ -486,12 +492,12 @@ class RepositoryService {
const expectedImageCount = artworkInfo.page_count || 1
if (files.length < expectedImageCount) {
// 图片文件数量不足,认为下载不完整
console.log(`作品 ${artworkId} 图片数量不匹配: 期望 ${expectedImageCount} 个,实际 ${files.length}`)
logger.info(`作品 ${artworkId} 图片数量不匹配: 期望 ${expectedImageCount} 个,实际 ${files.length}`)
return false
}
// 有信息文件、有图片文件且数量匹配,认为已下载
// console.log(`作品 ${artworkId} 已完整下载: ${files.length}/${expectedImageCount} 个图片文件`)
// logger.info(`作品 ${artworkId} 已完整下载: ${files.length}/${expectedImageCount} 个图片文件`)
return true
}
}
@@ -499,7 +505,7 @@ class RepositoryService {
return false
} catch (error) {
console.error('检查作品下载状态失败:', error)
logger.error('检查作品下载状态失败:', error)
return false
}
}
@@ -772,12 +778,12 @@ class RepositoryService {
if (cacheAge < maxCacheAge) {
this.diskUsageCache.data = cache.data
this.diskUsageCache.timestamp = cache.timestamp
console.log('已加载持久化缓存,缓存年龄:', Math.round(cacheAge / 1000 / 60), '分钟')
logger.info('已加载持久化缓存,缓存年龄:', Math.round(cacheAge / 1000 / 60), '分钟')
} else {
console.log('持久化缓存已过期,将重新计算')
logger.info('持久化缓存已过期,将重新计算')
}
} catch (error) {
console.log('加载持久化缓存失败,将使用内存缓存:', error.message)
logger.info('加载持久化缓存失败,将使用内存缓存:', error.message)
}
}
@@ -795,9 +801,9 @@ class RepositoryService {
}
await fs.writeFile(this.cacheFilePath, JSON.stringify(cacheData, null, 2), 'utf8')
console.log('持久化缓存已保存')
logger.info('持久化缓存已保存')
} catch (error) {
console.error('保存持久化缓存失败:', error.message)
logger.error('保存持久化缓存失败:', error.message)
}
}
@@ -812,9 +818,9 @@ class RepositoryService {
if (this.cacheFilePath) {
try {
await fs.unlink(this.cacheFilePath)
console.log('持久化缓存文件已删除')
logger.info('持久化缓存文件已删除')
} catch (error) {
console.log('删除持久化缓存文件失败:', error.message)
logger.info('删除持久化缓存文件失败:', error.message)
}
}
@@ -831,7 +837,7 @@ class RepositoryService {
// 检查内存缓存是否有效(除非强制刷新)
if (!forceRefresh && this.diskUsageCache.data &&
(now - this.diskUsageCache.timestamp) < this.diskUsageCache.cacheDuration) {
console.log('使用内存缓存的磁盘使用情况')
logger.info('使用内存缓存的磁盘使用情况')
return this.diskUsageCache.data
}
@@ -862,7 +868,7 @@ class RepositoryService {
return result
} catch (error) {
console.log('快速估算失败,返回默认值:', error.message)
logger.info('快速估算失败,返回默认值:', error.message)
return {
total: 0,
used: 0,
@@ -916,7 +922,7 @@ class RepositoryService {
return totalSize
} catch (error) {
console.error('快速目录大小估算失败:', error)
logger.error('快速目录大小估算失败:', error)
return 0
}
}
@@ -938,14 +944,14 @@ class RepositoryService {
totalSize += stats.size
} catch (error) {
// 忽略无法访问的文件
console.log(`无法访问文件: ${fullPath}`)
logger.info(`无法访问文件: ${fullPath}`)
}
}
}
return totalSize
} catch (error) {
console.error('计算目录大小失败:', error)
logger.error('计算目录大小失败:', error)
return 0
}
}
+9 -5
View File
@@ -1,6 +1,10 @@
const fs = require('fs-extra');
const path = require('path');
const { v4: uuidv4 } = require('uuid');
const { defaultLogger } = require('../utils/logger');
// 创建logger实例
const logger = defaultLogger.child('TaskManager');
/**
* 任务管理器 - 负责下载任务的生命周期管理
@@ -29,9 +33,9 @@ class TaskManager {
await this.cleanupCompletedTasks();
this.initialized = true;
console.log('任务管理器初始化完成');
logger.info('任务管理器初始化完成');
} catch (error) {
console.error('任务管理器初始化失败:', error);
logger.error('任务管理器初始化失败', error);
this.initialized = false;
}
}
@@ -53,7 +57,7 @@ class TaskManager {
}
}
} catch (error) {
console.error('加载任务状态失败:', error);
logger.error('加载任务状态失败', error);
this.tasks = new Map();
}
}
@@ -66,7 +70,7 @@ class TaskManager {
const tasksData = Object.fromEntries(this.tasks);
await fs.writeJson(this.tasksFile, tasksData, { spaces: 2 });
} catch (error) {
console.error('保存任务状态失败:', error);
logger.error('保存任务状态失败', error);
}
}
@@ -199,7 +203,7 @@ class TaskManager {
if (cleanedCount > 0) {
await this.saveTasks();
console.log(`清理已完成任务: ${cleanedCount}`);
logger.info(`清理已完成任务: ${cleanedCount}`);
}
return cleanedCount;