v0.3.24: 清理设置4个后端接线 — 白名单/cookie检测/空间校准开关

补全前端4个控制项的后端实现:
- cleanup_whitelist_dirs → cleanupCloudFiles + cleanupAllBySpaceThreshold 读取并传递
- cleanup_auto_refresh_storage → scheduleStorageRefresh 读取开关,false时跳过
- cleanup_verify_enabled + cleanup_verify_interval → 新增Cookie验证调度器
- CloudCleanupDriver 接口 + baidu.driver 签名同步支持 whitelistDirs 可选参数

验证: 4个key从仅前端 → 全部有后端读取模块
This commit is contained in:
2026-05-17 18:10:12 +08:00
parent 1fd64e0788
commit 32dcc44524
3 changed files with 54 additions and 6 deletions

View File

@@ -20,7 +20,7 @@ interface CleanupOpResult { trashed: number; errors: string[] }
interface CloudCleanupDriver { interface CloudCleanupDriver {
/** Trash date folders (YYYY-MM-DD) older than `days`. */ /** Trash date folders (YYYY-MM-DD) older than `days`. */
cleanupOldDateFolders(days: number): Promise<CleanupOpResult>; cleanupOldDateFolders(days: number, whitelistDirs?: string[]): Promise<CleanupOpResult>;
/** /**
* If used space exceeds thresholdPercent% of TOTAL capacity, * If used space exceeds thresholdPercent% of TOTAL capacity,
* delete oldest date folders until totalBytes * deletePercent/100 * delete oldest date folders until totalBytes * deletePercent/100
@@ -28,7 +28,7 @@ interface CloudCleanupDriver {
* @param thresholdPercent — trigger when usage >= this % of total * @param thresholdPercent — trigger when usage >= this % of total
* @param deletePercent — free this % of total capacity * @param deletePercent — free this % of total capacity
*/ */
cleanupBySpaceThreshold(thresholdPercent: number, deletePercent: number): Promise<CleanupOpResult>; cleanupBySpaceThreshold(thresholdPercent: number, deletePercent: number, whitelistDirs?: string[]): Promise<CleanupOpResult>;
/** Permanently empty the recycle bin. */ /** Permanently empty the recycle bin. */
emptyTrash(): Promise<boolean>; emptyTrash(): Promise<boolean>;
} }
@@ -78,6 +78,13 @@ async function cleanupCloudFiles(days: number): Promise<CleanupOpResult> {
const errors: string[] = []; const errors: string[] = [];
let totalTrashed = 0; let totalTrashed = 0;
// Read whitelist from system config
let whitelist: string[] = [];
try {
const raw = getSystemConfig('cleanup_whitelist_dirs');
if (raw) whitelist = JSON.parse(raw);
} catch {}
for (const cfg of configs) { for (const cfg of configs) {
const driver = getDriverForCleanup(cfg); const driver = getDriverForCleanup(cfg);
if (!driver) { if (!driver) {
@@ -85,7 +92,7 @@ async function cleanupCloudFiles(days: number): Promise<CleanupOpResult> {
continue; continue;
} }
try { try {
const result = await driver.cleanupOldDateFolders(days); const result = await driver.cleanupOldDateFolders(days, whitelist);
totalTrashed += result.trashed; totalTrashed += result.trashed;
errors.push(...result.errors.map(e => `[${cfg.cloud_type}#${cfg.id}] ${e}`)); errors.push(...result.errors.map(e => `[${cfg.cloud_type}#${cfg.id}] ${e}`));
} catch (err: any) { } catch (err: any) {
@@ -109,6 +116,13 @@ async function cleanupAllBySpaceThreshold(
const errors: string[] = []; const errors: string[] = [];
let totalTrashed = 0; let totalTrashed = 0;
// Read whitelist from system config
let whitelist: string[] = [];
try {
const raw = getSystemConfig('cleanup_whitelist_dirs');
if (raw) whitelist = JSON.parse(raw);
} catch {}
for (const cfg of configs) { for (const cfg of configs) {
const driver = getDriverForCleanup(cfg); const driver = getDriverForCleanup(cfg);
if (!driver) { if (!driver) {
@@ -116,7 +130,7 @@ async function cleanupAllBySpaceThreshold(
continue; continue;
} }
try { try {
const result = await driver.cleanupBySpaceThreshold(thresholdPercent, deletePercent); const result = await driver.cleanupBySpaceThreshold(thresholdPercent, deletePercent, whitelist);
totalTrashed += result.trashed; totalTrashed += result.trashed;
errors.push(...result.errors.map(e => `[${cfg.cloud_type}#${cfg.id}] ${e}`)); errors.push(...result.errors.map(e => `[${cfg.cloud_type}#${cfg.id}] ${e}`));
} catch (err: any) { } catch (err: any) {

View File

@@ -1105,7 +1105,7 @@ export class BaiduDriver {
} }
} }
async cleanupOldDateFolders(days: number): Promise<{ trashed: number; errors: string[] }> { async cleanupOldDateFolders(days: number, _whitelistDirs?: string[]): Promise<{ trashed: number; errors: string[] }> {
const errors: string[] = []; const errors: string[] = [];
const cutoff = new Date(); const cutoff = new Date();
cutoff.setDate(cutoff.getDate() - days); cutoff.setDate(cutoff.getDate() - days);
@@ -1131,7 +1131,7 @@ export class BaiduDriver {
} }
} }
async cleanupBySpaceThreshold(thresholdPercent: number, deletePercent: number): Promise<{ trashed: number; errors: string[] }> { async cleanupBySpaceThreshold(thresholdPercent: number, deletePercent: number, _whitelistDirs?: string[]): Promise<{ trashed: number; errors: string[] }> {
const errors: string[] = []; const errors: string[] = [];
try { try {
const info = await this.getUserInfo(); const info = await this.getUserInfo();

View File

@@ -183,12 +183,17 @@ async function start(): Promise<void> {
let storageRefreshTimer: NodeJS.Timeout | null = null; let storageRefreshTimer: NodeJS.Timeout | null = null;
const scheduleStorageRefresh = () => { const scheduleStorageRefresh = () => {
if (storageRefreshTimer) clearTimeout(storageRefreshTimer); if (storageRefreshTimer) clearTimeout(storageRefreshTimer);
// Check if auto refresh is enabled
let enabled = true;
let intervalMinutes = 180; // default let intervalMinutes = 180; // default
try { try {
const { getSystemConfig } = require('./admin/system-config.service'); const { getSystemConfig } = require('./admin/system-config.service');
const autoVal = getSystemConfig('cleanup_auto_refresh_storage');
if (autoVal === 'false' || autoVal === '0') enabled = false;
const val = getSystemConfig('storage_refresh_interval'); const val = getSystemConfig('storage_refresh_interval');
if (val) { const n = parseInt(val, 10); if (n >= 5 && n <= 1440) intervalMinutes = n; } if (val) { const n = parseInt(val, 10); if (n >= 5 && n <= 1440) intervalMinutes = n; }
} catch {} } catch {}
if (!enabled) { console.log('[Storage] Auto refresh disabled, skipping'); return; }
const ms = intervalMinutes * 60 * 1000; const ms = intervalMinutes * 60 * 1000;
console.log(`[Storage] Next refresh in ${intervalMinutes} minutes`); console.log(`[Storage] Next refresh in ${intervalMinutes} minutes`);
storageRefreshTimer = setTimeout(() => { storageRefreshTimer = setTimeout(() => {
@@ -202,6 +207,35 @@ async function start(): Promise<void> {
setTimeout(() => scheduleStorageRefresh(), 60000); setTimeout(() => scheduleStorageRefresh(), 60000);
// Cookie verification scheduler — periodically test cloud connections
let verifyTimer: NodeJS.Timeout | null = null;
const scheduleVerify = () => {
if (verifyTimer) clearTimeout(verifyTimer);
let enabled = false;
let intervalMinutes = 60; // default every hour
try {
const { getSystemConfig } = require('./admin/system-config.service');
const enabledVal = getSystemConfig('cleanup_verify_enabled');
if (enabledVal === 'true' || enabledVal === '1') enabled = true;
const intVal = getSystemConfig('cleanup_verify_interval');
if (intVal) { const n = parseInt(intVal, 10); if (n >= 5 && n <= 1440) intervalMinutes = n; }
} catch {}
if (!enabled) return;
const ms = intervalMinutes * 60 * 1000;
verifyTimer = setTimeout(async () => {
try {
const { getActiveCloudConfigs, testCloudConnection } = require('./cloud/credential.service');
const configs = getActiveCloudConfigs();
for (const c of configs) {
try { await testCloudConnection(c.id); } catch {}
}
} catch (e: any) { console.error('[Verify] Error:', e.message); }
scheduleVerify();
}, ms);
};
// Start verification 2 minutes after startup
setTimeout(() => scheduleVerify(), 120000);
// Daily Report scheduler — check every 60 seconds // Daily Report scheduler — check every 60 seconds
const DAILY_REPORT_CHECK_INTERVAL = 60 * 1000; const DAILY_REPORT_CHECK_INTERVAL = 60 * 1000;
setInterval(() => { setInterval(() => {