2 Commits

5 changed files with 27 additions and 9 deletions

View File

@@ -1,6 +1,6 @@
{ {
"name": "cloudsearch-backend", "name": "cloudsearch-backend",
"version": "0.2.2", "version": "0.2.6",
"private": true, "private": true,
"scripts": { "scripts": {
"dev": "tsx watch src/main.ts", "dev": "tsx watch src/main.ts",

View File

@@ -107,7 +107,7 @@ async function doSaveFromShare(shareUrl: string, cloudType: string, sourceTitle?
if (existing?.share_url) { if (existing?.share_url) {
const { LinkValidator } = await import('../validation/link-validator.service'); const { LinkValidator } = await import('../validation/link-validator.service');
const validator = new LinkValidator(); const validator = new LinkValidator();
const validation = await validator.validate(existing.share_url, 'quark'); const validation = await validator.validateWithLocalFallback(existing.share_url, 'quark');
if (validation.status === 'valid') { if (validation.status === 'valid') {
const isFirstReuse = dedupCutoff ? !db.prepare( const isFirstReuse = dedupCutoff ? !db.prepare(
`SELECT 1 FROM save_records WHERE source_url = ? AND created_at >= ? AND status = 'reused' LIMIT 1` `SELECT 1 FROM save_records WHERE source_url = ? AND created_at >= ? AND status = 'reused' LIMIT 1`
@@ -197,7 +197,14 @@ async function doSaveFromShare(shareUrl: string, cloudType: string, sourceTitle?
const nickname = config.nickname || cloudType; const nickname = config.nickname || cloudType;
notifyConfigEvent(config.id, 'save_success', `✅ 转存成功`, notifyConfigEvent(config.id, 'save_success', `✅ 转存成功`,
`**${cloudType}** · ${nickname}\n文件: ${driverResult.folderName || sourceTitle || shareUrl}\n耗时: ${((Date.now() - startTime) / 1000).toFixed(1)}s`, `**${cloudType}** · ${nickname}\n文件: ${driverResult.folderName || sourceTitle || shareUrl}\n耗时: ${((Date.now() - startTime) / 1000).toFixed(1)}s`,
'info'); 'info', {
file_name: driverResult.folderName || sourceTitle || shareUrl,
file_size: '',
cloud_type: cloudType,
nickname: nickname || '',
duration: ((Date.now() - startTime) / 1000).toFixed(1),
share_url: shareUrl,
});
db.prepare( db.prepare(
`UPDATE cloud_configs SET last_used_at = datetime('now','localtime'), total_saves = total_saves + 1, consecutive_failures = 0 WHERE id = ?` `UPDATE cloud_configs SET last_used_at = datetime('now','localtime'), total_saves = total_saves + 1, consecutive_failures = 0 WHERE id = ?`
@@ -206,7 +213,11 @@ async function doSaveFromShare(shareUrl: string, cloudType: string, sourceTitle?
// Cookie expired — don't count as failure, user needs to re-login // Cookie expired — don't count as failure, user needs to re-login
notifyConfigEvent(config.id, 'cookie_expire', `⚠️ Cookie过期`, notifyConfigEvent(config.id, 'cookie_expire', `⚠️ Cookie过期`,
`**${cloudType}** · ${config.nickname || '未知'}\n链接: ${shareUrl}\n请重新登录`, `**${cloudType}** · ${config.nickname || '未知'}\n链接: ${shareUrl}\n请重新登录`,
'error'); 'error', {
cloud_type: cloudType,
nickname: config.nickname || '',
share_url: shareUrl,
});
} else { } else {
db.prepare( db.prepare(
`UPDATE cloud_configs SET consecutive_failures = consecutive_failures + 1 WHERE id = ?` `UPDATE cloud_configs SET consecutive_failures = consecutive_failures + 1 WHERE id = ?`
@@ -215,7 +226,14 @@ async function doSaveFromShare(shareUrl: string, cloudType: string, sourceTitle?
if (failCount >= 3) { if (failCount >= 3) {
notifyConfigEvent(config.id, 'save_fail', `❌ 转存连续失败 ${failCount}`, notifyConfigEvent(config.id, 'save_fail', `❌ 转存连续失败 ${failCount}`,
`**${cloudType}** · ${config.nickname || '未知'}\n链接: ${shareUrl}\n错误: ${driverResult.message}`, `**${cloudType}** · ${config.nickname || '未知'}\n链接: ${shareUrl}\n错误: ${driverResult.message}`,
'warn'); 'warn', {
file_name: sourceTitle || shareUrl,
fail_count: String(failCount),
cloud_type: cloudType,
nickname: config.nickname || '',
error: driverResult.message || '',
share_url: shareUrl,
});
} }
} }

View File

@@ -198,13 +198,13 @@ export async function trashFiles(cookie: string, fids: string[]): Promise<boolea
if (!fids.length) return true; if (!fids.length) return true;
try { try {
const response = await fetch( const response = await fetch(
`${BASE_URL}/1/clouddrive/file/trash?${makeQuery()}`, `${BASE_URL}/1/clouddrive/file/delete?${makeQuery()}`,
{ {
method: 'POST', method: 'POST',
headers: { ...getHeaders(cookie), 'Content-Type': 'application/json' }, headers: { ...getHeaders(cookie), 'Content-Type': 'application/json' },
body: JSON.stringify({ body: JSON.stringify({
action_type: 1, // 1 = move to trash action_type: 1, // 1 = move to trash
filelist: fids, filelist: fids.map(fid => ({ fid })),
exclude_filelist: [], exclude_filelist: [],
}), }),
signal: AbortSignal.timeout(30000), signal: AbortSignal.timeout(30000),

View File

@@ -1 +1 @@
export const VERSION = "0.2.2"; export const VERSION = "0.2.6";

View File

@@ -1,6 +1,6 @@
{ {
"name": "cloudsearch-frontend", "name": "cloudsearch-frontend",
"version": "0.2.2", "version": "0.2.6",
"private": true, "private": true,
"type": "module", "type": "module",
"scripts": { "scripts": {