diff --git a/src/renderer/i18n/locales/en.json b/src/renderer/i18n/locales/en.json
index 7d6bb5de..28f2d57e 100644
--- a/src/renderer/i18n/locales/en.json
+++ b/src/renderer/i18n/locales/en.json
@@ -654,6 +654,9 @@
},
"selectDownloadFolderTips": "Select download directory",
"selectDownloadFolderTitle": "Choose download folder",
+ "thumbnailSuffixPlaceholder": "Example: ?imageMogr2/thumbnail/200x200",
+ "thumbnailSuffixTips": "Only affects image previews in the cloud management list. Copy, download, and delete still use the original URL",
+ "thumbnailSuffixTitle": "Image preview thumbnail suffix",
"timestampRenameTips": "When enabled, uploaded files will be renamed to a timestamp",
"timestampRenameTitle": "Timestamp rename on upload (highest priority)",
"title": "Manage General Settings"
diff --git a/src/renderer/i18n/locales/zh-CN.json b/src/renderer/i18n/locales/zh-CN.json
index 2702cda8..ba6007db 100644
--- a/src/renderer/i18n/locales/zh-CN.json
+++ b/src/renderer/i18n/locales/zh-CN.json
@@ -654,6 +654,9 @@
},
"selectDownloadFolderTips": "选择下载目录",
"selectDownloadFolderTitle": "选择下载文件夹",
+ "thumbnailSuffixPlaceholder": "例如:?imageMogr2/thumbnail/200x200",
+ "thumbnailSuffixTips": "仅影响云管理列表中的图片预览,不会改变复制链接、下载或删除使用的原始地址",
+ "thumbnailSuffixTitle": "图片预览缩略图后缀",
"timestampRenameTips": "开启后,上传的文件将自动重命名为时间戳",
"timestampRenameTitle": "上传文件时间戳重命名(最高优先级)",
"title": "管理通用设置"
diff --git a/src/renderer/i18n/locales/zh-TW.json b/src/renderer/i18n/locales/zh-TW.json
index 44d8083c..4c5eb038 100644
--- a/src/renderer/i18n/locales/zh-TW.json
+++ b/src/renderer/i18n/locales/zh-TW.json
@@ -654,6 +654,9 @@
},
"selectDownloadFolderTips": "選擇下載目錄",
"selectDownloadFolderTitle": "選擇下載資料夾",
+ "thumbnailSuffixPlaceholder": "例如:?imageMogr2/thumbnail/200x200",
+ "thumbnailSuffixTips": "僅影響雲端管理列表中的圖片預覽,不會變更複製連結、下載或刪除使用的原始地址",
+ "thumbnailSuffixTitle": "圖片預覽縮圖後綴",
"timestampRenameTips": "啟用後,上傳的檔案將自動更名為時間戳",
"timestampRenameTitle": "上傳檔案時間戳重新命名(最高優先級)",
"title": "管理通用設置"
diff --git a/src/renderer/manage/pages/BucketPage.vue b/src/renderer/manage/pages/BucketPage.vue
index f8c50aea..ae916502 100644
--- a/src/renderer/manage/pages/BucketPage.vue
+++ b/src/renderer/manage/pages/BucketPage.vue
@@ -327,7 +327,7 @@
>
{}"
/>
@@ -1189,6 +1189,7 @@ import {
} from '@/manage/utils/common'
import { getConfig, saveConfig } from '@/manage/utils/dataSender'
import { textFileExt } from '@/manage/utils/textfile'
+import { appendThumbnailSuffix } from '@/manage/utils/thumbnailUrl'
import { videoExt } from '@/manage/utils/videofile'
import { trimPath } from '@/utils/common'
import { useDragEventListeners } from '@/utils/drag'
@@ -1403,6 +1404,7 @@ const calculateAllFileSize = computed(
'0',
)
const isShowThumbnail = computed(() => manageStore.config.settings.isShowThumbnail ?? false)
+const thumbnailSuffix = computed(() => manageStore.config.settings.thumbnailSuffix ?? '')
const isUsePreSignedUrl = computed(() => manageStore.config.settings.isUsePreSignedUrl ?? false)
const isAutoRefresh = computed(() => manageStore.config.settings.isAutoRefresh ?? false)
const isIgnoreCase = computed(() => manageStore.config.settings.isIgnoreCase ?? false)
@@ -1468,6 +1470,10 @@ watch(
const getExtension = (fileName: string) => window.node.path.extname(fileName).slice(1)
+function getThumbnailUrl(url: string) {
+ return appendThumbnailSuffix(url, thumbnailSuffix.value)
+}
+
function getList() {
if (!searchText.value) {
return currentPageFilesInfo
diff --git a/src/renderer/manage/pages/ManageSetting.vue b/src/renderer/manage/pages/ManageSetting.vue
index 1527204c..c0ebe551 100644
--- a/src/renderer/manage/pages/ManageSetting.vue
+++ b/src/renderer/manage/pages/ManageSetting.vue
@@ -56,20 +56,30 @@
:placeholder="t('pages.manage.setting.copyFormat.customTips')"
/>
-
-
-
-
- {{ segment.text }}
-
-
-
- {{
- form[item.configName] ? item.activeText : item.inactiveText
- }}
-
-
-
+
+
+
+
+
+ {{ segment.text }}
+
+
+
+ {{
+ form[item.configName] ? item.activeText : item.inactiveText
+ }}
+
+
+
+
+
+
+
({
customRename: false,
isAutoRefresh: false,
isShowThumbnail: false,
+ thumbnailSuffix: '',
isUsePreSignedUrl: false,
isIgnoreCase: false,
isForceCustomUrlHttps: false,
diff --git a/src/renderer/manage/utils/thumbnailUrl.ts b/src/renderer/manage/utils/thumbnailUrl.ts
new file mode 100644
index 00000000..7106bada
--- /dev/null
+++ b/src/renderer/manage/utils/thumbnailUrl.ts
@@ -0,0 +1,14 @@
+export function appendThumbnailSuffix(url: string, suffix?: string): string {
+ const normalizedSuffix = suffix?.trim() ?? ''
+ if (!url || !normalizedSuffix) return url
+
+ if (normalizedSuffix.startsWith('?')) {
+ return `${url}${url.includes('?') ? '&' : '?'}${normalizedSuffix.slice(1)}`
+ }
+
+ if (normalizedSuffix.startsWith('&')) {
+ return `${url}${url.includes('?') ? '&' : '?'}${normalizedSuffix.slice(1)}`
+ }
+
+ return `${url}${normalizedSuffix}`
+}
diff --git a/tests/thumbnail-url.test.ts b/tests/thumbnail-url.test.ts
new file mode 100644
index 00000000..ee8e27bd
--- /dev/null
+++ b/tests/thumbnail-url.test.ts
@@ -0,0 +1,36 @@
+import { describe, expect, it } from 'vitest'
+
+import { appendThumbnailSuffix } from '../src/renderer/manage/utils/thumbnailUrl'
+
+describe('appendThumbnailSuffix', () => {
+ it('keeps the original URL when the suffix is empty', () => {
+ const url = 'https://example.com/image.png'
+
+ expect(appendThumbnailSuffix(url, '')).toBe(url)
+ expect(appendThumbnailSuffix(url)).toBe(url)
+ })
+
+ it('appends query-style suffixes to URLs without query strings', () => {
+ expect(appendThumbnailSuffix('https://example.com/image.png', '?imageMogr2/thumbnail/200x200')).toBe(
+ 'https://example.com/image.png?imageMogr2/thumbnail/200x200',
+ )
+ })
+
+ it('converts query-style suffixes to additional parameters when the URL already has a query string', () => {
+ expect(appendThumbnailSuffix('https://example.com/image.png?version=1', '?imageMogr2/thumbnail/200x200')).toBe(
+ 'https://example.com/image.png?version=1&imageMogr2/thumbnail/200x200',
+ )
+ })
+
+ it('normalizes ampersand-prefixed suffixes when the URL has no query string', () => {
+ expect(appendThumbnailSuffix('https://example.com/image.png', '&x-oss-process=image/resize,w_200')).toBe(
+ 'https://example.com/image.png?x-oss-process=image/resize,w_200',
+ )
+ })
+
+ it('appends path-style suffixes unchanged', () => {
+ expect(appendThumbnailSuffix('https://example.com/image.png', '/thumbnail/200x200')).toBe(
+ 'https://example.com/image.png/thumbnail/200x200',
+ )
+ })
+})