From 5907c04e00ea022bdf2b0091cc4ad20fb83dbe7b Mon Sep 17 00:00:00 2001 From: AxiosLeo <13862149+AxiosLeo@users.noreply.github.com> Date: Wed, 22 Apr 2026 07:08:40 +0800 Subject: [PATCH 1/4] fix: update selector for active menu item in useMenuScroll hook (#7829) --- packages/@core/ui-kit/menu-ui/src/hooks/use-menu-scroll.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/@core/ui-kit/menu-ui/src/hooks/use-menu-scroll.ts b/packages/@core/ui-kit/menu-ui/src/hooks/use-menu-scroll.ts index 270a0348d..e18bae755 100644 --- a/packages/@core/ui-kit/menu-ui/src/hooks/use-menu-scroll.ts +++ b/packages/@core/ui-kit/menu-ui/src/hooks/use-menu-scroll.ts @@ -20,7 +20,7 @@ export function useMenuScroll( if (!isEnabled) return; const activeElement = document.querySelector( - `aside li[role=menuitem].is-active`, + `aside a[role=menuitem].is-active`, ); if (activeElement) { activeElement.scrollIntoView({ From 3a83fb0c3e0ef233cff6288c5b4f760a70663e08 Mon Sep 17 00:00:00 2001 From: AxiosLeo <13862149+AxiosLeo@users.noreply.github.com> Date: Wed, 22 Apr 2026 07:09:09 +0800 Subject: [PATCH 2/4] fix: ensure trigger function is awaited in useDependencies (#7830) --- packages/@core/ui-kit/form-ui/src/form-render/dependencies.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/@core/ui-kit/form-ui/src/form-render/dependencies.ts b/packages/@core/ui-kit/form-ui/src/form-render/dependencies.ts index 505bc9eef..8eb656eac 100644 --- a/packages/@core/ui-kit/form-ui/src/form-render/dependencies.ts +++ b/packages/@core/ui-kit/form-ui/src/form-render/dependencies.ts @@ -154,7 +154,7 @@ export default function useDependencies( } if (isFunction(trigger)) { - trigger(formValues, formApi, getController()); + await trigger(formValues, formApi, getController()); } }, { deep: true, immediate: true }, From c7fd6ffb0e6f4092cd69189450767fca7fcb4f2f Mon Sep 17 00:00:00 2001 From: boisduval Date: Thu, 23 Apr 2026 17:25:10 +0800 Subject: [PATCH 3/4] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=E6=97=A5?= =?UTF-8?q?=E6=9C=9F=E6=A0=BC=E5=BC=8F=E5=8C=96=E5=87=BD=E6=95=B0=E7=9A=84?= =?UTF-8?q?=E7=A9=BA=E5=80=BC=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 当传入的时间参数为 undefined、null 或空字符串时,直接返回空字符串而不是继续执行格式化逻辑,避免无效的时间值导致程序错误。 --- packages/@core/base/shared/src/utils/date.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/@core/base/shared/src/utils/date.ts b/packages/@core/base/shared/src/utils/date.ts index c68c33850..784b9778e 100644 --- a/packages/@core/base/shared/src/utils/date.ts +++ b/packages/@core/base/shared/src/utils/date.ts @@ -20,6 +20,9 @@ type Format = | (string & {}); export function formatDate(time?: FormatDate, format: Format = 'YYYY-MM-DD') { + if (time === undefined || time === null || time === '') { + return ''; + } try { const date = dayjs.isDayjs(time) ? time : dayjs(time); if (!date.isValid()) { From 42317ddf418ee94a452032a0ca97e3edd85eba42 Mon Sep 17 00:00:00 2001 From: Lgf <2246221508@qq.com> Date: Fri, 24 Apr 2026 15:42:07 +0800 Subject: [PATCH 4/4] =?UTF-8?q?feat(watermark):=20=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E6=9A=97=E9=BB=91=E6=A8=A1=E5=BC=8F=E6=B0=B4=E5=8D=B0=E9=A2=9C?= =?UTF-8?q?=E8=89=B2=E9=80=82=E9=85=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 为水印功能添加暗黑模式适配,根据当前主题自动切换水印颜色。在暗黑模式下使用浅色水印,在亮色模式下使用深色水印,提升视觉体验。 --- apps/web-antd/src/layouts/basic.vue | 23 +++++++++++++++++++++-- apps/web-antdv-next/src/layouts/basic.vue | 23 +++++++++++++++++++++-- apps/web-ele/src/layouts/basic.vue | 23 +++++++++++++++++++++-- apps/web-naive/src/layouts/basic.vue | 23 +++++++++++++++++++++-- apps/web-tdesign/src/layouts/basic.vue | 23 +++++++++++++++++++++-- playground/src/layouts/basic.vue | 23 +++++++++++++++++++++-- 6 files changed, 126 insertions(+), 12 deletions(-) diff --git a/apps/web-antd/src/layouts/basic.vue b/apps/web-antd/src/layouts/basic.vue index 211ee7be3..1bb07ec8f 100644 --- a/apps/web-antd/src/layouts/basic.vue +++ b/apps/web-antd/src/layouts/basic.vue @@ -14,7 +14,7 @@ import { Notification, UserDropdown, } from '@vben/layouts'; -import { preferences } from '@vben/preferences'; +import { preferences, usePreferences } from '@vben/preferences'; import { useAccessStore, useUserStore } from '@vben/stores'; import { openWindow } from '@vben/utils'; @@ -80,6 +80,7 @@ const userStore = useUserStore(); const authStore = useAuthStore(); const accessStore = useAccessStore(); const { destroyWatermark, updateWatermark } = useWatermark(); +const { isDark } = usePreferences(); const showDot = computed(() => notifications.value.some((item) => !item.isRead), ); @@ -179,10 +180,28 @@ watch( () => ({ enable: preferences.app.watermark, content: preferences.app.watermarkContent, + isDark: isDark.value, }), - async ({ enable, content }) => { + async ({ enable, content, isDark: isDarkValue }) => { if (enable) { + const watermarkColor = isDarkValue + ? 'rgba(255, 255, 255, 0.12)' + : 'rgba(0, 0, 0, 0.12)'; + await updateWatermark({ + advancedStyle: { + colorStops: [ + { + color: watermarkColor, + offset: 0, + }, + { + color: watermarkColor, + offset: 1, + }, + ], + type: 'linear', + }, content: content || `${userStore.userInfo?.username} - ${userStore.userInfo?.realName}`, diff --git a/apps/web-antdv-next/src/layouts/basic.vue b/apps/web-antdv-next/src/layouts/basic.vue index 211ee7be3..1bb07ec8f 100644 --- a/apps/web-antdv-next/src/layouts/basic.vue +++ b/apps/web-antdv-next/src/layouts/basic.vue @@ -14,7 +14,7 @@ import { Notification, UserDropdown, } from '@vben/layouts'; -import { preferences } from '@vben/preferences'; +import { preferences, usePreferences } from '@vben/preferences'; import { useAccessStore, useUserStore } from '@vben/stores'; import { openWindow } from '@vben/utils'; @@ -80,6 +80,7 @@ const userStore = useUserStore(); const authStore = useAuthStore(); const accessStore = useAccessStore(); const { destroyWatermark, updateWatermark } = useWatermark(); +const { isDark } = usePreferences(); const showDot = computed(() => notifications.value.some((item) => !item.isRead), ); @@ -179,10 +180,28 @@ watch( () => ({ enable: preferences.app.watermark, content: preferences.app.watermarkContent, + isDark: isDark.value, }), - async ({ enable, content }) => { + async ({ enable, content, isDark: isDarkValue }) => { if (enable) { + const watermarkColor = isDarkValue + ? 'rgba(255, 255, 255, 0.12)' + : 'rgba(0, 0, 0, 0.12)'; + await updateWatermark({ + advancedStyle: { + colorStops: [ + { + color: watermarkColor, + offset: 0, + }, + { + color: watermarkColor, + offset: 1, + }, + ], + type: 'linear', + }, content: content || `${userStore.userInfo?.username} - ${userStore.userInfo?.realName}`, diff --git a/apps/web-ele/src/layouts/basic.vue b/apps/web-ele/src/layouts/basic.vue index 211ee7be3..1bb07ec8f 100644 --- a/apps/web-ele/src/layouts/basic.vue +++ b/apps/web-ele/src/layouts/basic.vue @@ -14,7 +14,7 @@ import { Notification, UserDropdown, } from '@vben/layouts'; -import { preferences } from '@vben/preferences'; +import { preferences, usePreferences } from '@vben/preferences'; import { useAccessStore, useUserStore } from '@vben/stores'; import { openWindow } from '@vben/utils'; @@ -80,6 +80,7 @@ const userStore = useUserStore(); const authStore = useAuthStore(); const accessStore = useAccessStore(); const { destroyWatermark, updateWatermark } = useWatermark(); +const { isDark } = usePreferences(); const showDot = computed(() => notifications.value.some((item) => !item.isRead), ); @@ -179,10 +180,28 @@ watch( () => ({ enable: preferences.app.watermark, content: preferences.app.watermarkContent, + isDark: isDark.value, }), - async ({ enable, content }) => { + async ({ enable, content, isDark: isDarkValue }) => { if (enable) { + const watermarkColor = isDarkValue + ? 'rgba(255, 255, 255, 0.12)' + : 'rgba(0, 0, 0, 0.12)'; + await updateWatermark({ + advancedStyle: { + colorStops: [ + { + color: watermarkColor, + offset: 0, + }, + { + color: watermarkColor, + offset: 1, + }, + ], + type: 'linear', + }, content: content || `${userStore.userInfo?.username} - ${userStore.userInfo?.realName}`, diff --git a/apps/web-naive/src/layouts/basic.vue b/apps/web-naive/src/layouts/basic.vue index 211ee7be3..1bb07ec8f 100644 --- a/apps/web-naive/src/layouts/basic.vue +++ b/apps/web-naive/src/layouts/basic.vue @@ -14,7 +14,7 @@ import { Notification, UserDropdown, } from '@vben/layouts'; -import { preferences } from '@vben/preferences'; +import { preferences, usePreferences } from '@vben/preferences'; import { useAccessStore, useUserStore } from '@vben/stores'; import { openWindow } from '@vben/utils'; @@ -80,6 +80,7 @@ const userStore = useUserStore(); const authStore = useAuthStore(); const accessStore = useAccessStore(); const { destroyWatermark, updateWatermark } = useWatermark(); +const { isDark } = usePreferences(); const showDot = computed(() => notifications.value.some((item) => !item.isRead), ); @@ -179,10 +180,28 @@ watch( () => ({ enable: preferences.app.watermark, content: preferences.app.watermarkContent, + isDark: isDark.value, }), - async ({ enable, content }) => { + async ({ enable, content, isDark: isDarkValue }) => { if (enable) { + const watermarkColor = isDarkValue + ? 'rgba(255, 255, 255, 0.12)' + : 'rgba(0, 0, 0, 0.12)'; + await updateWatermark({ + advancedStyle: { + colorStops: [ + { + color: watermarkColor, + offset: 0, + }, + { + color: watermarkColor, + offset: 1, + }, + ], + type: 'linear', + }, content: content || `${userStore.userInfo?.username} - ${userStore.userInfo?.realName}`, diff --git a/apps/web-tdesign/src/layouts/basic.vue b/apps/web-tdesign/src/layouts/basic.vue index 211ee7be3..1bb07ec8f 100644 --- a/apps/web-tdesign/src/layouts/basic.vue +++ b/apps/web-tdesign/src/layouts/basic.vue @@ -14,7 +14,7 @@ import { Notification, UserDropdown, } from '@vben/layouts'; -import { preferences } from '@vben/preferences'; +import { preferences, usePreferences } from '@vben/preferences'; import { useAccessStore, useUserStore } from '@vben/stores'; import { openWindow } from '@vben/utils'; @@ -80,6 +80,7 @@ const userStore = useUserStore(); const authStore = useAuthStore(); const accessStore = useAccessStore(); const { destroyWatermark, updateWatermark } = useWatermark(); +const { isDark } = usePreferences(); const showDot = computed(() => notifications.value.some((item) => !item.isRead), ); @@ -179,10 +180,28 @@ watch( () => ({ enable: preferences.app.watermark, content: preferences.app.watermarkContent, + isDark: isDark.value, }), - async ({ enable, content }) => { + async ({ enable, content, isDark: isDarkValue }) => { if (enable) { + const watermarkColor = isDarkValue + ? 'rgba(255, 255, 255, 0.12)' + : 'rgba(0, 0, 0, 0.12)'; + await updateWatermark({ + advancedStyle: { + colorStops: [ + { + color: watermarkColor, + offset: 0, + }, + { + color: watermarkColor, + offset: 1, + }, + ], + type: 'linear', + }, content: content || `${userStore.userInfo?.username} - ${userStore.userInfo?.realName}`, diff --git a/playground/src/layouts/basic.vue b/playground/src/layouts/basic.vue index 69fefbe33..62b641768 100644 --- a/playground/src/layouts/basic.vue +++ b/playground/src/layouts/basic.vue @@ -14,7 +14,7 @@ import { Notification, UserDropdown, } from '@vben/layouts'; -import { preferences } from '@vben/preferences'; +import { preferences, usePreferences } from '@vben/preferences'; import { useAccessStore, useTabbarStore, useUserStore } from '@vben/stores'; import { openWindow } from '@vben/utils'; @@ -93,6 +93,7 @@ const userStore = useUserStore(); const authStore = useAuthStore(); const accessStore = useAccessStore(); const { destroyWatermark, updateWatermark } = useWatermark(); +const { isDark } = usePreferences(); const showDot = computed(() => notifications.value.some((item) => !item.isRead), ); @@ -194,10 +195,28 @@ watch( () => ({ enable: preferences.app.watermark, content: preferences.app.watermarkContent, + isDark: isDark.value, }), - async ({ enable, content }) => { + async ({ enable, content, isDark: isDarkValue }) => { if (enable) { + const watermarkColor = isDarkValue + ? 'rgba(255, 255, 255, 0.12)' + : 'rgba(0, 0, 0, 0.12)'; + await updateWatermark({ + advancedStyle: { + colorStops: [ + { + color: watermarkColor, + offset: 0, + }, + { + color: watermarkColor, + offset: 1, + }, + ], + type: 'linear', + }, content: content || `${userStore.userInfo?.username} - ${userStore.userInfo?.realName}`,