From 4d2e08f9bc100f053beeaf384480eead96601ce8 Mon Sep 17 00:00:00 2001 From: Zain Date: Fri, 26 Dec 2025 23:23:11 +0800 Subject: [PATCH] =?UTF-8?q?fix(quark):=20=E4=BF=AE=E5=A4=8D=E4=BB=8EURL=20?= =?UTF-8?q?hash=E4=B8=AD=E6=8F=90=E5=8F=96=E7=9B=AE=E5=BD=95ID=E7=9A=84?= =?UTF-8?q?=E9=97=AE=E9=A2=98=E5=B9=B6=E6=94=AF=E6=8C=81=E6=96=87=E4=BB=B6?= =?UTF-8?q?=E5=A4=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 修改QuarkAdapter以正确处理URL hash路径中的目录ID,并支持在文件列表中包含文件夹 --- src/adapters/quark/quark.ts | 62 ++++++++--- src/shared/version.ts | 2 +- tests/unit/adapters/quark-adapter.test.ts | 121 ++++++++++++++++++++++ 3 files changed, 169 insertions(+), 16 deletions(-) diff --git a/src/adapters/quark/quark.ts b/src/adapters/quark/quark.ts index 099b7f5..c1456b3 100644 --- a/src/adapters/quark/quark.ts +++ b/src/adapters/quark/quark.ts @@ -162,20 +162,18 @@ export class QuarkAdapter extends BasePlatformAdapter { const pageFiles = result.data.list; - // Filter out folders (only return files) - const files = pageFiles - .filter(f => f.file && !f.dir) - .map((file): FileItem => { - const { ext } = parseFileName(file.file_name); - return { - id: file.fid, - name: file.file_name, - ext: ext, - parentId: file.pdir_fid, - size: file.size, - mtime: file.updated_at, - }; - }); + // Include both files and folders (folders have empty extension) + const files = pageFiles.map((item): FileItem => { + const ext = item.file ? parseFileName(item.file_name).ext : ''; + return { + id: item.fid, + name: item.file_name, + ext, + parentId: item.pdir_fid, + size: item.size, + mtime: item.updated_at, + }; + }); allFiles.push(...files); @@ -337,10 +335,44 @@ export class QuarkAdapter extends BasePlatformAdapter { return dirId; } + // 夸克网盘使用 hash 路由 (例如: #/list/folder/12345 或 #/list/all/12345-xxxx) + // 支持嵌套路径: #/list/all/parent-name/child1-name/child2-name + const hash = window.location.hash || ''; + if (hash) { + // Remove query string portion in hash (if any) + const hashPath = hash.split('?')[0]; + + // 🔧 FIX: 提取整个路径,取最后一个 segment(当前目录) + // 移除前缀 #/list/folder/ 或 #/list/all/ + const normalized = hashPath + .replace(/^#/, '') + .replace(/^\/list\/(?:all|folder)/, '') + .replace(/^\/+/, '') + .replace(/\/+$/, ''); + + if (normalized) { + // 分割路径,取最后一个 segment(当前目录) + const segments = normalized.split('/').filter(Boolean); + if (segments.length > 0) { + const lastSegment = segments[segments.length - 1]; + // 提取 ID(-之前的部分) + // 例如: "e1446ca1c77f4061b470c07961369e2d-第一章:机器学习与深度学习理论基础" + // -> "e1446ca1c77f4061b470c07961369e2d" + const idMatch = lastSegment.match(/^([a-z0-9]+)/); + if (idMatch && idMatch[1]) { + return idMatch[1]; + } + } + } + } + // 尝试从 DOM 中提取 const dirElement = document.querySelector('[data-dir-id]'); if (dirElement) { - return dirElement.getAttribute('data-dir-id') || ''; + const domDirId = dirElement.getAttribute('data-dir-id'); + if (domDirId) { + return domDirId; + } } // 默认返回根目录标识 diff --git a/src/shared/version.ts b/src/shared/version.ts index d990e6c..4a32d57 100644 --- a/src/shared/version.ts +++ b/src/shared/version.ts @@ -10,7 +10,7 @@ * 1. Edit version in package.json * 2. Run: npm run sync:version (or automatically via prebuild/predev) * - * Generated at: 2025-12-26T07:59:11.768Z + * Generated at: 2025-12-26T14:21:45.285Z */ /** diff --git a/tests/unit/adapters/quark-adapter.test.ts b/tests/unit/adapters/quark-adapter.test.ts index a336a3c..f2e71a2 100644 --- a/tests/unit/adapters/quark-adapter.test.ts +++ b/tests/unit/adapters/quark-adapter.test.ts @@ -182,6 +182,81 @@ describe('QuarkAdapter', () => { }); }); + describe('getAllFiles方法', () => { + it('应该返回当前目录下的文件和文件夹', async () => { + // Avoid real 800ms rate limiting delay in unit test + vi.spyOn(adapter as any, 'rateLimit').mockResolvedValue(undefined); + + Object.defineProperty(window, 'location', { + value: { + search: '', + hash: '#/list/folder/12345', + }, + writable: true, + }); + + mockFetch.mockResolvedValue({ + json: async () => ({ + status: 200, + code: 0, + message: 'success', + timestamp: Date.now(), + data: { + list: [ + { + fid: 'file-1', + file_name: 'a.txt', + pdir_fid: '12345', + size: 10, + updated_at: 111, + file: true, + dir: false, + }, + { + fid: 'dir-1', + file_name: 'folderA', + pdir_fid: '12345', + size: 0, + updated_at: 222, + file: false, + dir: true, + }, + ], + }, + }), + }); + + const files = await adapter.getAllFiles(); + + expect(files).toEqual([ + { + id: 'file-1', + name: 'a.txt', + ext: '.txt', + parentId: '12345', + size: 10, + mtime: 111, + }, + { + id: 'dir-1', + name: 'folderA', + ext: '', + parentId: '12345', + size: 0, + mtime: 222, + }, + ]); + + expect(mockFetch).toHaveBeenCalledWith( + expect.stringContaining('pdir_fid=12345'), + expect.objectContaining({ + method: 'GET', + credentials: 'include', + }) + ); + }); + }); + describe('renameFile方法', () => { beforeEach(() => { vi.useFakeTimers(); @@ -683,6 +758,52 @@ describe('QuarkAdapter', () => { expect(files).toHaveLength(1); expect(files[0].parentId).toBe('0'); }); + + it('应该从URL hash中提取folder路径的目录ID', async () => { + Object.defineProperty(window, 'location', { + value: { + search: '', + hash: '#/list/folder/12345', + }, + writable: true, + }); + + document.body.innerHTML = ` + + + + + +
test.txt
+ `; + + const files = await adapter.getSelectedFiles(); + expect(files).toHaveLength(1); + expect(files[0].parentId).toBe('12345'); + }); + + it('应该从URL hash中提取all路径的目录ID并去掉后缀', async () => { + Object.defineProperty(window, 'location', { + value: { + search: '', + hash: '#/list/all/98765-extra-info', + }, + writable: true, + }); + + document.body.innerHTML = ` + + + + + +
test.txt
+ `; + + const files = await adapter.getSelectedFiles(); + expect(files).toHaveLength(1); + expect(files[0].parentId).toBe('98765'); + }); }); describe('配置和平台属性', () => {