From 1c4a2176e995ba3ee0bf690d89c6596c6b690153 Mon Sep 17 00:00:00 2001 From: jxxghp Date: Tue, 29 Jul 2025 08:20:16 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=9E=E7=8E=B0=E9=80=8F=E6=98=8E=E4=B8=BB?= =?UTF-8?q?=E9=A2=98=E7=9A=84=E9=80=8F=E6=98=8E=E5=BA=A6=E5=92=8C=E6=A8=A1?= =?UTF-8?q?=E7=B3=8A=E5=BA=A6=E8=AE=BE=E7=BD=AE=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/layouts/components/UserProfile.vue | 210 +++++++++++++++++++++++++ src/locales/en-US.ts | 14 +- src/locales/zh-CN.ts | 11 +- src/locales/zh-TW.ts | 11 +- src/styles/themes/transparent.scss | 57 ++++--- 5 files changed, 274 insertions(+), 29 deletions(-) diff --git a/src/layouts/components/UserProfile.vue b/src/layouts/components/UserProfile.vue index df6a994f..8e2b60c8 100644 --- a/src/layouts/components/UserProfile.vue +++ b/src/layouts/components/UserProfile.vue @@ -46,6 +46,33 @@ const showLanguageMenu = ref(false) // 自定义CSS const customCSS = ref('') +// 透明度相关 +const transparencyOpacity = ref(parseFloat(localStorage.getItem('transparency-opacity') || '0.3')) +const transparencyBlur = ref(parseFloat(localStorage.getItem('transparency-blur') || '10')) +const transparencyLevel = ref(localStorage.getItem('transparency-level') || 'medium') +const isTransparentTheme = computed(() => currentThemeName.value === 'transparent') +const showTransparencyDialog = ref(false) + +// 预设值配置 +const transparencyPresets = { + low: { opacity: 0.1, blur: 5 }, + medium: { opacity: 0.3, blur: 10 }, + high: { opacity: 0.6, blur: 15 }, +} + +// 判断当前值是否匹配预设值 +const currentPresetLevel = computed(() => { + for (const [level, preset] of Object.entries(transparencyPresets)) { + if ( + Math.abs(transparencyOpacity.value - preset.opacity) < 0.01 && + Math.abs(transparencyBlur.value - preset.blur) < 0.1 + ) { + return level + } + } + return null +}) + // 重启轮询控制标识 const restartPollingId = ref(null) const isRestarting = ref(false) @@ -251,6 +278,11 @@ async function changeTheme(theme: string) { // 立即更新主题(不再刷新页面) await updateTheme() + // 如果是透明主题,应用透明度设置 + if (theme === 'transparent') { + applyTransparencySettings() + } + // 保存主题到服务端 try { api.post('/user/config/Layout', { @@ -294,11 +326,78 @@ async function saveCustomCSS() { } } +// 应用透明度设置 +function applyTransparencySettings() { + const root = document.documentElement + + // 设置CSS变量 + root.style.setProperty('--transparent-opacity', transparencyOpacity.value.toString()) + root.style.setProperty('--transparent-opacity-light', (transparencyOpacity.value * 0.67).toString()) + root.style.setProperty('--transparent-opacity-heavy', (transparencyOpacity.value * 1.67).toString()) + root.style.setProperty('--transparent-blur', `${transparencyBlur.value}px`) + root.style.setProperty('--transparent-blur-heavy', `${transparencyBlur.value * 1.6}px`) + + // 保存到本地存储 + localStorage.setItem('transparency-opacity', transparencyOpacity.value.toString()) + localStorage.setItem('transparency-blur', transparencyBlur.value.toString()) +} + +// 调整透明度预设 +function adjustTransparency(level: string) { + transparencyLevel.value = level + localStorage.setItem('transparency-level', level) + + // 设置预设值 + switch (level) { + case 'low': + transparencyOpacity.value = 0.1 + transparencyBlur.value = 5 + break + case 'medium': + transparencyOpacity.value = 0.3 + transparencyBlur.value = 10 + break + case 'high': + transparencyOpacity.value = 0.6 + transparencyBlur.value = 15 + break + } + + applyTransparencySettings() +} + +// 透明度变化处理 +function onOpacityChange() { + applyTransparencySettings() + // 清除预设级别,因为用户手动调整了 + transparencyLevel.value = '' +} + +// 模糊度变化处理 +function onBlurChange() { + applyTransparencySettings() + // 清除预设级别,因为用户手动调整了 + transparencyLevel.value = '' +} + +// 重置透明度设置 +function resetTransparencySettings() { + transparencyOpacity.value = 0.3 + transparencyBlur.value = 10 + transparencyLevel.value = 'medium' + applyTransparencySettings() +} + // 监听主题变化 watch( () => currentThemeName.value, async () => { await updateTheme() + + // 如果切换到透明主题,应用透明度设置 + if (currentThemeName.value === 'transparent') { + applyTransparencySettings() + } }, ) @@ -351,6 +450,11 @@ const getThemeIcon = computed(() => { onMounted(() => { getCustomCSS() + + // 初始化透明度设置 + if (isTransparentTheme.value) { + applyTransparencySettings() + } }) // 组件卸载时清理轮询 @@ -456,6 +560,20 @@ onUnmounted(() => { {{ t('theme.custom') }} + + + @@ -553,6 +671,98 @@ onUnmounted(() => { + + + + + + + + {{ t('theme.transparencyAdjust') }} + + + + + +
+ +
+
+ {{ t('theme.transparencyOpacity') }} + {{ Math.round(transparencyOpacity * 100) }}% +
+ +
+ + +
+
+ {{ t('theme.transparencyBlur') }} + {{ transparencyBlur }}px +
+ +
+ + +
+ {{ t('common.preset') }} + + + {{ t('theme.transparencyLow') }} + + + {{ t('theme.transparencyMedium') }} + + + {{ t('theme.transparencyHigh') }} + + +
+
+
+ + + + + {{ t('theme.transparencyReset') }} + + + {{ t('common.confirm') }} + + +
+