From 4b9bcd7a96bf742084e5bb571053c9ab7c350d70 Mon Sep 17 00:00:00 2001 From: admin <362324317@qq.com> Date: Fri, 15 May 2026 18:23:40 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20cookie=E5=8A=A0=E5=AF=86=E5=90=8Ecloud.s?= =?UTF-8?q?ervice.ts=E6=9C=AA=E8=A7=A3=E5=AF=86=E5=AF=BC=E8=87=B4API=20401?= =?UTF-8?q?;=20=E6=9B=B4=E6=96=B0=E7=89=88=E6=9C=AC=E5=8F=B7=E8=87=B32.1.1?= =?UTF-8?q?/1.1.9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 2 +- packages/backend/src/cloud/cloud.service.ts | 26 +++++++++++++++---- .../backend/src/cloud/credential.service.ts | 6 ++--- .../src/cloud/drivers/quark-cleanup.ts | 8 +----- packages/backend/src/database/database.ts | 2 ++ packages/frontend/package.json | 2 +- .../frontend/src/pages/admin/CloudConfig.vue | 10 +++---- .../frontend/src/pages/admin/SaveRecords.vue | 10 +++++-- 8 files changed, 42 insertions(+), 24 deletions(-) diff --git a/package.json b/package.json index f73f8ae..dd316ce 100755 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cloudsearch-backend", - "version": "2.1.0", + "version": "2.1.1", "private": true, "scripts": { "dev": "tsx watch src/main.ts", diff --git a/packages/backend/src/cloud/cloud.service.ts b/packages/backend/src/cloud/cloud.service.ts index 9020f13..56c87eb 100644 --- a/packages/backend/src/cloud/cloud.service.ts +++ b/packages/backend/src/cloud/cloud.service.ts @@ -1,6 +1,7 @@ import { getDb } from '../database/database'; import { localTimestamp, formatLocalDateTime } from '../utils/time'; import { getSystemConfig } from '../admin/system-config.service'; +import { decrypt } from '../utils/crypto'; import { QuarkDriver } from './drivers/quark.driver'; import { BaiduDriver } from './drivers/baidu.driver'; import { CloudConfig, getAndValidateCredential, getActiveCloudConfigs } from './credential.service'; @@ -159,12 +160,12 @@ async function doSaveFromShare(shareUrl: string, cloudType: string, sourceTitle? switch (cloudType) { case 'quark': { - const driver = new QuarkDriver({ cookie: config.cookie!, nickname: config.nickname }); + const driver = new QuarkDriver({ cookie: decrypt(config.cookie!), nickname: config.nickname }); driverResult = await driver.saveFromShare(shareUrl, sourceTitle); break; } case 'baidu': { - const driver = new BaiduDriver({ cookie: config.cookie!, nickname: config.nickname }); + const driver = new BaiduDriver({ cookie: decrypt(config.cookie!), nickname: config.nickname }); driverResult = await driver.saveFromShare(shareUrl, sourceTitle); break; } @@ -174,6 +175,21 @@ async function doSaveFromShare(shareUrl: string, cloudType: string, sourceTitle? return { success: false, message: `暂不支持 ${cloudType} 的保存功能` }; } + // ── If save failed, get actual error reason from PanSou validation ── + let actualError: string | null = null; + if (!driverResult.success) { + try { + const { LinkValidator } = await import('../validation/link-validator.service'); + const validator = new LinkValidator(); + const validation = await validator.validate(shareUrl, cloudType); + if (validation.message) { + actualError = validation.message; + } + } catch { + // PanSou unreachable + } + } + const durationMs = Date.now() - startTime; if (driverResult.success) { @@ -196,7 +212,7 @@ async function doSaveFromShare(shareUrl: string, cloudType: string, sourceTitle? driverResult.shareUrl || null, driverResult.sharePwd || null, driverResult.fileSize == null ? null : String(driverResult.fileSize), driverResult.fileCount || 0, driverResult.folderCount || 0, durationMs, driverResult.success ? 'success' : 'failed', - driverResult.success ? null : driverResult.message, + driverResult.success ? null : (actualError ? `${driverResult.message} | ${actualError}` : driverResult.message), driverResult.folderName || null, driverResult.originalFolderName || null, ipAddress || null, ipLocation, localTimestamp(), config.id ); @@ -312,7 +328,7 @@ export async function refreshAllStorageInfo(): Promise { for (const cfg of configs) { try { const { QuarkDriver } = require('./drivers/quark.driver'); - const driver = new QuarkDriver({ cookie: cfg.cookie, nickname: cfg.nickname }); + const driver = new QuarkDriver({ cookie: decrypt(cfg.cookie!), nickname: cfg.nickname }); const storage = await driver.getStorageInfo(); if (storage.totalBytes > 0 || storage.usedBytes > 0) { const db = getDb(); @@ -324,4 +340,4 @@ export async function refreshAllStorageInfo(): Promise { console.error(`[Storage] Failed to refresh quark#${cfg.id}:`, err.message); } } -} +} \ No newline at end of file diff --git a/packages/backend/src/cloud/credential.service.ts b/packages/backend/src/cloud/credential.service.ts index c78e63b..7588a49 100644 --- a/packages/backend/src/cloud/credential.service.ts +++ b/packages/backend/src/cloud/credential.service.ts @@ -189,7 +189,7 @@ export function saveCloudConfig(data: { consecutive_failures = 0, updated_at = ? WHERE id = ?` - ).run(data.cloud_type, encryptedCookie || null, data.nickname || null, data.is_active ?? 1, data.promotion_account ?? '', data.is_transfer_enabled ?? 1, data.storage_used || null, data.storage_total || null, cloudTypeUid || null, localTimestamp(), data.id); + ).run(data.cloud_type, encryptedCookie || null, data.nickname || null, data.is_active == null ? 1 : Number(data.is_active), data.promotion_account ?? '', data.is_transfer_enabled == null ? 1 : Number(data.is_transfer_enabled), data.storage_used || null, data.storage_total || null, cloudTypeUid || null, localTimestamp(), data.id); } else { // Try to find existing config by cloud_type + cloud_type_uid let existing: any = null; @@ -220,7 +220,7 @@ export function saveCloudConfig(data: { consecutive_failures = 0, updated_at = ? WHERE id = ?` - ).run(encryptedCookie || null, data.nickname || null, data.is_active ?? 1, data.promotion_account ?? '', data.is_transfer_enabled ?? 1, data.storage_used || null, data.storage_total || null, cloudTypeUid || null, localTimestamp(), existing.id); + ).run(encryptedCookie || null, data.nickname || null, data.is_active == null ? 1 : Number(data.is_active), data.promotion_account ?? '', data.is_transfer_enabled == null ? 1 : Number(data.is_transfer_enabled), data.storage_used || null, data.storage_total || null, cloudTypeUid || null, localTimestamp(), existing.id); // Re-read savedId for return const savedId = existing.id; @@ -236,7 +236,7 @@ export function saveCloudConfig(data: { // No existing config found — insert new db.prepare( 'INSERT INTO cloud_configs (cloud_type, cookie, nickname, is_active, promotion_account, is_transfer_enabled, storage_used, storage_total, cloud_type_uid, consecutive_failures) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, 0)' - ).run(data.cloud_type, encryptedCookie || null, data.nickname || null, data.is_active ?? 1, data.promotion_account ?? '', data.is_transfer_enabled ?? 1, data.storage_used || null, data.storage_total || null, cloudTypeUid || null); + ).run(data.cloud_type, encryptedCookie || null, data.nickname || null, data.is_active == null ? 1 : Number(data.is_active), data.promotion_account ?? '', data.is_transfer_enabled == null ? 1 : Number(data.is_transfer_enabled), data.storage_used || null, data.storage_total || null, cloudTypeUid || null); } const savedId = data.id || (db.prepare('SELECT last_insert_rowid() as id').get() as any).id; diff --git a/packages/backend/src/cloud/drivers/quark-cleanup.ts b/packages/backend/src/cloud/drivers/quark-cleanup.ts index 5b149cd..ad46849 100644 --- a/packages/backend/src/cloud/drivers/quark-cleanup.ts +++ b/packages/backend/src/cloud/drivers/quark-cleanup.ts @@ -89,14 +89,8 @@ export async function getStorageInfoQuick(cookie: string, fallbackTotal?: string */ export async function getStorageInfo(cookie: string): Promise<{ used: string; total: string; usedBytes: number; totalBytes: number }> { try { - const mparam = getMparam(cookie); let totalBytes = 0; - const params = new URLSearchParams({ - ...getCommonParams(), - kps: mparam.kps || '', - sign: mparam.sign || '', - vcode: mparam.vcode || '', - }); + const params = new URLSearchParams(getCommonParams()); const response = await fetch(`${BASE_URL}/1/clouddrive/capacity/detail?${params.toString()}`, { headers: getHeaders(cookie), signal: AbortSignal.timeout(10000), diff --git a/packages/backend/src/database/database.ts b/packages/backend/src/database/database.ts index 29cace1..be0e6ee 100755 --- a/packages/backend/src/database/database.ts +++ b/packages/backend/src/database/database.ts @@ -321,6 +321,8 @@ function seedSystemConfigs(db: Database.Database): void { { key: 'quark_ad_keywords', value: '广告,推广,福利,加V,加微,联系,客服,赚钱,兼职', description: '夸克转存广告关键词(一行一个,匹配文件名/文件夹名即删除)' }, { key: 'quark_warning_folder_names', value: '⚠️ 网盘内除您所需资源外', description: '夸克转存后自动创建的警示文件夹名(一行一个,自动加上 ⚠️ 前缀)' }, { key: 'quark_sus_extensions', value: 'bat\nexe\nvbs\nscr\ncmd\ncom\npif\njs\njar\nmsi\nreg\ninf\nps1', description: '夸克转存可疑文件后缀(一行一个,不写点号,匹配即删除)' }, + { key: 'link_valid_keywords', value: '链接有效', description: 'PanSou 链接有效关键词(一行一条)' }, + { key: 'link_invalid_keywords', value: '链接失效', description: 'PanSou 链接失效关键词和本地验证失效关键词(一行一条)' }, ]; const insert = db.prepare( 'INSERT OR IGNORE INTO system_configs (key, value, description) VALUES (?, ?, ?)' diff --git a/packages/frontend/package.json b/packages/frontend/package.json index 7bd993f..bc2168b 100755 --- a/packages/frontend/package.json +++ b/packages/frontend/package.json @@ -1,6 +1,6 @@ { "name": "cloudsearch-frontend", - "version": "1.1.8", + "version": "1.1.9", "private": true, "type": "module", "scripts": { diff --git a/packages/frontend/src/pages/admin/CloudConfig.vue b/packages/frontend/src/pages/admin/CloudConfig.vue index fa1238e..1f14a1a 100755 --- a/packages/frontend/src/pages/admin/CloudConfig.vue +++ b/packages/frontend/src/pages/admin/CloudConfig.vue @@ -351,7 +351,7 @@ async function handleToggleTransfer(row: CloudConfig, enabled: boolean) { nickname: row.nickname || '', promotion_account: row.promotion_account || '', is_transfer_enabled: newVal, - is_active: row.is_active !== 0, + is_active: row.is_active, cookie: undefined, // don't send cookie on toggle-only }) row.is_transfer_enabled = newVal @@ -503,9 +503,9 @@ async function handleSave() { cloud_type: form.cloud_type as CloudType, nickname: form.nickname, promotion_account: form.promotion_account, - is_transfer_enabled: form.is_transfer_enabled, + is_transfer_enabled: form.is_transfer_enabled ? 1 : 0, cookie: form.cookie || undefined, - is_active: true, + is_active: 1, storage_used: form._storageUsed || undefined, storage_total: form._storageTotal || undefined, }) @@ -515,9 +515,9 @@ async function handleSave() { cloud_type: form.cloud_type as CloudType, nickname: form.nickname, promotion_account: form.promotion_account, - is_transfer_enabled: form.is_transfer_enabled, + is_transfer_enabled: form.is_transfer_enabled ? 1 : 0, cookie: form.cookie, - is_active: true, + is_active: 1, storage_used: form._storageUsed || undefined, storage_total: form._storageTotal || undefined, }) diff --git a/packages/frontend/src/pages/admin/SaveRecords.vue b/packages/frontend/src/pages/admin/SaveRecords.vue index efaf27e..7764fc7 100755 --- a/packages/frontend/src/pages/admin/SaveRecords.vue +++ b/packages/frontend/src/pages/admin/SaveRecords.vue @@ -93,7 +93,7 @@
文件大小 - {{ formatFileSize(row.file_size) }} + {{ row.file_size ? (function(n){if(n==null||n==='')return'-';var v=typeof n==='string'?parseInt(n,10):n;if(!v||v<=0)return'-';var u=['B','KB','MB','GB','TB'];var i=0,s=v;while(s>=1024&&i<4){s/=1024;i++}return s.toFixed(i===0?0:2)+' '+u[i]})(row.file_size) : '-' }}
文件夹 @@ -157,7 +157,13 @@
错误信息 -
{{ row.error_message }}
+
{{ row.error_message.includes(' | ') ? row.error_message.split(' | ')[1] : row.error_message.split(' | ')[0] }}
+
+
+
+
+ 友好提示 +
{{ row.error_message.split(' | ')[0] }}