From 8f3969268a6beae4fd57b363bc6a313264ce5dfc Mon Sep 17 00:00:00 2001
From: XiaoDaiGua-Ray <443547225@qq.com>
Date: Sun, 27 Oct 2024 17:01:53 +0800
Subject: [PATCH] version: v5.0.3
---
CHANGELOG.md | 8 +
package.json | 2 +-
.../provider/AppWatermarkProvider/index.tsx | 2 +-
src/app-config/design-config.ts | 1 -
src/layout/components/Menu/index.tsx | 5 +-
.../components/SettingDrawer/constant.ts | 67 +++-
.../components/SettingDrawer/index.scss | 9 +-
.../components/SettingDrawer/index.tsx | 374 ++++--------------
.../segment-views/Appearance.tsx | 117 ++++++
.../SettingDrawer/segment-views/Common.tsx | 98 +++++
.../segment-views/CustomMenu.tsx | 167 ++++++++
.../SettingDrawer/segment-views/Watermark.tsx | 184 +++++++++
src/store/hooks/useSettingStore.ts | 25 +-
src/store/modules/menu/utils.ts | 6 +
src/store/modules/setting/index.ts | 71 ++--
src/store/modules/setting/types.ts | 11 +
src/types/modules/app-config.ts | 5 +-
src/types/modules/helper.ts | 38 +-
18 files changed, 843 insertions(+), 347 deletions(-)
create mode 100644 src/layout/components/SiderBar/components/SettingDrawer/segment-views/Appearance.tsx
create mode 100644 src/layout/components/SiderBar/components/SettingDrawer/segment-views/Common.tsx
create mode 100644 src/layout/components/SiderBar/components/SettingDrawer/segment-views/CustomMenu.tsx
create mode 100644 src/layout/components/SiderBar/components/SettingDrawer/segment-views/Watermark.tsx
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 36f089b4..e61e4e61 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,13 @@
# CHANGE LOG
+## 5.0.3
+
+个性化配置能力再次提升。
+
+## Feats
+
+- `SettingDrawer` 组件重构
+
## 5.0.2
## Feats
diff --git a/package.json b/package.json
index 88d8e35a..40d74af6 100755
--- a/package.json
+++ b/package.json
@@ -1,7 +1,7 @@
{
"name": "ray-template",
"private": false,
- "version": "5.0.2",
+ "version": "5.0.3",
"type": "module",
"engines": {
"node": "^18.0.0 || >=20.0.0",
diff --git a/src/app-components/provider/AppWatermarkProvider/index.tsx b/src/app-components/provider/AppWatermarkProvider/index.tsx
index b068dd9b..1e4c12b1 100644
--- a/src/app-components/provider/AppWatermarkProvider/index.tsx
+++ b/src/app-components/provider/AppWatermarkProvider/index.tsx
@@ -26,7 +26,7 @@ export default defineComponent({
const { getWatermarkConfig, getWatermarkSwitch } = this
return getWatermarkSwitch ? (
-
+
) : null
},
})
diff --git a/src/app-config/design-config.ts b/src/app-config/design-config.ts
index 34eb9a21..7d5df677 100644
--- a/src/app-config/design-config.ts
+++ b/src/app-config/design-config.ts
@@ -11,7 +11,6 @@ export const APP_THEME: AppTheme = {
'#3f9eff',
'#ff42bc',
'#ee4f12',
- '#a6e4f7',
'#dbcb02',
'#18A058',
],
diff --git a/src/layout/components/Menu/index.tsx b/src/layout/components/Menu/index.tsx
index db9537b2..4745f5e3 100644
--- a/src/layout/components/Menu/index.tsx
+++ b/src/layout/components/Menu/index.tsx
@@ -79,7 +79,8 @@ export default defineComponent({
collapseMode={getMenuConfig.value.collapsedMode}
collapsedWidth={getMenuConfig.value.collapsedWidth}
onUpdateCollapsed={collapsedMenu.bind(this)}
- nativeScrollbar={false}
+ width={getMenuConfig.value.menuWidth}
+ nativeScrollbar={getMenuConfig.value.nativeScrollbar}
ref={LAYOUT_SIDER_REF}
collapsed={getCollapsed.value}
onExpand={() => {
@@ -88,6 +89,7 @@ export default defineComponent({
onCollapse={() => {
updateMenuState('collapsed', true)
}}
+ inverted={getMenuConfig.value.inverted}
>
{getMenuConfig.value.menuSiderBarLogo ? (
@@ -107,6 +109,7 @@ export default defineComponent({
}}
accordion={getMenuConfig.value.accordion}
iconSize={getMenuConfig.value.iconSize}
+ inverted={getMenuConfig.value.inverted}
/>
)
diff --git a/src/layout/components/SiderBar/components/SettingDrawer/constant.ts b/src/layout/components/SiderBar/components/SettingDrawer/constant.ts
index 37acf693..5f32e799 100644
--- a/src/layout/components/SiderBar/components/SettingDrawer/constant.ts
+++ b/src/layout/components/SiderBar/components/SettingDrawer/constant.ts
@@ -1,11 +1,30 @@
import type { SettingState } from '@/store/modules/setting/types'
+import type { InjectionKey, Reactive } from 'vue'
+import type { DebouncedFunc } from 'lodash-es'
-export const defaultSettingConfig: Partial = {
+type OmitKeys =
+ | 'contentTransition'
+ | 'watermarkSwitch'
+ | 'keepAliveConfig'
+ | 'menuConfig'
+ | 'menuTagSwitch'
+ | 'breadcrumbSwitch'
+ | 'copyrightSwitch'
+ | 'drawerPlacement'
+ | 'colorWeakness'
+ | 'watermarkConfig'
+ | 'dynamicDocumentTitle'
+
+interface Config extends Pick {}
+
+// SettingDrawer 默认配置系统配置项
+const defaultSettingConfig: Readonly> = {
contentTransition: 'scale',
watermarkSwitch: false,
keepAliveConfig: {
maxKeepAliveLength: 10,
setupKeepAlive: true,
+ keepAliveExclude: [],
},
menuConfig: {
collapsedWidth: 64,
@@ -15,9 +34,55 @@ export const defaultSettingConfig: Partial = {
accordion: false,
menuSiderBarLogo: true,
iconSize: 16,
+ menuWidth: 272,
+ inverted: false,
+ nativeScrollbar: false,
},
menuTagSwitch: true,
breadcrumbSwitch: true,
copyrightSwitch: true,
drawerPlacement: 'right',
+ colorWeakness: false,
+ watermarkConfig: {
+ content: 'Trying be better~',
+ fontSize: 16,
+ lineHeight: 16,
+ width: 384,
+ height: 384,
+ xOffset: 12,
+ yOffset: 60,
+ rotate: -15,
+ xGap: 0,
+ yGap: 0,
+ cross: true,
+ },
+ dynamicDocumentTitle: true,
}
+
+/**
+ *
+ * @description
+ * 获取默认配置。
+ */
+export const getDefaultSettingConfig = (): Partial => {
+ return defaultSettingConfig
+}
+
+/**
+ *
+ * @param config 配置项
+ *
+ * @description
+ * 更新默认配置。
+ */
+export const updateDefaultSettingConfig = (config: Partial) => {
+ Object.assign(defaultSettingConfig, config)
+}
+
+interface SettingDrawerInjectKey extends SettingState {
+ throttleSetupAppMenu: DebouncedFunc<() => Promise>
+}
+
+export const SETTING_DRAWER_INJECT_KEY: Reactive<
+ InjectionKey>
+> = Symbol('segmentDrawer')
diff --git a/src/layout/components/SiderBar/components/SettingDrawer/index.scss b/src/layout/components/SiderBar/components/SettingDrawer/index.scss
index 760db0c1..088ec87e 100644
--- a/src/layout/components/SiderBar/components/SettingDrawer/index.scss
+++ b/src/layout/components/SiderBar/components/SettingDrawer/index.scss
@@ -1,8 +1,3 @@
-.setting-drawer__space {
- width: 100%;
-
- & .n-descriptions-table-content {
- display: flex !important;
- justify-content: space-between;
- }
+.n-form.setting-drawer__overrides-form .n-form-item .n-form-item-blank {
+ justify-content: flex-end;
}
diff --git a/src/layout/components/SiderBar/components/SettingDrawer/index.tsx b/src/layout/components/SiderBar/components/SettingDrawer/index.tsx
index e9dc0862..d1995eaa 100644
--- a/src/layout/components/SiderBar/components/SettingDrawer/index.tsx
+++ b/src/layout/components/SiderBar/components/SettingDrawer/index.tsx
@@ -3,50 +3,30 @@ import './index.scss'
import {
NDrawer,
NDrawerContent,
- NDivider,
NFlex,
- NSwitch,
- NColorPicker,
- NDescriptions,
- NDescriptionsItem,
- NSelect,
- NInputNumber,
- NFormItem,
- NForm,
NButton,
- NText,
- NTooltip,
+ NTabs,
+ NTabPane,
} from 'naive-ui'
-import ThemeSegment from './components/ThemeSegment'
import { RIcon } from '@/components'
+import SegmentViewsAppearance from './segment-views/Appearance'
+import SegmentViewsCommon from './segment-views/Common'
+import SegmentViewsWatermark from './segment-views/Watermark'
+import SegmentViewsCustomMenu from './segment-views/CustomMenu'
-import { APP_THEME, CONTENT_TRANSITION_OPTIONS } from '@/app-config'
import { useSettingGetters, useSettingActions, useMenuActions } from '@/store'
-import { defaultSettingConfig } from './constant'
+import { getDefaultSettingConfig, SETTING_DRAWER_INJECT_KEY } from './constant'
import { forIn, throttle } from 'lodash-es'
+import { drawerProps } from 'naive-ui'
+import { useModal } from '@/components'
-import type { PropType } from 'vue'
-import type { Placement } from '@/types'
import type { SettingState } from '@/store/modules/setting/types'
export default defineComponent({
name: 'SettingDrawer',
- props: {
- show: {
- type: Boolean,
- default: false,
- },
- placement: {
- type: String as PropType,
- default: 'right',
- },
- width: {
- type: Number,
- default: 280,
- },
- },
- emits: ['update:show'],
- setup(props, { emit }) {
+ props: drawerProps,
+ setup() {
+ const { create: createModal } = useModal()
const { changePrimaryColor, updateSettingState } = useSettingActions()
const {
getAppTheme,
@@ -59,296 +39,94 @@ export default defineComponent({
getKeepAliveConfig,
getMenuConfig,
getDrawerPlacement,
+ getColorWeakness,
+ getWatermarkConfig,
+ getDynamicDocumentTitle,
} = useSettingGetters()
const { setupAppMenu } = useMenuActions()
-
- const modelShow = computed({
- get: () => props.show,
- set: (bool) => {
- emit('update:show', bool)
- },
- })
- // 为了方便管理多个 computed,因为 computed 不能被逆向修改
- const modelReactive = computed({
- get: () => {
- return {
- getMenuTagSwitch: getMenuTagSwitch.value,
- getBreadcrumbSwitch: getBreadcrumbSwitch.value,
- getCopyrightSwitch: getCopyrightSwitch.value,
- getContentTransition: getContentTransition.value,
- getWatermarkSwitch: getWatermarkSwitch.value,
- getKeepAliveConfig: getKeepAliveConfig.value,
- getMenuConfig: getMenuConfig.value,
- getDrawerPlacement: getDrawerPlacement.value,
- }
- },
- set: (value) => {},
- })
-
const throttleSetupAppMenu = throttle(setupAppMenu, 300)
+ const modelReactive = reactive({
+ menuTagSwitch: getMenuTagSwitch.value,
+ breadcrumbSwitch: getBreadcrumbSwitch.value,
+ copyrightSwitch: getCopyrightSwitch.value,
+ contentTransition: getContentTransition.value,
+ watermarkSwitch: getWatermarkSwitch.value,
+ keepAliveConfig: getKeepAliveConfig.value,
+ menuConfig: getMenuConfig.value,
+ drawerPlacement: getDrawerPlacement.value,
+ colorWeakness: getColorWeakness.value,
+ primaryColorOverride: getPrimaryColorOverride.value,
+ watermarkConfig: getWatermarkConfig.value,
+ dynamicDocumentTitle: getDynamicDocumentTitle.value,
+ throttleSetupAppMenu,
+ })
const defaultSettingBtnClick = () => {
- forIn(defaultSettingConfig, (value, key) => {
- updateSettingState(key as keyof SettingState, value)
- })
+ createModal({
+ preset: 'dialog',
+ title: '恢复默认配置',
+ type: 'warning',
+ content: '点击【确认初始化】按钮会恢复默认系统配置,是否继续?',
+ positiveText: '确认初始化',
+ negativeText: '取消',
+ onPositiveClick: () => {
+ forIn(getDefaultSettingConfig(), (value, key) => {
+ modelReactive[key] = value
- throttleSetupAppMenu()
+ updateSettingState(key as keyof SettingState, value)
+ })
+
+ throttleSetupAppMenu()
+ },
+ })
}
+ provide(SETTING_DRAWER_INJECT_KEY, modelReactive)
+
return {
- modelShow,
changePrimaryColor,
getAppTheme,
getPrimaryColorOverride,
updateSettingState,
modelReactive,
defaultSettingBtnClick,
- throttleSetupAppMenu,
}
},
render() {
- const {
- $t,
- changePrimaryColor,
- updateSettingState,
- defaultSettingBtnClick,
- throttleSetupAppMenu,
- } = this
+ const { defaultSettingBtnClick, $props } = this
+ const { trapFocus, autoFocus, nativeScrollbar, ...restProps } = $props
return (
-
-
-
-
- {$t('headerSettingOptions.ThemeOptions.Title')}
-
-
-
- {$t('headerSettingOptions.ThemeOptions.PrimaryColorConfig')}
-
-
-
- {$t('headerSettingOptions.ContentTransition')}
-
- {
- updateSettingState('contentTransition', value)
- }}
- />
- 抽屉位置
- {
- updateSettingState('drawerPlacement', value)
- }}
- />
- 系统设置
-
-
-
- updateSettingState('menuConfig', {
- menuSiderBarLogo: bool,
- })
- }
- />
-
-
-
- updateSettingState('menuConfig', {
- accordion: bool,
- })
- }
- />
-
-
-
- updateSettingState('keepAliveConfig', {
- setupKeepAlive: bool,
- })
- }
- />
-
-
-
- updateSettingState('menuTagSwitch', bool)
- }
- />
-
-
-
- updateSettingState('breadcrumbSwitch', bool)
- }
- />
-
-
-
- updateSettingState('watermarkSwitch', bool)
- }
- />
-
-
-
- updateSettingState('copyrightSwitch', bool)
- }
- />
-
-
-
-
-
+
+
+ {{
+ default: () => (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ),
+ footer: () => (
+
+
{{
- trigger: () => ,
- default: () => '菜单渲染是一个复杂、耗时的操作,请手动更新',
- }}
-
- 菜单样式
-
-
-
-
- {
- if (value !== null) {
- updateSettingState('menuConfig', {
- collapsedIndent: value,
- })
- }
- }}
- />
-
-
- {
- if (value !== null) {
- updateSettingState('menuConfig', {
- iconSize: value,
- })
- }
- }}
- />
-
-
- {
- if (value !== null) {
- updateSettingState('menuConfig', {
- collapsedIconSize: value,
- })
- }
- }}
- />
-
-
- {
- if (value !== null) {
- updateSettingState('menuConfig', {
- collapsedWidth: value,
- })
- }
- }}
- />
-
-
-
- {{
- icon: () => ,
- default: () => '点击刷新',
+ icon: () => ,
+ default: () => '初始化配置',
}}
-
-
-
-
-
- {{
- trigger: () => ,
- default: () => '当设置为【0】时,缓存将会失效',
- }}
-
- 最大缓存数
-
-
- 操作
-
-
- 清除设置
-
-
-
+ ),
+ }}
)
diff --git a/src/layout/components/SiderBar/components/SettingDrawer/segment-views/Appearance.tsx b/src/layout/components/SiderBar/components/SettingDrawer/segment-views/Appearance.tsx
new file mode 100644
index 00000000..bd776ab4
--- /dev/null
+++ b/src/layout/components/SiderBar/components/SettingDrawer/segment-views/Appearance.tsx
@@ -0,0 +1,117 @@
+import {
+ NFlex,
+ NColorPicker,
+ NFormItem,
+ NDivider,
+ NSelect,
+ NSwitch,
+ NForm,
+} from 'naive-ui'
+import ThemeSegment from '../components/ThemeSegment'
+
+import { SETTING_DRAWER_INJECT_KEY } from '../constant'
+import { APP_THEME, CONTENT_TRANSITION_OPTIONS } from '@/app-config'
+import { useSettingActions } from '@/store'
+
+export default defineComponent({
+ name: 'SegmentViewsAppearance',
+ setup() {
+ const model = inject(SETTING_DRAWER_INJECT_KEY, {})
+ const { changePrimaryColor, updateSettingState, toggleColorWeakness } =
+ useSettingActions()
+
+ return {
+ toggleColorWeakness,
+ model,
+ changePrimaryColor,
+ updateSettingState,
+ }
+ },
+ render() {
+ const {
+ toggleColorWeakness,
+ model,
+ changePrimaryColor,
+ updateSettingState,
+ } = this
+
+ return (
+
+ 系统主题
+
+ 内置主题
+
+ 切换动画
+ {
+ updateSettingState('contentTransition', value)
+ }}
+ />
+ 配置入口出现位置
+ {
+ updateSettingState('drawerPlacement', value)
+ }}
+ />
+ 其他设置
+
+
+
+ updateSettingState('breadcrumbSwitch', bool)
+ }
+ />
+
+
+
+ updateSettingState('menuTagSwitch', bool)
+ }
+ />
+
+
+
+ updateSettingState('copyrightSwitch', bool)
+ }
+ />
+
+
+ {
+ updateSettingState('colorWeakness', bool)
+ toggleColorWeakness(bool)
+ }}
+ />
+
+
+
+ )
+ },
+})
diff --git a/src/layout/components/SiderBar/components/SettingDrawer/segment-views/Common.tsx b/src/layout/components/SiderBar/components/SettingDrawer/segment-views/Common.tsx
new file mode 100644
index 00000000..ff9aacbd
--- /dev/null
+++ b/src/layout/components/SiderBar/components/SettingDrawer/segment-views/Common.tsx
@@ -0,0 +1,98 @@
+import {
+ NFlex,
+ NFormItem,
+ NDivider,
+ NSwitch,
+ NForm,
+ NInputNumber,
+ NDynamicTags,
+} from 'naive-ui'
+import { RIcon } from '@/components'
+
+import { SETTING_DRAWER_INJECT_KEY } from '../constant'
+import { useSettingActions } from '@/store'
+
+export default defineComponent({
+ name: 'SegmentViewsCommon',
+ setup() {
+ const model = inject(SETTING_DRAWER_INJECT_KEY, {})
+ const { updateSettingState } = useSettingActions()
+
+ return {
+ model,
+ updateSettingState,
+ }
+ },
+ render() {
+ const { model, updateSettingState } = this
+
+ return (
+
+ 基础设置
+
+
+
+ updateSettingState('keepAliveConfig', {
+ setupKeepAlive: bool,
+ })
+ }
+ />
+
+
+
+ updateSettingState('dynamicDocumentTitle', bool)
+ }
+ />
+
+
+ 缓存设置
+
+ {
+ if (model.keepAliveConfig!.maxKeepAliveLength <= 0) {
+ return '设置为【0】时,缓存将会失效'
+ }
+
+ return ''
+ }).value
+ }
+ >
+
+ updateSettingState('keepAliveConfig', {
+ maxKeepAliveLength: val!,
+ })
+ }
+ />
+
+
+
+
+
+
+ )
+ },
+})
diff --git a/src/layout/components/SiderBar/components/SettingDrawer/segment-views/CustomMenu.tsx b/src/layout/components/SiderBar/components/SettingDrawer/segment-views/CustomMenu.tsx
new file mode 100644
index 00000000..095e2ac1
--- /dev/null
+++ b/src/layout/components/SiderBar/components/SettingDrawer/segment-views/CustomMenu.tsx
@@ -0,0 +1,167 @@
+import {
+ NFlex,
+ NFormItem,
+ NDivider,
+ NSwitch,
+ NForm,
+ NTooltip,
+ NText,
+ NInputNumber,
+ NButton,
+} from 'naive-ui'
+import { RIcon } from '@/components'
+
+import { SETTING_DRAWER_INJECT_KEY } from '../constant'
+import { useSettingActions } from '@/store'
+
+export default defineComponent({
+ name: 'SegmentViewsCustomMenu',
+ setup() {
+ const model = inject(SETTING_DRAWER_INJECT_KEY, {})
+ const { updateSettingState } = useSettingActions()
+
+ return {
+ model,
+ updateSettingState,
+ }
+ },
+ render() {
+ const { model, updateSettingState } = this
+
+ return (
+
+
+
+
+ {{
+ trigger: () => ,
+ default: () =>
+ '菜单更新是一个复杂、耗时的操作,请手动点击【更新菜单】按钮更新设置',
+ }}
+
+ 菜单样式
+
+
+
+
+
+ updateSettingState('menuConfig', {
+ collapsedIndent: value!,
+ })
+ }
+ />
+
+
+
+ updateSettingState('menuConfig', {
+ iconSize: value!,
+ })
+ }
+ />
+
+
+
+ updateSettingState('menuConfig', {
+ collapsedIconSize: value!,
+ })
+ }
+ />
+
+
+
+ updateSettingState('menuConfig', {
+ menuWidth: value!,
+ })
+ }
+ />
+
+
+
+ updateSettingState('menuConfig', {
+ collapsedWidth: value!,
+ })
+ }
+ />
+
+
+
+ 更新菜单
+
+
+
+ 其他设置
+
+
+
+ updateSettingState('menuConfig', {
+ inverted: bool,
+ })
+ }
+ />
+
+
+
+ updateSettingState('menuConfig', {
+ menuSiderBarLogo: bool,
+ })
+ }
+ />
+
+
+
+ updateSettingState('menuConfig', {
+ accordion: bool,
+ })
+ }
+ />
+
+
+
+ updateSettingState('menuConfig', {
+ nativeScrollbar: bool,
+ })
+ }
+ />
+
+
+
+ )
+ },
+})
diff --git a/src/layout/components/SiderBar/components/SettingDrawer/segment-views/Watermark.tsx b/src/layout/components/SiderBar/components/SettingDrawer/segment-views/Watermark.tsx
new file mode 100644
index 00000000..68d3c153
--- /dev/null
+++ b/src/layout/components/SiderBar/components/SettingDrawer/segment-views/Watermark.tsx
@@ -0,0 +1,184 @@
+import {
+ NFlex,
+ NFormItem,
+ NDivider,
+ NSwitch,
+ NForm,
+ NInputNumber,
+ NInput,
+} from 'naive-ui'
+
+import { SETTING_DRAWER_INJECT_KEY } from '../constant'
+import { useSettingActions } from '@/store'
+
+export default defineComponent({
+ name: 'SegmentViewsWatermark',
+ setup() {
+ const model = inject(SETTING_DRAWER_INJECT_KEY, {})
+ const { updateSettingState } = useSettingActions()
+
+ return {
+ model,
+ updateSettingState,
+ }
+ },
+ render() {
+ const { model, updateSettingState } = this
+
+ return (
+
+ 基础设置
+
+
+
+ updateSettingState('watermarkSwitch', bool)
+ }
+ />
+
+
+
+ updateSettingState('watermarkConfig', {
+ cross: val,
+ })
+ }
+ />
+
+
+ 个性化水印
+
+
+
+ updateSettingState('watermarkConfig', {
+ content: val,
+ })
+ }
+ />
+
+
+
+ updateSettingState('watermarkConfig', {
+ fontSize: val!,
+ })
+ }
+ />
+
+
+
+ updateSettingState('watermarkConfig', {
+ lineHeight: val!,
+ })
+ }
+ />
+
+
+
+ updateSettingState('watermarkConfig', {
+ width: val!,
+ })
+ }
+ />
+
+
+
+ updateSettingState('watermarkConfig', {
+ height: val!,
+ })
+ }
+ />
+
+
+
+ updateSettingState('watermarkConfig', {
+ xOffset: val!,
+ })
+ }
+ />
+
+
+
+ updateSettingState('watermarkConfig', {
+ xGap: val!,
+ })
+ }
+ />
+
+
+
+ updateSettingState('watermarkConfig', {
+ yOffset: val!,
+ })
+ }
+ />
+
+
+
+ updateSettingState('watermarkConfig', {
+ yGap: val!,
+ })
+ }
+ />
+
+
+
+ updateSettingState('watermarkConfig', {
+ rotate: val!,
+ })
+ }
+ />
+
+
+
+ )
+ },
+})
diff --git a/src/store/hooks/useSettingStore.ts b/src/store/hooks/useSettingStore.ts
index f3dbd3e8..d713d53d 100644
--- a/src/store/hooks/useSettingStore.ts
+++ b/src/store/hooks/useSettingStore.ts
@@ -105,6 +105,20 @@ export const useSettingGetters = () => {
*/
const getMenuConfig = computed(() => variable.menuConfig)
+ /**
+ *
+ * @description
+ * 获取是否启用色弱模式。
+ */
+ const getColorWeakness = computed(() => variable.colorWeakness)
+
+ /**
+ *
+ * @description
+ * 是否启用动态浏览器标题。
+ */
+ const getDynamicDocumentTitle = computed(() => variable.dynamicDocumentTitle)
+
return {
getDrawerPlacement,
getPrimaryColorOverride,
@@ -122,16 +136,23 @@ export const useSettingGetters = () => {
getKeepAliveConfig,
getMenuConfig,
getAppThemeStr,
+ getColorWeakness,
+ getDynamicDocumentTitle,
}
}
export const useSettingActions = () => {
- const { updateLocale, changePrimaryColor, updateSettingState } =
- piniaSettingStore()
+ const {
+ updateLocale,
+ changePrimaryColor,
+ updateSettingState,
+ toggleColorWeakness,
+ } = piniaSettingStore()
return {
updateLocale,
changePrimaryColor,
updateSettingState,
+ toggleColorWeakness,
}
}
diff --git a/src/store/modules/menu/utils.ts b/src/store/modules/menu/utils.ts
index 06e15668..87bbfce1 100644
--- a/src/store/modules/menu/utils.ts
+++ b/src/store/modules/menu/utils.ts
@@ -109,6 +109,12 @@ export const parseAndFindMatchingNodes = (
* 会自动拼接 sideBarLogo.title。
*/
export const updateDocumentTitle = (option: AppMenuOption) => {
+ const { dynamicDocumentTitle } = piniaSettingStore()
+
+ if (!dynamicDocumentTitle) {
+ return
+ }
+
const { breadcrumbLabel } = option
if (!breadcrumbLabel) {
diff --git a/src/store/modules/setting/index.ts b/src/store/modules/setting/index.ts
index 7cc3f8a2..4642cdcf 100644
--- a/src/store/modules/setting/index.ts
+++ b/src/store/modules/setting/index.ts
@@ -1,5 +1,5 @@
import { getAppDefaultLanguage } from '@/locales/utils'
-import { colorToRgba, setStorage, updateObjectValue } from '@/utils'
+import { colorToRgba, setStorage, updateObjectValue, setStyle } from '@/utils'
import { useI18n, useDayjs } from '@/hooks'
import { APP_CATCH_KEY, APP_THEME } from '@/app-config'
@@ -52,8 +52,11 @@ export const piniaSettingStore = defineStore(
width: 384,
height: 384,
xOffset: 12,
+ xGap: 0,
+ yGap: 0,
yOffset: 60,
rotate: -15,
+ cross: true,
},
// 根路由信息
appRootRoute: {
@@ -82,7 +85,14 @@ export const piniaSettingStore = defineStore(
accordion: false,
menuSiderBarLogo: true,
iconSize: 16,
+ menuWidth: 272,
+ inverted: false,
+ nativeScrollbar: false,
},
+ // 色弱模式
+ colorWeakness: false,
+ // 动态标题
+ dynamicDocumentTitle: true,
})
// 修改当前语言
@@ -125,7 +135,6 @@ export const piniaSettingStore = defineStore(
*
* @description
* 更新 settingState 的值,如果 key 不存在与 settingState 中,则不会更新。
- * 但是不论是否更新成功,都会执行回调函数。
*
* @example
* updateSettingState('drawerPlacement', 'left')
@@ -143,39 +152,49 @@ export const piniaSettingStore = defineStore(
updateObjectValue(settingState, key, value, cb)
}
+ const toggleColorWeakness = (bool: boolean) => {
+ const html = document.documentElement
+
+ updateSettingState('colorWeakness', bool)
+ setStyle(html, {
+ filter: bool ? 'invert(100%)' : '',
+ })
+ }
+
/**
*
- * 初始化合并自定义主题色
- * 该方法会在初始化时执行一次,之后会在切换主题色时执行
+ * @description
+ * 初始化合并自定义主题色。
+ * 该方法会在初始化时执行一次,之后会在切换主题色时执行。
*/
- watch(
- () => settingState.appTheme,
- (ndata) => {
- ndata
- ? (settingState.primaryColorOverride = Object.assign(
- {},
- settingState.primaryColorOverride,
- APP_THEME.appNaiveUIThemeOverrides.dark,
- APP_THEME.appNaiveUIThemeOverridesCommon.dark,
- ))
- : (settingState.primaryColorOverride = Object.assign(
- {},
- settingState.primaryColorOverride,
- APP_THEME.appNaiveUIThemeOverrides.light,
- APP_THEME.appNaiveUIThemeOverridesCommon.light,
- ))
- },
- {
- immediate: true,
- once: true,
- },
- )
+ watchEffect(() => {
+ settingState.appTheme
+ ? (settingState.primaryColorOverride = Object.assign(
+ {},
+ settingState.primaryColorOverride,
+ APP_THEME.appNaiveUIThemeOverrides.dark,
+ APP_THEME.appNaiveUIThemeOverridesCommon.dark,
+ ))
+ : (settingState.primaryColorOverride = Object.assign(
+ {},
+ settingState.primaryColorOverride,
+ APP_THEME.appNaiveUIThemeOverrides.light,
+ APP_THEME.appNaiveUIThemeOverridesCommon.light,
+ ))
+
+ toggleColorWeakness(settingState.colorWeakness)
+
+ if (!settingState.dynamicDocumentTitle) {
+ document.title = settingState.sideBarLogo?.title || 'Ray Template'
+ }
+ })
return {
...toRefs(settingState),
updateLocale,
changePrimaryColor,
updateSettingState,
+ toggleColorWeakness,
}
},
{
diff --git a/src/store/modules/setting/types.ts b/src/store/modules/setting/types.ts
index a136b668..c3278357 100644
--- a/src/store/modules/setting/types.ts
+++ b/src/store/modules/setting/types.ts
@@ -14,7 +14,10 @@ export interface WatermarkConfig {
height: number
xOffset: number
yOffset: number
+ xGap: number
+ yGap: number
rotate: number
+ cross: boolean
}
export interface AppRootRoute {
@@ -70,4 +73,12 @@ export interface SettingState {
* accordion 手风琴模式
*/
menuConfig: AppMenuConfig
+ colorWeakness: boolean
+ /**
+ *
+ * @description
+ * 动态浏览器标题。
+ * 如果设置为 true,会在更新菜单时,自动取用当前菜单的标题作为浏览器标题。
+ */
+ dynamicDocumentTitle: boolean
}
diff --git a/src/types/modules/app-config.ts b/src/types/modules/app-config.ts
index fc35f67a..3873b2e0 100644
--- a/src/types/modules/app-config.ts
+++ b/src/types/modules/app-config.ts
@@ -10,11 +10,14 @@ export interface AppMenuConfig {
accordion: boolean
menuSiderBarLogo: boolean
iconSize: number
+ menuWidth: number
+ inverted: boolean
+ nativeScrollbar: boolean
}
export interface AppKeepAlive {
setupKeepAlive: boolean
- keepAliveExclude?: string[]
+ keepAliveExclude: string[]
maxKeepAliveLength: number
}
diff --git a/src/types/modules/helper.ts b/src/types/modules/helper.ts
index f97ba350..0b399b5b 100644
--- a/src/types/modules/helper.ts
+++ b/src/types/modules/helper.ts
@@ -2,7 +2,8 @@
/**
*
- * 从目标类型中挑选出符合条件的属性名
+ * @description
+ * 从目标类型中挑选出符合条件的属性名。
*
* @example
* ConditionalKeys<{ a: string, b: number }, string> // 'a'
@@ -15,7 +16,8 @@ export type ConditionalKeys = NonNullable<
/**
*
- * 从目标类型中排除符合条件的属性
+ * @description
+ * 从目标类型中排除符合条件的属性。
*
* @example
* ConditionalExclude<{ a: string, b: number }, string> // { b: number }
@@ -27,7 +29,8 @@ export type ConditionalExclude = Omit<
/**
*
- * 从目标类型中挑选出符合条件的属性
+ * @description
+ * 从目标类型中挑选出符合条件的属性。
*
* @example
* ConditionalPick<{ a: string, b: number }, string> // { a: string }
@@ -39,7 +42,8 @@ export type ConditionalPick = Pick<
/**
*
- * 声明一个任意类型的对象
+ * @description
+ * 声明一个任意类型的对象。
*
* @example
* const A: Recordable = { a: 1, b: [] }
@@ -48,7 +52,8 @@ export type Recordable = Record
/**
*
- * 获取目标类型的所有属性类型
+ * @description
+ * 获取目标类型的所有属性类型。
*
* @example
* ValueOf<{ a: string, b: number }> // string | number
@@ -57,7 +62,8 @@ export type ValueOf = T[keyof T]
/**
*
- * 将目标所有属性变为可修改
+ * @description
+ * 将目标所有属性变为可修改。
*
* @example
* Mutable<{ readonly a: string }> // { a: string }
@@ -68,7 +74,8 @@ export type Mutable = {
/**
*
- * 递归将目标所有属性变为可修改
+ * @description
+ * 递归将目标所有属性变为可修改。
*
* @example
* DeepMutable<{ readonly a: { readonly b: { readonly c: string } } }> // { a: { b: { c: string } } }
@@ -83,7 +90,8 @@ export type DeepMutable = {
/**
*
- * 获取 Promise 返回值类型
+ * @description
+ * 获取 Promise 返回值类型。
*
* @example
* ReturnPromiseType> // string
@@ -91,3 +99,17 @@ export type DeepMutable = {
*/
export type ReturnPromiseType> =
T extends Promise ? U : never
+
+/**
+ *
+ * @description
+ * 深度只读。
+ *
+ * @example
+ * DeepReadonly<{ a: { b: string } }> // { readonly a: { readonly b: string } }
+ */
+export type DeepReadonly = T extends object
+ ? {
+ readonly [P in keyof T]: DeepReadonly
+ }
+ : T