diff --git a/frontend-vue/src/shared/api/download.ts b/frontend-vue/src/shared/api/download.ts new file mode 100644 index 00000000..f73d8380 --- /dev/null +++ b/frontend-vue/src/shared/api/download.ts @@ -0,0 +1,22 @@ +export interface DownloadableItem { + freshDownloadUrl?: string | null + downloadUrl?: string | null +} + +export function buildDownloadUrl(path: string, userId?: number): string { + if (userId === undefined || userId === null || Number.isNaN(userId)) { + return path + } + if (/[?&]user_id=/.test(path)) { + return path + } + const separator = path.includes('?') ? '&' : '?' + return `${path}${separator}user_id=${userId}` +} + +export function resolveDownloadUrl(item: DownloadableItem | null | undefined): string { + if (!item) { + return '' + } + return item.freshDownloadUrl || item.downloadUrl || '' +} diff --git a/frontend-vue/tests/download.test.ts b/frontend-vue/tests/download.test.ts new file mode 100644 index 00000000..7a37c02b --- /dev/null +++ b/frontend-vue/tests/download.test.ts @@ -0,0 +1,50 @@ +import { test } from 'node:test' +import assert from 'node:assert/strict' +import { buildDownloadUrl, resolveDownloadUrl } from '../src/shared/api/download.ts' + +test('test_download_url_user_id', () => { + assert.equal( + buildDownloadUrl('/api/dedupe/results/5/download', 42), + '/api/dedupe/results/5/download?user_id=42', + ) +}) + +test('test_download_url_no_user_id', () => { + assert.equal(buildDownloadUrl('/api/dedupe/results/5/download'), '/api/dedupe/results/5/download') +}) + +test('test_download_url_existing_user_id', () => { + assert.equal( + buildDownloadUrl('/api/dedupe/results/5/download?user_id=99', 42), + '/api/dedupe/results/5/download?user_id=99', + '已有 user_id 时不重复追加', + ) +}) + +test('test_resolve_download_fresh_priority', () => { + const item = { freshDownloadUrl: '/newApi/api/fresh-url', downloadUrl: '/old-url' } + assert.equal(resolveDownloadUrl(item), '/newApi/api/fresh-url') +}) + +test('test_resolve_download_fallback', () => { + const item = { downloadUrl: '/newApi/api/old-url' } + assert.equal(resolveDownloadUrl(item), '/newApi/api/old-url') +}) + +test('test_resolve_download_both_blank', () => { + assert.equal(resolveDownloadUrl({}), '') + assert.equal(resolveDownloadUrl({ freshDownloadUrl: '', downloadUrl: '' }), '') +}) + +test('test_download_url_query_merge', () => { + assert.equal( + buildDownloadUrl('/api/x/download?token=abc', 7), + '/api/x/download?token=abc&user_id=7', + '已有 query 应合并追加 user_id', + ) +}) + +test('test_resolve_download_null_safe', () => { + assert.equal(resolveDownloadUrl(null as never), '') + assert.equal(resolveDownloadUrl(undefined as never), '') +})