diff --git a/.env.example b/.env.example index f1eb495..2b128d9 100644 --- a/.env.example +++ b/.env.example @@ -14,9 +14,13 @@ # 管理后台域名(可选;不填则使用当前请求域名,也可在设置页配置) # SITE_BASE_URL=https://admin.example.com -# 隐藏图片直链中的目录前缀(如 images/2026/08/a.webp → 2026/08/a.webp) +# 隐藏图片直链中的目录前缀(如 images/2026/08/a.webp → a.webp) # HIDE_FOLDER_IN_URL=false +# 上传目录按年/月分组(true/date 默认;false/flat 则保存为 images/xxx.webp) +# STORAGE_USE_DATE_PATH=true +# STORAGE_LAYOUT=date + # 图片直链域名(可选;不填则使用当前请求域名,也可在设置页配置) # IMAGE_BASE_URL=https://pic.example.com diff --git a/app/pages/logs.vue b/app/pages/logs.vue index a909a96..368c44b 100644 --- a/app/pages/logs.vue +++ b/app/pages/logs.vue @@ -104,8 +104,8 @@ function storageIcon(storage: ActivityLogStorage | null) { function publicPathFromKey(key: string) { if (!hideFolderInUrl.value) return key - const slash = key.indexOf('/') - return slash > 0 ? key.slice(slash + 1) : key + const slash = key.lastIndexOf('/') + return slash >= 0 ? key.slice(slash + 1) : key } function imageUrl(key: string) { diff --git a/app/pages/settings/index.vue b/app/pages/settings/index.vue index e35886d..d5ec014 100644 --- a/app/pages/settings/index.vue +++ b/app/pages/settings/index.vue @@ -20,6 +20,8 @@ interface SettingsResponse { domainSeparation: boolean hideFolderInUrl: boolean hideFolderInUrlSource: SettingSource + storageUseDatePath: boolean + storageUseDatePathSource: SettingSource allowRegistration: boolean appVersion: string } @@ -37,6 +39,7 @@ const refererDraft = ref('') const siteBaseUrlDraft = ref('') const imageBaseUrlDraft = ref('') const hideFolderInUrlDraft = ref(false) +const storageUseDatePathDraft = ref(true) const allowRegistrationDraft = ref(false) const domainSeparationDraft = ref(false) const hideFolderConfirmOpen = ref(false) @@ -61,6 +64,7 @@ const hasServerChanges = computed(() => { || siteBaseUrlDraft.value !== (settings.value.domainSeparation ? settings.value.siteBaseUrlConfigured : '') || imageBaseUrlDraft.value !== settings.value.imageBaseUrlConfigured || hideFolderInUrlDraft.value !== settings.value.hideFolderInUrl + || storageUseDatePathDraft.value !== settings.value.storageUseDatePath || allowRegistrationDraft.value !== settings.value.allowRegistration }) @@ -101,6 +105,7 @@ function applySettings(data: SettingsResponse) { siteBaseUrlDraft.value = data.domainSeparation ? data.siteBaseUrlConfigured : '' imageBaseUrlDraft.value = data.imageBaseUrlConfigured hideFolderInUrlDraft.value = data.hideFolderInUrl + storageUseDatePathDraft.value = data.storageUseDatePath allowRegistrationDraft.value = data.allowRegistration domainSeparationDraft.value = data.domainSeparation } @@ -170,6 +175,7 @@ async function saveServerSettings() { siteBaseUrl: domainSeparationDraft.value ? siteBaseUrlDraft.value : '', imageBaseUrl: imageBaseUrlDraft.value, hideFolderInUrl: hideFolderInUrlDraft.value, + storageUseDatePath: storageUseDatePathDraft.value, allowRegistration: allowRegistrationDraft.value }) toast.add({ title: t('settings.saved'), color: 'success' }) @@ -299,192 +305,54 @@ watch(isAuthenticated, async (authed, prev) => { class="p-5 sm:p-6" >
- {{ t('settings.defaultFolderHint') }} -
-- {{ t('settings.refererHint') }} -
-- {{ t('setup.domainSeparationProxyHint') }} - - {{ t('setup.domainSeparationProxyExample') }} - -
- -- {{ t('settings.siteBaseUrlHint') }} -
-- {{ t('settings.siteBaseUrlActive', { url: settings.siteBaseUrl }) }} -
-- {{ t('settings.imageBaseUrlHint') }} -
-- {{ t('settings.imageBaseUrlActive', { url: settings.imageBaseUrl }) }} -
-- {{ t('settings.imageBaseUrlSingleHint') }} -
-- {{ t('settings.imageBaseUrlActive', { url: settings.imageBaseUrl }) }} -
-+ {{ t('settings.defaultFolderHint') }} +
++ {{ t('settings.refererHint') }} +
++ {{ t('setup.domainSeparationProxyHint') }} + + {{ t('setup.domainSeparationProxyExample') }} + +
+ ++ {{ t('settings.siteBaseUrlHint') }} +
++ {{ t('settings.siteBaseUrlActive', { url: settings.siteBaseUrl }) }} +
++ {{ t('settings.imageBaseUrlHint') }} +
++ {{ t('settings.imageBaseUrlActive', { url: settings.imageBaseUrl }) }} +
++ {{ t('settings.imageBaseUrlSingleHint') }} +
++ {{ t('settings.imageBaseUrlActive', { url: settings.imageBaseUrl }) }} +
+