diff --git a/apps/web-antd/src/layouts/basic.vue b/apps/web-antd/src/layouts/basic.vue index 1bb07ec8f..c938f09cd 100644 --- a/apps/web-antd/src/layouts/basic.vue +++ b/apps/web-antd/src/layouts/basic.vue @@ -226,6 +226,7 @@ watch( description="ann.vben@gmail.com" tag-text="Pro" @logout="handleLogout" + @clear-preferences-and-logout="handleLogout" /> diff --git a/apps/web-antdv-next/src/layouts/basic.vue b/apps/web-antdv-next/src/layouts/basic.vue index 1bb07ec8f..c938f09cd 100644 --- a/apps/web-antdv-next/src/layouts/basic.vue +++ b/apps/web-antdv-next/src/layouts/basic.vue @@ -226,6 +226,7 @@ watch( description="ann.vben@gmail.com" tag-text="Pro" @logout="handleLogout" + @clear-preferences-and-logout="handleLogout" /> diff --git a/apps/web-ele/src/layouts/basic.vue b/apps/web-ele/src/layouts/basic.vue index 1bb07ec8f..c938f09cd 100644 --- a/apps/web-ele/src/layouts/basic.vue +++ b/apps/web-ele/src/layouts/basic.vue @@ -226,6 +226,7 @@ watch( description="ann.vben@gmail.com" tag-text="Pro" @logout="handleLogout" + @clear-preferences-and-logout="handleLogout" /> diff --git a/apps/web-naive/src/layouts/basic.vue b/apps/web-naive/src/layouts/basic.vue index 1bb07ec8f..c938f09cd 100644 --- a/apps/web-naive/src/layouts/basic.vue +++ b/apps/web-naive/src/layouts/basic.vue @@ -226,6 +226,7 @@ watch( description="ann.vben@gmail.com" tag-text="Pro" @logout="handleLogout" + @clear-preferences-and-logout="handleLogout" /> diff --git a/apps/web-tdesign/src/layouts/basic.vue b/apps/web-tdesign/src/layouts/basic.vue index 1bb07ec8f..c938f09cd 100644 --- a/apps/web-tdesign/src/layouts/basic.vue +++ b/apps/web-tdesign/src/layouts/basic.vue @@ -226,6 +226,7 @@ watch( description="ann.vben@gmail.com" tag-text="Pro" @logout="handleLogout" + @clear-preferences-and-logout="handleLogout" /> diff --git a/packages/@core/base/typings/src/app.d.ts b/packages/@core/base/typings/src/app.d.ts index f2b443359..dc6081b1a 100644 --- a/packages/@core/base/typings/src/app.d.ts +++ b/packages/@core/base/typings/src/app.d.ts @@ -10,12 +10,17 @@ type LayoutType = type ThemeModeType = 'auto' | 'dark' | 'light'; /** - * 偏好设置按钮位置 + * 按钮位置 + * user-dropdown 用户的下拉弹出框中 * fixed 固定在右侧 * header 顶栏 * auto 自动 */ -type PreferencesButtonPositionType = 'auto' | 'fixed' | 'header'; +type PreferencesButtonPositionType = + | 'auto' + | 'fixed' + | 'header' + | 'user-dropdown'; type BuiltinThemeType = | 'custom' diff --git a/packages/@core/preferences/__tests__/__snapshots__/config.test.ts.snap b/packages/@core/preferences/__tests__/__snapshots__/config.test.ts.snap index 5e3dc6c81..041dfab27 100644 --- a/packages/@core/preferences/__tests__/__snapshots__/config.test.ts.snap +++ b/packages/@core/preferences/__tests__/__snapshots__/config.test.ts.snap @@ -30,6 +30,7 @@ exports[`defaultPreferences immutability test > should not modify the config obj "loginExpiredMode": "page", "name": "Vben Admin", "preferencesButtonPosition": "auto", + "timezone": "Asia/Shanghai", "watermark": false, "watermarkContent": "", "zIndex": 200, diff --git a/packages/@core/preferences/src/config.ts b/packages/@core/preferences/src/config.ts index c39366a75..88ba861fb 100644 --- a/packages/@core/preferences/src/config.ts +++ b/packages/@core/preferences/src/config.ts @@ -30,6 +30,7 @@ const defaultPreferences: Preferences = { loginExpiredMode: 'page', name: 'Vben Admin', preferencesButtonPosition: 'auto', + timezone: 'Asia/Shanghai', watermark: false, watermarkContent: '', zIndex: 200, diff --git a/packages/@core/preferences/src/types.ts b/packages/@core/preferences/src/types.ts index 50aefa6e0..bf86935bf 100644 --- a/packages/@core/preferences/src/types.ts +++ b/packages/@core/preferences/src/types.ts @@ -155,6 +155,10 @@ interface AppPreferences { name: string; /** 偏好设置按钮位置 */ preferencesButtonPosition: PreferencesButtonPositionType; + /** + * @zh_CN 应用时区 + */ + timezone: string; /** * @zh_CN 是否开启水印 */ diff --git a/packages/@core/preferences/src/use-preferences.ts b/packages/@core/preferences/src/use-preferences.ts index e126cd9a8..a27f8d733 100644 --- a/packages/@core/preferences/src/use-preferences.ts +++ b/packages/@core/preferences/src/use-preferences.ts @@ -195,12 +195,12 @@ function usePreferences() { */ const preferencesButtonPosition = computed(() => { const { enablePreferences, preferencesButtonPosition } = preferences.app; - // 如果没有启用偏好设置按钮 if (!enablePreferences) { return { fixed: false, header: false, + userDropdown: false, }; } @@ -211,12 +211,15 @@ function usePreferences() { const contentIsMaximize = headerHidden && sidebarHidden; const isHeaderPosition = preferencesButtonPosition === 'header'; + const isUserDropdownPosition = + preferencesButtonPosition === 'user-dropdown'; // 如果设置了固定位置 if (preferencesButtonPosition !== 'auto') { return { fixed: preferencesButtonPosition === 'fixed', header: isHeaderPosition, + userDropdown: isUserDropdownPosition, }; } @@ -230,6 +233,7 @@ function usePreferences() { return { fixed, header: !fixed, + userDropdown: !fixed && isUserDropdownPosition, }; }); diff --git a/packages/effects/layouts/src/widgets/preferences/blocks/general/general.vue b/packages/effects/layouts/src/widgets/preferences/blocks/general/general.vue index 857902924..d5fd1c737 100644 --- a/packages/effects/layouts/src/widgets/preferences/blocks/general/general.vue +++ b/packages/effects/layouts/src/widgets/preferences/blocks/general/general.vue @@ -1,6 +1,9 @@ {{ $t('preferences.language') }} + + {{ $t('preferences.timezone') }} + {{ $t('preferences.dynamicTitle') }} diff --git a/packages/effects/layouts/src/widgets/preferences/blocks/layout/widget.vue b/packages/effects/layouts/src/widgets/preferences/blocks/layout/widget.vue index 73b7af7a8..39cd14e5b 100644 --- a/packages/effects/layouts/src/widgets/preferences/blocks/layout/widget.vue +++ b/packages/effects/layouts/src/widgets/preferences/blocks/layout/widget.vue @@ -38,6 +38,10 @@ const positionItems = computed((): SelectOption[] => [ label: $t('preferences.position.fixed'), value: 'fixed', }, + { + label: $t('preferences.position.userDropdown'), + value: 'user-dropdown', + }, ]); diff --git a/packages/effects/layouts/src/widgets/preferences/preferences-drawer.vue b/packages/effects/layouts/src/widgets/preferences/preferences-drawer.vue index c3204166f..963e9da4b 100644 --- a/packages/effects/layouts/src/widgets/preferences/preferences-drawer.vue +++ b/packages/effects/layouts/src/widgets/preferences/preferences-drawer.vue @@ -65,6 +65,7 @@ const emit = defineEmits<{ clearPreferencesAndLogout: [] }>(); const message = globalShareState.getMessage(); const appLocale = defineModel('appLocale'); +const appTimezone = defineModel('appTimezone'); const appDynamicTitle = defineModel('appDynamicTitle'); const appLayout = defineModel('appLayout'); const appColorGrayMode = defineModel('appColorGrayMode'); @@ -359,6 +360,7 @@ function handleCustomPreferencesUpdate(updates: CustomPreferencesRecord) { v-model:app-enable-check-updates="appEnableCheckUpdates" v-model:app-enable-copy-preferences="appEnableCopyPreferences" v-model:app-locale="appLocale" + v-model:app-timezone="appTimezone" v-model:app-watermark="appWatermark" v-model:app-watermark-content="appWatermarkContent" /> diff --git a/packages/effects/layouts/src/widgets/preferences/preferences.vue b/packages/effects/layouts/src/widgets/preferences/preferences.vue index d99e0d90d..ef2e41cfe 100644 --- a/packages/effects/layouts/src/widgets/preferences/preferences.vue +++ b/packages/effects/layouts/src/widgets/preferences/preferences.vue @@ -11,10 +11,26 @@ import { VbenButton } from '@vben-core/shadcn-ui'; import PreferencesDrawer from './preferences-drawer.vue'; +interface Props { + /** 是否显示按钮 */ + showButton?: boolean; +} + +const props = withDefaults(defineProps(), { + showButton: true, +}); + +const emit = defineEmits<{ clearPreferencesAndLogout: [] }>(); + const [Drawer, drawerApi] = useVbenDrawer({ connectedComponent: PreferencesDrawer, }); +// 暴露打开抽屉的方法 +defineExpose({ + open: () => drawerApi.open(), +}); + /** * preferences 转成 vue props * preferences.widget.fullscreen=>widgetFullscreen @@ -56,17 +72,22 @@ const listen = computed(() => { - + - drawerApi.open()"> - - - - - - + + + drawerApi.open()" + > + + + diff --git a/packages/effects/layouts/src/widgets/user-dropdown/user-dropdown.vue b/packages/effects/layouts/src/widgets/user-dropdown/user-dropdown.vue index b11f3857b..8eadde33a 100644 --- a/packages/effects/layouts/src/widgets/user-dropdown/user-dropdown.vue +++ b/packages/effects/layouts/src/widgets/user-dropdown/user-dropdown.vue @@ -6,7 +6,7 @@ import type { AnyFunction } from '@vben/types'; import { computed, useTemplateRef, watch } from 'vue'; import { useHoverToggle } from '@vben/hooks'; -import { LockKeyhole, LogOut } from '@vben/icons'; +import { LockKeyhole, LogOut, Settings } from '@vben/icons'; import { $t } from '@vben/locales'; import { preferences, usePreferences } from '@vben/preferences'; import { useAccessStore } from '@vben/stores'; @@ -29,6 +29,7 @@ import { import { useMagicKeys, whenever } from '@vueuse/core'; import { LockScreenModal } from '../lock-screen'; +import { Preferences } from '../preferences'; interface Props { /** @@ -82,10 +83,13 @@ const props = withDefaults(defineProps(), { hoverDelay: 500, }); -const emit = defineEmits<{ logout: [] }>(); +const emit = defineEmits<{ clearPreferencesAndLogout: []; logout: [] }>(); -const { globalLockScreenShortcutKey, globalLogoutShortcutKey } = - usePreferences(); +const { + globalLockScreenShortcutKey, + globalLogoutShortcutKey, + preferencesButtonPosition, +} = usePreferences(); const accessStore = useAccessStore(); const [LockModal, lockModalApi] = useVbenModal({ connectedComponent: LockScreenModal, @@ -98,6 +102,7 @@ const [LogoutModal, logoutModalApi] = useVbenModal({ const refTrigger = useTemplateRef('refTrigger'); const refContent = useTemplateRef('refContent'); +const refPreferences = useTemplateRef('refPreferences'); const [openPopover, hoverWatcher] = useHoverToggle( [refTrigger, refContent], () => props.hoverDelay, @@ -151,6 +156,11 @@ function handleSubmitLogout() { logoutModalApi.close(); } +// 设置 - 打开偏好设置抽屉 +function handleOpenSettings() { + refPreferences.value?.open(); +} + if (enableShortcutKey.value) { const keys = useMagicKeys(); const logoutKey = keys['Alt+KeyQ']; @@ -195,6 +205,13 @@ if (enableShortcutKey.value) { {{ $t('ui.widgets.logoutTip') }} + + @@ -241,6 +258,14 @@ if (enableShortcutKey.value) { {{ menu.text }} + + + {{ $t('preferences.title') }} + { tag-text="Pro" trigger="both" @logout="handleLogout" + @clear-preferences-and-logout="handleLogout" />