From d1082a867748f58d7208c2ae8628fb6172b6682b Mon Sep 17 00:00:00 2001 From: kjqwer <2990346238@qq.com> Date: Thu, 9 Oct 2025 12:13:52 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E9=87=8D=E5=90=AF=E6=B8=85?= =?UTF-8?q?=E7=90=86=E7=B3=BB=E7=BB=9F=E4=BB=A3=E7=90=86=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/auth.js | 4 +- backend/core.js | 41 ++++++++++++++- backend/server.js | 124 ++++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 160 insertions(+), 9 deletions(-) diff --git a/backend/auth.js b/backend/auth.js index c38bfb8..c398a1b 100644 --- a/backend/auth.js +++ b/backend/auth.js @@ -40,7 +40,7 @@ class PixivAuth { */ createAxiosInstance() { const config = { - timeout: 30000, // 30秒超时 + timeout: 60000, headers: this.getDefaultHeaders() }; @@ -474,4 +474,4 @@ class PixivAuth { } } -module.exports = PixivAuth; \ No newline at end of file +module.exports = PixivAuth; \ No newline at end of file diff --git a/backend/core.js b/backend/core.js index 6fa7bd9..1a0a79b 100644 --- a/backend/core.js +++ b/backend/core.js @@ -84,8 +84,13 @@ class PixivBackend { * 启动token同步定时任务 */ startTokenSyncTask() { + // 清理可能存在的旧定时器 + if (this.tokenSyncTimer) { + clearInterval(this.tokenSyncTimer); + } + // 每5分钟同步一次token状态到配置文件 - setInterval(() => { + this.tokenSyncTimer = setInterval(() => { if (this.auth && this.isLoggedIn) { this.syncTokensToConfig(); } @@ -336,6 +341,38 @@ class PixivBackend { getDownloadService() { return this.downloadService; } + + /** + * 清理资源 + */ + async cleanup() { + logger.info('正在清理 Pixiv 后端资源...'); + + try { + // 停止token同步定时任务 + if (this.tokenSyncTimer) { + clearInterval(this.tokenSyncTimer); + this.tokenSyncTimer = null; + logger.info('Token同步定时任务已停止'); + } + + // 清理认证实例的定时器 + if (this.auth) { + this.auth.stopProactiveRefresh(); + logger.info('认证定时器已清理'); + } + + // 清理下载服务 + if (this.downloadService) { + await this.downloadService.cleanup?.(); + logger.info('下载服务已清理'); + } + + logger.info('Pixiv 后端资源清理完成'); + } catch (error) { + logger.error('清理 Pixiv 后端资源时出错:', error.message); + } + } } -module.exports = PixivBackend; \ No newline at end of file +module.exports = PixivBackend; \ No newline at end of file diff --git a/backend/server.js b/backend/server.js index 559698f..24975b7 100644 --- a/backend/server.js +++ b/backend/server.js @@ -1,6 +1,7 @@ const express = require('express'); const cors = require('cors'); const path = require('path'); +const fs = require('fs'); // 导入logger const { defaultLogger } = require('./utils/logger'); @@ -29,6 +30,118 @@ class PixivServer { this.backend = null; } + /** + * 加载配置文件 + */ + loadConfig() { + // 检测是否在pkg打包环境中运行 + const isPackaged = process.pkg !== undefined; + + // 在打包环境中,配置文件在当前工作目录;在开发环境中,配置文件在上级目录 + const configPath = isPackaged + ? path.join(process.cwd(), 'config.json') // 打包环境:当前工作目录 + : path.join(__dirname, '..', 'config.json'); // 开发环境:上级目录 + let config = { + server: { + port: 3000, + autoOpenBrowser: true + }, + proxy: { + port: null, + enabled: false + }, + logging: { + level: "INFO" + }, + system: { + threadPoolSize: 16 + } + }; + + try { + logger.info(`检测环境: ${isPackaged ? '打包环境' : '开发环境'}`); + logger.info(`配置文件路径: ${configPath}`); + + if (fs.existsSync(configPath)) { + const configData = fs.readFileSync(configPath, 'utf8'); + const userConfig = JSON.parse(configData); + + // 合并配置,用户配置覆盖默认配置 + config = { + ...config, + server: { ...config.server, ...userConfig.server }, + proxy: { ...config.proxy, ...userConfig.proxy }, + logging: { ...config.logging, ...userConfig.logging }, + system: { ...config.system, ...userConfig.system } + }; + logger.info('已加载配置文件'); + } else { + // 如果配置文件不存在,创建默认配置文件 + fs.writeFileSync(configPath, JSON.stringify(config, null, 2), 'utf8'); + logger.info('已创建默认配置文件:', configPath); + } + } catch (error) { + logger.error('读取配置文件失败,使用默认配置:', error.message); + } + + return config; + } + + /** + * 应用配置到环境变量 + */ + applyConfig(config) { + // 设置线程池大小 + if (!process.env.UV_THREADPOOL_SIZE) { + process.env.UV_THREADPOOL_SIZE = config.system.threadPoolSize.toString(); + } + + // 设置环境变量 + process.env.NODE_ENV = process.env.NODE_ENV || 'development'; + + // 设置日志级别环境变量 + if (config.logging.level) { + process.env.LOG_LEVEL = config.logging.level.toLowerCase(); + } + + // 如果配置了代理,设置环境变量 + if (config.proxy.enabled === true || (config.proxy.enabled === "auto" && config.proxy.port)) { + // 显式配置代理端口 + if (config.proxy.port) { + process.env.PROXY_PORT = config.proxy.port.toString(); + logger.info(`代理端口已设置为: ${config.proxy.port}`); + } + } else if (config.proxy.enabled === "auto") { + // 自动检测系统代理 + const systemProxy = process.env.HTTP_PROXY || process.env.HTTPS_PROXY || process.env.http_proxy || process.env.https_proxy; + if (systemProxy) { + logger.info(`检测到系统代理: ${systemProxy}`); + // 从系统代理URL中提取端口 + const match = systemProxy.match(/http:\/\/127\.0\.0\.1:(\d+)/); + if (match) { + process.env.PROXY_PORT = match[1]; + logger.info(`自动设置代理端口为: ${match[1]}`); + } + } else { + logger.info('未检测到系统代理,将尝试使用系统代理环境变量'); + } + } + + // 设置服务器端口 + if (config.server.port) { + process.env.PORT = config.server.port.toString(); + logger.info(`服务器端口已设置为: ${config.server.port}`); + } + + // 设置自动打开浏览器选项 + if (config.server.autoOpenBrowser !== undefined) { + process.env.AUTO_OPEN_BROWSER = config.server.autoOpenBrowser.toString(); + logger.info(`自动打开浏览器: ${config.server.autoOpenBrowser ? '启用' : '禁用'}`); + } + + logger.info(`日志级别: ${config.logging.level}`); + } + /** * 初始化服务器 */ @@ -168,9 +281,6 @@ class PixivServer { logger.info('正在重启服务器...'); try { - // 清理代理环境变量 - proxyConfig.clearEnvironmentVariables(); - // 关闭当前服务器 if (this.server) { await new Promise((resolve) => { @@ -186,6 +296,12 @@ class PixivServer { await this.backend.cleanup?.(); } + // 重新加载配置文件 + const config = this.loadConfig(); + + // 重新应用配置到环境变量 + this.applyConfig(config); + // 重新初始化并启动 await this.init(); await this.start(); @@ -204,8 +320,6 @@ class PixivServer { */ async shutdown() { logger.info('正在关闭服务器...'); - // 清理代理环境变量 - proxyConfig.clearEnvironmentVariables(); logger.info('服务器已关闭'); process.exit(0); }