mirror of
https://github.com/XiaoDaiGua-Ray/ray-template.git
synced 2025-04-05 07:03:00 +08:00
version: v5.0.3
This commit is contained in:
parent
7783872ef6
commit
8f3969268a
@ -1,5 +1,13 @@
|
|||||||
# CHANGE LOG
|
# CHANGE LOG
|
||||||
|
|
||||||
|
## 5.0.3
|
||||||
|
|
||||||
|
个性化配置能力再次提升。
|
||||||
|
|
||||||
|
## Feats
|
||||||
|
|
||||||
|
- `SettingDrawer` 组件重构
|
||||||
|
|
||||||
## 5.0.2
|
## 5.0.2
|
||||||
|
|
||||||
## Feats
|
## Feats
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "ray-template",
|
"name": "ray-template",
|
||||||
"private": false,
|
"private": false,
|
||||||
"version": "5.0.2",
|
"version": "5.0.3",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^18.0.0 || >=20.0.0",
|
"node": "^18.0.0 || >=20.0.0",
|
||||||
|
@ -26,7 +26,7 @@ export default defineComponent({
|
|||||||
const { getWatermarkConfig, getWatermarkSwitch } = this
|
const { getWatermarkConfig, getWatermarkSwitch } = this
|
||||||
|
|
||||||
return getWatermarkSwitch ? (
|
return getWatermarkSwitch ? (
|
||||||
<NWatermark cross fullscreen {...getWatermarkConfig} />
|
<NWatermark {...getWatermarkConfig} fullscreen />
|
||||||
) : null
|
) : null
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
@ -11,7 +11,6 @@ export const APP_THEME: AppTheme = {
|
|||||||
'#3f9eff',
|
'#3f9eff',
|
||||||
'#ff42bc',
|
'#ff42bc',
|
||||||
'#ee4f12',
|
'#ee4f12',
|
||||||
'#a6e4f7',
|
|
||||||
'#dbcb02',
|
'#dbcb02',
|
||||||
'#18A058',
|
'#18A058',
|
||||||
],
|
],
|
||||||
|
@ -79,7 +79,8 @@ export default defineComponent({
|
|||||||
collapseMode={getMenuConfig.value.collapsedMode}
|
collapseMode={getMenuConfig.value.collapsedMode}
|
||||||
collapsedWidth={getMenuConfig.value.collapsedWidth}
|
collapsedWidth={getMenuConfig.value.collapsedWidth}
|
||||||
onUpdateCollapsed={collapsedMenu.bind(this)}
|
onUpdateCollapsed={collapsedMenu.bind(this)}
|
||||||
nativeScrollbar={false}
|
width={getMenuConfig.value.menuWidth}
|
||||||
|
nativeScrollbar={getMenuConfig.value.nativeScrollbar}
|
||||||
ref={LAYOUT_SIDER_REF}
|
ref={LAYOUT_SIDER_REF}
|
||||||
collapsed={getCollapsed.value}
|
collapsed={getCollapsed.value}
|
||||||
onExpand={() => {
|
onExpand={() => {
|
||||||
@ -88,6 +89,7 @@ export default defineComponent({
|
|||||||
onCollapse={() => {
|
onCollapse={() => {
|
||||||
updateMenuState('collapsed', true)
|
updateMenuState('collapsed', true)
|
||||||
}}
|
}}
|
||||||
|
inverted={getMenuConfig.value.inverted}
|
||||||
>
|
>
|
||||||
{getMenuConfig.value.menuSiderBarLogo ? (
|
{getMenuConfig.value.menuSiderBarLogo ? (
|
||||||
<SiderBarLogo collapsed={getCollapsed.value} />
|
<SiderBarLogo collapsed={getCollapsed.value} />
|
||||||
@ -107,6 +109,7 @@ export default defineComponent({
|
|||||||
}}
|
}}
|
||||||
accordion={getMenuConfig.value.accordion}
|
accordion={getMenuConfig.value.accordion}
|
||||||
iconSize={getMenuConfig.value.iconSize}
|
iconSize={getMenuConfig.value.iconSize}
|
||||||
|
inverted={getMenuConfig.value.inverted}
|
||||||
/>
|
/>
|
||||||
</NLayoutSider>
|
</NLayoutSider>
|
||||||
)
|
)
|
||||||
|
@ -1,11 +1,30 @@
|
|||||||
import type { SettingState } from '@/store/modules/setting/types'
|
import type { SettingState } from '@/store/modules/setting/types'
|
||||||
|
import type { InjectionKey, Reactive } from 'vue'
|
||||||
|
import type { DebouncedFunc } from 'lodash-es'
|
||||||
|
|
||||||
export const defaultSettingConfig: Partial<SettingState> = {
|
type OmitKeys =
|
||||||
|
| 'contentTransition'
|
||||||
|
| 'watermarkSwitch'
|
||||||
|
| 'keepAliveConfig'
|
||||||
|
| 'menuConfig'
|
||||||
|
| 'menuTagSwitch'
|
||||||
|
| 'breadcrumbSwitch'
|
||||||
|
| 'copyrightSwitch'
|
||||||
|
| 'drawerPlacement'
|
||||||
|
| 'colorWeakness'
|
||||||
|
| 'watermarkConfig'
|
||||||
|
| 'dynamicDocumentTitle'
|
||||||
|
|
||||||
|
interface Config extends Pick<SettingState, OmitKeys> {}
|
||||||
|
|
||||||
|
// SettingDrawer 默认配置系统配置项
|
||||||
|
const defaultSettingConfig: Readonly<Partial<Config>> = {
|
||||||
contentTransition: 'scale',
|
contentTransition: 'scale',
|
||||||
watermarkSwitch: false,
|
watermarkSwitch: false,
|
||||||
keepAliveConfig: {
|
keepAliveConfig: {
|
||||||
maxKeepAliveLength: 10,
|
maxKeepAliveLength: 10,
|
||||||
setupKeepAlive: true,
|
setupKeepAlive: true,
|
||||||
|
keepAliveExclude: [],
|
||||||
},
|
},
|
||||||
menuConfig: {
|
menuConfig: {
|
||||||
collapsedWidth: 64,
|
collapsedWidth: 64,
|
||||||
@ -15,9 +34,55 @@ export const defaultSettingConfig: Partial<SettingState> = {
|
|||||||
accordion: false,
|
accordion: false,
|
||||||
menuSiderBarLogo: true,
|
menuSiderBarLogo: true,
|
||||||
iconSize: 16,
|
iconSize: 16,
|
||||||
|
menuWidth: 272,
|
||||||
|
inverted: false,
|
||||||
|
nativeScrollbar: false,
|
||||||
},
|
},
|
||||||
menuTagSwitch: true,
|
menuTagSwitch: true,
|
||||||
breadcrumbSwitch: true,
|
breadcrumbSwitch: true,
|
||||||
copyrightSwitch: true,
|
copyrightSwitch: true,
|
||||||
drawerPlacement: 'right',
|
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<Config> => {
|
||||||
|
return defaultSettingConfig
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param config 配置项
|
||||||
|
*
|
||||||
|
* @description
|
||||||
|
* 更新默认配置。
|
||||||
|
*/
|
||||||
|
export const updateDefaultSettingConfig = (config: Partial<SettingState>) => {
|
||||||
|
Object.assign(defaultSettingConfig, config)
|
||||||
|
}
|
||||||
|
|
||||||
|
interface SettingDrawerInjectKey extends SettingState {
|
||||||
|
throttleSetupAppMenu: DebouncedFunc<() => Promise<void>>
|
||||||
|
}
|
||||||
|
|
||||||
|
export const SETTING_DRAWER_INJECT_KEY: Reactive<
|
||||||
|
InjectionKey<Partial<SettingDrawerInjectKey>>
|
||||||
|
> = Symbol('segmentDrawer')
|
||||||
|
@ -1,8 +1,3 @@
|
|||||||
.setting-drawer__space {
|
.n-form.setting-drawer__overrides-form .n-form-item .n-form-item-blank {
|
||||||
width: 100%;
|
justify-content: flex-end;
|
||||||
|
|
||||||
& .n-descriptions-table-content {
|
|
||||||
display: flex !important;
|
|
||||||
justify-content: space-between;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -3,50 +3,30 @@ import './index.scss'
|
|||||||
import {
|
import {
|
||||||
NDrawer,
|
NDrawer,
|
||||||
NDrawerContent,
|
NDrawerContent,
|
||||||
NDivider,
|
|
||||||
NFlex,
|
NFlex,
|
||||||
NSwitch,
|
|
||||||
NColorPicker,
|
|
||||||
NDescriptions,
|
|
||||||
NDescriptionsItem,
|
|
||||||
NSelect,
|
|
||||||
NInputNumber,
|
|
||||||
NFormItem,
|
|
||||||
NForm,
|
|
||||||
NButton,
|
NButton,
|
||||||
NText,
|
NTabs,
|
||||||
NTooltip,
|
NTabPane,
|
||||||
} from 'naive-ui'
|
} from 'naive-ui'
|
||||||
import ThemeSegment from './components/ThemeSegment'
|
|
||||||
import { RIcon } from '@/components'
|
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 { useSettingGetters, useSettingActions, useMenuActions } from '@/store'
|
||||||
import { defaultSettingConfig } from './constant'
|
import { getDefaultSettingConfig, SETTING_DRAWER_INJECT_KEY } from './constant'
|
||||||
import { forIn, throttle } from 'lodash-es'
|
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'
|
import type { SettingState } from '@/store/modules/setting/types'
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: 'SettingDrawer',
|
name: 'SettingDrawer',
|
||||||
props: {
|
props: drawerProps,
|
||||||
show: {
|
setup() {
|
||||||
type: Boolean,
|
const { create: createModal } = useModal()
|
||||||
default: false,
|
|
||||||
},
|
|
||||||
placement: {
|
|
||||||
type: String as PropType<Placement>,
|
|
||||||
default: 'right',
|
|
||||||
},
|
|
||||||
width: {
|
|
||||||
type: Number,
|
|
||||||
default: 280,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
emits: ['update:show'],
|
|
||||||
setup(props, { emit }) {
|
|
||||||
const { changePrimaryColor, updateSettingState } = useSettingActions()
|
const { changePrimaryColor, updateSettingState } = useSettingActions()
|
||||||
const {
|
const {
|
||||||
getAppTheme,
|
getAppTheme,
|
||||||
@ -59,296 +39,94 @@ export default defineComponent({
|
|||||||
getKeepAliveConfig,
|
getKeepAliveConfig,
|
||||||
getMenuConfig,
|
getMenuConfig,
|
||||||
getDrawerPlacement,
|
getDrawerPlacement,
|
||||||
|
getColorWeakness,
|
||||||
|
getWatermarkConfig,
|
||||||
|
getDynamicDocumentTitle,
|
||||||
} = useSettingGetters()
|
} = useSettingGetters()
|
||||||
const { setupAppMenu } = useMenuActions()
|
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 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 = () => {
|
const defaultSettingBtnClick = () => {
|
||||||
forIn(defaultSettingConfig, (value, key) => {
|
createModal({
|
||||||
updateSettingState(key as keyof SettingState, value)
|
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 {
|
return {
|
||||||
modelShow,
|
|
||||||
changePrimaryColor,
|
changePrimaryColor,
|
||||||
getAppTheme,
|
getAppTheme,
|
||||||
getPrimaryColorOverride,
|
getPrimaryColorOverride,
|
||||||
updateSettingState,
|
updateSettingState,
|
||||||
modelReactive,
|
modelReactive,
|
||||||
defaultSettingBtnClick,
|
defaultSettingBtnClick,
|
||||||
throttleSetupAppMenu,
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
render() {
|
render() {
|
||||||
const {
|
const { defaultSettingBtnClick, $props } = this
|
||||||
$t,
|
const { trapFocus, autoFocus, nativeScrollbar, ...restProps } = $props
|
||||||
changePrimaryColor,
|
|
||||||
updateSettingState,
|
|
||||||
defaultSettingBtnClick,
|
|
||||||
throttleSetupAppMenu,
|
|
||||||
} = this
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<NDrawer
|
<NDrawer {...restProps} trapFocus={false} autoFocus={false} width={320}>
|
||||||
v-model:show={this.modelShow}
|
<NDrawerContent title="个性化配置" closable>
|
||||||
placement={this.placement}
|
{{
|
||||||
width={this.width}
|
default: () => (
|
||||||
trapFocus={false}
|
<NTabs type="bar" animated defaultValue="appearance">
|
||||||
autoFocus={false}
|
<NTabPane name="appearance" tab="外观">
|
||||||
>
|
<SegmentViewsAppearance />
|
||||||
<NDrawerContent title="系统配置">
|
</NTabPane>
|
||||||
<NFlex class="setting-drawer__space" vertical>
|
<NTabPane name="menu" tab="菜单">
|
||||||
<NDivider titlePlacement="center">
|
<SegmentViewsCustomMenu />
|
||||||
{$t('headerSettingOptions.ThemeOptions.Title')}
|
</NTabPane>
|
||||||
</NDivider>
|
<NTabPane name="watermark" tab="水印">
|
||||||
<ThemeSegment />
|
<SegmentViewsWatermark />
|
||||||
<NDivider titlePlacement="center">
|
</NTabPane>
|
||||||
{$t('headerSettingOptions.ThemeOptions.PrimaryColorConfig')}
|
<NTabPane name="common" tab="通用">
|
||||||
</NDivider>
|
<SegmentViewsCommon />
|
||||||
<NColorPicker
|
</NTabPane>
|
||||||
swatches={APP_THEME.appThemeColors}
|
</NTabs>
|
||||||
v-model:value={this.getPrimaryColorOverride.common!.primaryColor}
|
),
|
||||||
onUpdateValue={changePrimaryColor.bind(this)}
|
footer: () => (
|
||||||
/>
|
<NFlex justify="flex-start">
|
||||||
<NDivider titlePlacement="center">
|
<NButton type="warning" onClick={defaultSettingBtnClick}>
|
||||||
{$t('headerSettingOptions.ContentTransition')}
|
|
||||||
</NDivider>
|
|
||||||
<NSelect
|
|
||||||
v-model:value={this.modelReactive.getContentTransition}
|
|
||||||
options={CONTENT_TRANSITION_OPTIONS}
|
|
||||||
onUpdateValue={(value) => {
|
|
||||||
updateSettingState('contentTransition', value)
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
<NDivider titlePlacement="center">抽屉位置</NDivider>
|
|
||||||
<NSelect
|
|
||||||
v-model:value={this.modelReactive.getDrawerPlacement}
|
|
||||||
options={[
|
|
||||||
{
|
|
||||||
label: '右边',
|
|
||||||
value: 'right',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: '左边',
|
|
||||||
value: 'left',
|
|
||||||
},
|
|
||||||
]}
|
|
||||||
onUpdateValue={(value) => {
|
|
||||||
updateSettingState('drawerPlacement', value)
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
<NDivider titlePlacement="center">系统设置</NDivider>
|
|
||||||
<NDescriptions labelPlacement="left" column={1}>
|
|
||||||
<NDescriptionsItem label="菜单页头">
|
|
||||||
<NSwitch
|
|
||||||
v-model:value={
|
|
||||||
this.modelReactive.getMenuConfig.menuSiderBarLogo
|
|
||||||
}
|
|
||||||
onUpdateValue={(bool: boolean) =>
|
|
||||||
updateSettingState('menuConfig', {
|
|
||||||
menuSiderBarLogo: bool,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
</NDescriptionsItem>
|
|
||||||
<NDescriptionsItem label="菜单手风琴">
|
|
||||||
<NSwitch
|
|
||||||
v-model:value={this.modelReactive.getMenuConfig.accordion}
|
|
||||||
onUpdateValue={(bool: boolean) =>
|
|
||||||
updateSettingState('menuConfig', {
|
|
||||||
accordion: bool,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
</NDescriptionsItem>
|
|
||||||
<NDescriptionsItem label="页面缓存">
|
|
||||||
<NSwitch
|
|
||||||
v-model:value={
|
|
||||||
this.modelReactive.getKeepAliveConfig.setupKeepAlive
|
|
||||||
}
|
|
||||||
onUpdateValue={(bool: boolean) =>
|
|
||||||
updateSettingState('keepAliveConfig', {
|
|
||||||
setupKeepAlive: bool,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
</NDescriptionsItem>
|
|
||||||
<NDescriptionsItem label="多标签">
|
|
||||||
<NSwitch
|
|
||||||
v-model:value={this.modelReactive.getMenuTagSwitch}
|
|
||||||
onUpdateValue={(bool: boolean) =>
|
|
||||||
updateSettingState('menuTagSwitch', bool)
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
</NDescriptionsItem>
|
|
||||||
<NDescriptionsItem label="面包屑">
|
|
||||||
<NSwitch
|
|
||||||
v-model:value={this.modelReactive.getBreadcrumbSwitch}
|
|
||||||
onUpdateValue={(bool: boolean) =>
|
|
||||||
updateSettingState('breadcrumbSwitch', bool)
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
</NDescriptionsItem>
|
|
||||||
<NDescriptionsItem label="水印">
|
|
||||||
<NSwitch
|
|
||||||
v-model:value={this.modelReactive.getWatermarkSwitch}
|
|
||||||
onUpdateValue={(bool: boolean) =>
|
|
||||||
updateSettingState('watermarkSwitch', bool)
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
</NDescriptionsItem>
|
|
||||||
<NDescriptionsItem label="页底信息">
|
|
||||||
<NSwitch
|
|
||||||
v-model:value={this.modelReactive.getCopyrightSwitch}
|
|
||||||
onUpdateValue={(bool: boolean) =>
|
|
||||||
updateSettingState('copyrightSwitch', bool)
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
</NDescriptionsItem>
|
|
||||||
</NDescriptions>
|
|
||||||
<NDivider titlePlacement="center">
|
|
||||||
<NFlex wrap={false} align="center" size={[4, 0]}>
|
|
||||||
<NTooltip placement="top" showArrow={false}>
|
|
||||||
{{
|
{{
|
||||||
trigger: () => <RIcon name="question" size="16" />,
|
icon: () => <RIcon name="reload" />,
|
||||||
default: () => '菜单渲染是一个复杂、耗时的操作,请手动更新',
|
default: () => '初始化配置',
|
||||||
}}
|
|
||||||
</NTooltip>
|
|
||||||
<NText>菜单样式</NText>
|
|
||||||
</NFlex>
|
|
||||||
</NDivider>
|
|
||||||
<NForm showFeedback={true} showRequireMark={false}>
|
|
||||||
<NFormItem label="每级菜单缩进">
|
|
||||||
<NInputNumber
|
|
||||||
v-model:value={
|
|
||||||
this.modelReactive.getMenuConfig.collapsedIndent
|
|
||||||
}
|
|
||||||
min={0}
|
|
||||||
precision={0}
|
|
||||||
onUpdateValue={(value) => {
|
|
||||||
if (value !== null) {
|
|
||||||
updateSettingState('menuConfig', {
|
|
||||||
collapsedIndent: value,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</NFormItem>
|
|
||||||
<NFormItem label="菜单图标尺寸">
|
|
||||||
<NInputNumber
|
|
||||||
v-model:value={this.modelReactive.getMenuConfig.iconSize}
|
|
||||||
min={0}
|
|
||||||
precision={0}
|
|
||||||
onUpdateValue={(value) => {
|
|
||||||
if (value !== null) {
|
|
||||||
updateSettingState('menuConfig', {
|
|
||||||
iconSize: value,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</NFormItem>
|
|
||||||
<NFormItem label="折叠菜单图标尺寸">
|
|
||||||
<NInputNumber
|
|
||||||
v-model:value={
|
|
||||||
this.modelReactive.getMenuConfig.collapsedIconSize
|
|
||||||
}
|
|
||||||
min={0}
|
|
||||||
precision={0}
|
|
||||||
onUpdateValue={(value) => {
|
|
||||||
if (value !== null) {
|
|
||||||
updateSettingState('menuConfig', {
|
|
||||||
collapsedIconSize: value,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</NFormItem>
|
|
||||||
<NFormItem label="折叠菜单宽度">
|
|
||||||
<NInputNumber
|
|
||||||
v-model:value={
|
|
||||||
this.modelReactive.getMenuConfig.collapsedWidth
|
|
||||||
}
|
|
||||||
min={0}
|
|
||||||
precision={0}
|
|
||||||
onUpdateValue={(value) => {
|
|
||||||
if (value !== null) {
|
|
||||||
updateSettingState('menuConfig', {
|
|
||||||
collapsedWidth: value,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</NFormItem>
|
|
||||||
<NFormItem showFeedback={false} showLabel={false}>
|
|
||||||
<NButton
|
|
||||||
onClick={throttleSetupAppMenu}
|
|
||||||
block
|
|
||||||
type="info"
|
|
||||||
secondary
|
|
||||||
>
|
|
||||||
{{
|
|
||||||
icon: () => <RIcon name="question" size="16" />,
|
|
||||||
default: () => '点击刷新',
|
|
||||||
}}
|
}}
|
||||||
</NButton>
|
</NButton>
|
||||||
</NFormItem>
|
|
||||||
</NForm>
|
|
||||||
<NDivider titlePlacement="center">
|
|
||||||
<NFlex wrap={false} align="center" size={[4, 0]}>
|
|
||||||
<NTooltip placement="top" showArrow={false}>
|
|
||||||
{{
|
|
||||||
trigger: () => <RIcon name="question" size="16" />,
|
|
||||||
default: () => '当设置为【0】时,缓存将会失效',
|
|
||||||
}}
|
|
||||||
</NTooltip>
|
|
||||||
<NText>最大缓存数</NText>
|
|
||||||
</NFlex>
|
</NFlex>
|
||||||
</NDivider>
|
),
|
||||||
<NInputNumber
|
}}
|
||||||
v-model:value={
|
|
||||||
this.modelReactive.getKeepAliveConfig.maxKeepAliveLength
|
|
||||||
}
|
|
||||||
showButton={true}
|
|
||||||
min={0}
|
|
||||||
max={100}
|
|
||||||
precision={0}
|
|
||||||
disabled={!this.modelReactive.getKeepAliveConfig.setupKeepAlive}
|
|
||||||
/>
|
|
||||||
<NDivider titlePlacement="center">操作</NDivider>
|
|
||||||
<NFlex>
|
|
||||||
<NButton type="primary" block onClick={defaultSettingBtnClick}>
|
|
||||||
清除设置
|
|
||||||
</NButton>
|
|
||||||
</NFlex>
|
|
||||||
</NFlex>
|
|
||||||
</NDrawerContent>
|
</NDrawerContent>
|
||||||
</NDrawer>
|
</NDrawer>
|
||||||
)
|
)
|
||||||
|
@ -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 (
|
||||||
|
<NFlex vertical style="width: 100%;" size={[0, 0]}>
|
||||||
|
<NDivider>系统主题</NDivider>
|
||||||
|
<ThemeSegment />
|
||||||
|
<NDivider>内置主题</NDivider>
|
||||||
|
<NColorPicker
|
||||||
|
showPreview
|
||||||
|
swatches={APP_THEME.appThemeColors}
|
||||||
|
v-model:value={model.primaryColorOverride!.common!.primaryColor}
|
||||||
|
onUpdateValue={changePrimaryColor.bind(this)}
|
||||||
|
/>
|
||||||
|
<NDivider>切换动画</NDivider>
|
||||||
|
<NSelect
|
||||||
|
v-model:value={model.contentTransition}
|
||||||
|
options={CONTENT_TRANSITION_OPTIONS}
|
||||||
|
onUpdateValue={(value) => {
|
||||||
|
updateSettingState('contentTransition', value)
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<NDivider>配置入口出现位置</NDivider>
|
||||||
|
<NSelect
|
||||||
|
v-model:value={model.drawerPlacement}
|
||||||
|
options={[
|
||||||
|
{
|
||||||
|
label: '右边',
|
||||||
|
value: 'right',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '左边',
|
||||||
|
value: 'left',
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
onUpdateValue={(value) => {
|
||||||
|
updateSettingState('drawerPlacement', value)
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<NDivider>其他设置</NDivider>
|
||||||
|
<NForm
|
||||||
|
labelPlacement="left"
|
||||||
|
class="setting-drawer__overrides-form"
|
||||||
|
showFeedback={false}
|
||||||
|
>
|
||||||
|
<NFormItem label="面包屑">
|
||||||
|
<NSwitch
|
||||||
|
v-model:value={model.breadcrumbSwitch}
|
||||||
|
onUpdateValue={(bool) =>
|
||||||
|
updateSettingState('breadcrumbSwitch', bool)
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</NFormItem>
|
||||||
|
<NFormItem label="标签页">
|
||||||
|
<NSwitch
|
||||||
|
v-model:value={model.menuTagSwitch}
|
||||||
|
onUpdateValue={(bool) =>
|
||||||
|
updateSettingState('menuTagSwitch', bool)
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</NFormItem>
|
||||||
|
<NFormItem label="页底信息">
|
||||||
|
<NSwitch
|
||||||
|
v-model:value={model.copyrightSwitch}
|
||||||
|
onUpdateValue={(bool) =>
|
||||||
|
updateSettingState('copyrightSwitch', bool)
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</NFormItem>
|
||||||
|
<NFormItem label="色弱模式">
|
||||||
|
<NSwitch
|
||||||
|
v-model:value={model.colorWeakness}
|
||||||
|
onUpdateValue={(bool) => {
|
||||||
|
updateSettingState('colorWeakness', bool)
|
||||||
|
toggleColorWeakness(bool)
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</NFormItem>
|
||||||
|
</NForm>
|
||||||
|
</NFlex>
|
||||||
|
)
|
||||||
|
},
|
||||||
|
})
|
@ -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 (
|
||||||
|
<NFlex vertical style="width: 100%;" size={[0, 0]}>
|
||||||
|
<NDivider>基础设置</NDivider>
|
||||||
|
<NForm
|
||||||
|
labelPlacement="left"
|
||||||
|
class="setting-drawer__overrides-form"
|
||||||
|
showFeedback={false}
|
||||||
|
>
|
||||||
|
<NFormItem label="页面缓存">
|
||||||
|
<NSwitch
|
||||||
|
v-model:value={model.keepAliveConfig!.setupKeepAlive}
|
||||||
|
onUpdateValue={(bool) =>
|
||||||
|
updateSettingState('keepAliveConfig', {
|
||||||
|
setupKeepAlive: bool,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</NFormItem>
|
||||||
|
<NFormItem label="动态浏览器标题">
|
||||||
|
<NSwitch
|
||||||
|
v-model:value={model.dynamicDocumentTitle}
|
||||||
|
onUpdateValue={(bool) =>
|
||||||
|
updateSettingState('dynamicDocumentTitle', bool)
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</NFormItem>
|
||||||
|
</NForm>
|
||||||
|
<NDivider>缓存设置</NDivider>
|
||||||
|
<NForm
|
||||||
|
labelPlacement="top"
|
||||||
|
showFeedback={true}
|
||||||
|
showRequireMark={false}
|
||||||
|
model={model.keepAliveConfig}
|
||||||
|
>
|
||||||
|
<NFormItem
|
||||||
|
label="最大缓存数"
|
||||||
|
feedback={
|
||||||
|
computed(() => {
|
||||||
|
if (model.keepAliveConfig!.maxKeepAliveLength <= 0) {
|
||||||
|
return '设置为【0】时,缓存将会失效'
|
||||||
|
}
|
||||||
|
|
||||||
|
return ''
|
||||||
|
}).value
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<NInputNumber
|
||||||
|
disabled={!model.keepAliveConfig!.setupKeepAlive}
|
||||||
|
v-model:value={model.keepAliveConfig!.maxKeepAliveLength}
|
||||||
|
min={0}
|
||||||
|
precision={0}
|
||||||
|
showButton={false}
|
||||||
|
onUpdateValue={(val) =>
|
||||||
|
updateSettingState('keepAliveConfig', {
|
||||||
|
maxKeepAliveLength: val!,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</NFormItem>
|
||||||
|
<NFormItem label="排除缓存">
|
||||||
|
<NDynamicTags
|
||||||
|
type="success"
|
||||||
|
v-model:value={model.keepAliveConfig!.keepAliveExclude}
|
||||||
|
/>
|
||||||
|
</NFormItem>
|
||||||
|
</NForm>
|
||||||
|
</NFlex>
|
||||||
|
)
|
||||||
|
},
|
||||||
|
})
|
@ -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 (
|
||||||
|
<NFlex vertical style="width: 100%;" size={[0, 0]}>
|
||||||
|
<NDivider titlePlacement="center">
|
||||||
|
<NFlex wrap={false} align="center" size={[4, 0]}>
|
||||||
|
<NTooltip placement="top" showArrow={false}>
|
||||||
|
{{
|
||||||
|
trigger: () => <RIcon name="question" size="16" />,
|
||||||
|
default: () =>
|
||||||
|
'菜单更新是一个复杂、耗时的操作,请手动点击【更新菜单】按钮更新设置',
|
||||||
|
}}
|
||||||
|
</NTooltip>
|
||||||
|
<NText>菜单样式</NText>
|
||||||
|
</NFlex>
|
||||||
|
</NDivider>
|
||||||
|
<NForm
|
||||||
|
showFeedback={true}
|
||||||
|
showRequireMark={false}
|
||||||
|
class="setting-drawer__overrides-form"
|
||||||
|
>
|
||||||
|
<NFormItem label="每级菜单缩进">
|
||||||
|
<NInputNumber
|
||||||
|
v-model:value={model.menuConfig!.collapsedIndent}
|
||||||
|
min={0}
|
||||||
|
precision={0}
|
||||||
|
onUpdateValue={(value) =>
|
||||||
|
updateSettingState('menuConfig', {
|
||||||
|
collapsedIndent: value!,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</NFormItem>
|
||||||
|
<NFormItem label="菜单图标尺寸">
|
||||||
|
<NInputNumber
|
||||||
|
v-model:value={model.menuConfig!.iconSize}
|
||||||
|
min={0}
|
||||||
|
precision={0}
|
||||||
|
onUpdateValue={(value) =>
|
||||||
|
updateSettingState('menuConfig', {
|
||||||
|
iconSize: value!,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</NFormItem>
|
||||||
|
<NFormItem label="折叠菜单图标尺寸">
|
||||||
|
<NInputNumber
|
||||||
|
v-model:value={model.menuConfig!.collapsedIconSize}
|
||||||
|
min={0}
|
||||||
|
precision={0}
|
||||||
|
onUpdateValue={(value) =>
|
||||||
|
updateSettingState('menuConfig', {
|
||||||
|
collapsedIconSize: value!,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</NFormItem>
|
||||||
|
<NFormItem label="菜单宽度">
|
||||||
|
<NInputNumber
|
||||||
|
v-model:value={model.menuConfig!.menuWidth}
|
||||||
|
min={0}
|
||||||
|
precision={0}
|
||||||
|
onUpdateValue={(value) =>
|
||||||
|
updateSettingState('menuConfig', {
|
||||||
|
menuWidth: value!,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</NFormItem>
|
||||||
|
<NFormItem label="折叠菜单宽度">
|
||||||
|
<NInputNumber
|
||||||
|
v-model:value={model.menuConfig!.collapsedWidth}
|
||||||
|
min={0}
|
||||||
|
precision={0}
|
||||||
|
onUpdateValue={(value) =>
|
||||||
|
updateSettingState('menuConfig', {
|
||||||
|
collapsedWidth: value!,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</NFormItem>
|
||||||
|
<NFormItem showFeedback={false} showLabel={false}>
|
||||||
|
<NButton onClick={model.throttleSetupAppMenu} block type="primary">
|
||||||
|
更新菜单
|
||||||
|
</NButton>
|
||||||
|
</NFormItem>
|
||||||
|
</NForm>
|
||||||
|
<NDivider>其他设置</NDivider>
|
||||||
|
<NForm
|
||||||
|
showFeedback={false}
|
||||||
|
showRequireMark={false}
|
||||||
|
class="setting-drawer__overrides-form"
|
||||||
|
labelPlacement="left"
|
||||||
|
>
|
||||||
|
<NFormItem label="反转色菜单">
|
||||||
|
<NSwitch
|
||||||
|
v-model:value={model.menuConfig!.inverted}
|
||||||
|
onUpdateValue={(bool) =>
|
||||||
|
updateSettingState('menuConfig', {
|
||||||
|
inverted: bool,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</NFormItem>
|
||||||
|
<NFormItem label="菜单标题">
|
||||||
|
<NSwitch
|
||||||
|
v-model:value={model.menuConfig!.menuSiderBarLogo}
|
||||||
|
onUpdateValue={(bool) =>
|
||||||
|
updateSettingState('menuConfig', {
|
||||||
|
menuSiderBarLogo: bool,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</NFormItem>
|
||||||
|
<NFormItem label="手风琴菜单">
|
||||||
|
<NSwitch
|
||||||
|
v-model:value={model.menuConfig!.accordion}
|
||||||
|
onUpdateValue={(bool) =>
|
||||||
|
updateSettingState('menuConfig', {
|
||||||
|
accordion: bool,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</NFormItem>
|
||||||
|
<NFormItem label="原生滚动条">
|
||||||
|
<NSwitch
|
||||||
|
v-model:value={model.menuConfig!.nativeScrollbar}
|
||||||
|
onUpdateValue={(bool) =>
|
||||||
|
updateSettingState('menuConfig', {
|
||||||
|
nativeScrollbar: bool,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</NFormItem>
|
||||||
|
</NForm>
|
||||||
|
</NFlex>
|
||||||
|
)
|
||||||
|
},
|
||||||
|
})
|
@ -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 (
|
||||||
|
<NFlex vertical style="width: 100%;" size={[0, 0]}>
|
||||||
|
<NDivider>基础设置</NDivider>
|
||||||
|
<NForm
|
||||||
|
showFeedback={false}
|
||||||
|
showRequireMark={false}
|
||||||
|
class="setting-drawer__overrides-form"
|
||||||
|
labelPlacement="left"
|
||||||
|
>
|
||||||
|
<NFormItem label="全屏水印">
|
||||||
|
<NSwitch
|
||||||
|
v-model:value={model.watermarkSwitch}
|
||||||
|
onUpdateValue={(bool) =>
|
||||||
|
updateSettingState('watermarkSwitch', bool)
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</NFormItem>
|
||||||
|
<NFormItem label="跨边界显示">
|
||||||
|
<NSwitch
|
||||||
|
v-model:value={model.watermarkConfig!.cross}
|
||||||
|
onUpdateValue={(val) =>
|
||||||
|
updateSettingState('watermarkConfig', {
|
||||||
|
cross: val,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</NFormItem>
|
||||||
|
</NForm>
|
||||||
|
<NDivider>个性化水印</NDivider>
|
||||||
|
<NForm
|
||||||
|
showFeedback={true}
|
||||||
|
showRequireMark={false}
|
||||||
|
class="setting-drawer__overrides-form"
|
||||||
|
>
|
||||||
|
<NFormItem label="水印内容">
|
||||||
|
<NInput
|
||||||
|
v-model:value={model.watermarkConfig!.content}
|
||||||
|
onUpdateValue={(val) =>
|
||||||
|
updateSettingState('watermarkConfig', {
|
||||||
|
content: val,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</NFormItem>
|
||||||
|
<NFormItem label="字体尺寸">
|
||||||
|
<NInputNumber
|
||||||
|
precision={0}
|
||||||
|
showButton={false}
|
||||||
|
v-model:value={model.watermarkConfig!.fontSize}
|
||||||
|
onUpdateValue={(val) =>
|
||||||
|
updateSettingState('watermarkConfig', {
|
||||||
|
fontSize: val!,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</NFormItem>
|
||||||
|
<NFormItem label="字体行高">
|
||||||
|
<NInputNumber
|
||||||
|
precision={0}
|
||||||
|
showButton={false}
|
||||||
|
v-model:value={model.watermarkConfig!.lineHeight}
|
||||||
|
onUpdateValue={(val) =>
|
||||||
|
updateSettingState('watermarkConfig', {
|
||||||
|
lineHeight: val!,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</NFormItem>
|
||||||
|
<NFormItem label="字体宽度">
|
||||||
|
<NInputNumber
|
||||||
|
precision={0}
|
||||||
|
showButton={false}
|
||||||
|
v-model:value={model.watermarkConfig!.width}
|
||||||
|
onUpdateValue={(val) =>
|
||||||
|
updateSettingState('watermarkConfig', {
|
||||||
|
width: val!,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</NFormItem>
|
||||||
|
<NFormItem label="字体高度">
|
||||||
|
<NInputNumber
|
||||||
|
precision={0}
|
||||||
|
showButton={false}
|
||||||
|
v-model:value={model.watermarkConfig!.height}
|
||||||
|
onUpdateValue={(val) =>
|
||||||
|
updateSettingState('watermarkConfig', {
|
||||||
|
height: val!,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</NFormItem>
|
||||||
|
<NFormItem label="x轴偏移">
|
||||||
|
<NInputNumber
|
||||||
|
precision={0}
|
||||||
|
showButton={false}
|
||||||
|
v-model:value={model.watermarkConfig!.xOffset}
|
||||||
|
onUpdateValue={(val) =>
|
||||||
|
updateSettingState('watermarkConfig', {
|
||||||
|
xOffset: val!,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</NFormItem>
|
||||||
|
<NFormItem label="x轴间隙">
|
||||||
|
<NInputNumber
|
||||||
|
precision={0}
|
||||||
|
showButton={false}
|
||||||
|
v-model:value={model.watermarkConfig!.xGap}
|
||||||
|
onUpdateValue={(val) =>
|
||||||
|
updateSettingState('watermarkConfig', {
|
||||||
|
xGap: val!,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</NFormItem>
|
||||||
|
<NFormItem label="y轴偏移">
|
||||||
|
<NInputNumber
|
||||||
|
precision={0}
|
||||||
|
showButton={false}
|
||||||
|
v-model:value={model.watermarkConfig!.yOffset}
|
||||||
|
onUpdateValue={(val) =>
|
||||||
|
updateSettingState('watermarkConfig', {
|
||||||
|
yOffset: val!,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</NFormItem>
|
||||||
|
<NFormItem label="y轴间隙">
|
||||||
|
<NInputNumber
|
||||||
|
precision={0}
|
||||||
|
showButton={false}
|
||||||
|
v-model:value={model.watermarkConfig!.yGap}
|
||||||
|
onUpdateValue={(val) =>
|
||||||
|
updateSettingState('watermarkConfig', {
|
||||||
|
yGap: val!,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</NFormItem>
|
||||||
|
<NFormItem label="旋转角度">
|
||||||
|
<NInputNumber
|
||||||
|
precision={0}
|
||||||
|
showButton={false}
|
||||||
|
v-model:value={model.watermarkConfig!.rotate}
|
||||||
|
onUpdateValue={(val) =>
|
||||||
|
updateSettingState('watermarkConfig', {
|
||||||
|
rotate: val!,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</NFormItem>
|
||||||
|
</NForm>
|
||||||
|
</NFlex>
|
||||||
|
)
|
||||||
|
},
|
||||||
|
})
|
@ -105,6 +105,20 @@ export const useSettingGetters = () => {
|
|||||||
*/
|
*/
|
||||||
const getMenuConfig = computed(() => variable.menuConfig)
|
const getMenuConfig = computed(() => variable.menuConfig)
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @description
|
||||||
|
* 获取是否启用色弱模式。
|
||||||
|
*/
|
||||||
|
const getColorWeakness = computed(() => variable.colorWeakness)
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @description
|
||||||
|
* 是否启用动态浏览器标题。
|
||||||
|
*/
|
||||||
|
const getDynamicDocumentTitle = computed(() => variable.dynamicDocumentTitle)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
getDrawerPlacement,
|
getDrawerPlacement,
|
||||||
getPrimaryColorOverride,
|
getPrimaryColorOverride,
|
||||||
@ -122,16 +136,23 @@ export const useSettingGetters = () => {
|
|||||||
getKeepAliveConfig,
|
getKeepAliveConfig,
|
||||||
getMenuConfig,
|
getMenuConfig,
|
||||||
getAppThemeStr,
|
getAppThemeStr,
|
||||||
|
getColorWeakness,
|
||||||
|
getDynamicDocumentTitle,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const useSettingActions = () => {
|
export const useSettingActions = () => {
|
||||||
const { updateLocale, changePrimaryColor, updateSettingState } =
|
const {
|
||||||
piniaSettingStore()
|
updateLocale,
|
||||||
|
changePrimaryColor,
|
||||||
|
updateSettingState,
|
||||||
|
toggleColorWeakness,
|
||||||
|
} = piniaSettingStore()
|
||||||
|
|
||||||
return {
|
return {
|
||||||
updateLocale,
|
updateLocale,
|
||||||
changePrimaryColor,
|
changePrimaryColor,
|
||||||
updateSettingState,
|
updateSettingState,
|
||||||
|
toggleColorWeakness,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -109,6 +109,12 @@ export const parseAndFindMatchingNodes = (
|
|||||||
* 会自动拼接 sideBarLogo.title。
|
* 会自动拼接 sideBarLogo.title。
|
||||||
*/
|
*/
|
||||||
export const updateDocumentTitle = (option: AppMenuOption) => {
|
export const updateDocumentTitle = (option: AppMenuOption) => {
|
||||||
|
const { dynamicDocumentTitle } = piniaSettingStore()
|
||||||
|
|
||||||
|
if (!dynamicDocumentTitle) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
const { breadcrumbLabel } = option
|
const { breadcrumbLabel } = option
|
||||||
|
|
||||||
if (!breadcrumbLabel) {
|
if (!breadcrumbLabel) {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { getAppDefaultLanguage } from '@/locales/utils'
|
import { getAppDefaultLanguage } from '@/locales/utils'
|
||||||
import { colorToRgba, setStorage, updateObjectValue } from '@/utils'
|
import { colorToRgba, setStorage, updateObjectValue, setStyle } from '@/utils'
|
||||||
import { useI18n, useDayjs } from '@/hooks'
|
import { useI18n, useDayjs } from '@/hooks'
|
||||||
import { APP_CATCH_KEY, APP_THEME } from '@/app-config'
|
import { APP_CATCH_KEY, APP_THEME } from '@/app-config'
|
||||||
|
|
||||||
@ -52,8 +52,11 @@ export const piniaSettingStore = defineStore(
|
|||||||
width: 384,
|
width: 384,
|
||||||
height: 384,
|
height: 384,
|
||||||
xOffset: 12,
|
xOffset: 12,
|
||||||
|
xGap: 0,
|
||||||
|
yGap: 0,
|
||||||
yOffset: 60,
|
yOffset: 60,
|
||||||
rotate: -15,
|
rotate: -15,
|
||||||
|
cross: true,
|
||||||
},
|
},
|
||||||
// 根路由信息
|
// 根路由信息
|
||||||
appRootRoute: {
|
appRootRoute: {
|
||||||
@ -82,7 +85,14 @@ export const piniaSettingStore = defineStore(
|
|||||||
accordion: false,
|
accordion: false,
|
||||||
menuSiderBarLogo: true,
|
menuSiderBarLogo: true,
|
||||||
iconSize: 16,
|
iconSize: 16,
|
||||||
|
menuWidth: 272,
|
||||||
|
inverted: false,
|
||||||
|
nativeScrollbar: false,
|
||||||
},
|
},
|
||||||
|
// 色弱模式
|
||||||
|
colorWeakness: false,
|
||||||
|
// 动态标题
|
||||||
|
dynamicDocumentTitle: true,
|
||||||
})
|
})
|
||||||
|
|
||||||
// 修改当前语言
|
// 修改当前语言
|
||||||
@ -125,7 +135,6 @@ export const piniaSettingStore = defineStore(
|
|||||||
*
|
*
|
||||||
* @description
|
* @description
|
||||||
* 更新 settingState 的值,如果 key 不存在与 settingState 中,则不会更新。
|
* 更新 settingState 的值,如果 key 不存在与 settingState 中,则不会更新。
|
||||||
* 但是不论是否更新成功,都会执行回调函数。
|
|
||||||
*
|
*
|
||||||
* @example
|
* @example
|
||||||
* updateSettingState('drawerPlacement', 'left')
|
* updateSettingState('drawerPlacement', 'left')
|
||||||
@ -143,39 +152,49 @@ export const piniaSettingStore = defineStore(
|
|||||||
updateObjectValue(settingState, key, value, cb)
|
updateObjectValue(settingState, key, value, cb)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const toggleColorWeakness = (bool: boolean) => {
|
||||||
|
const html = document.documentElement
|
||||||
|
|
||||||
|
updateSettingState('colorWeakness', bool)
|
||||||
|
setStyle(html, {
|
||||||
|
filter: bool ? 'invert(100%)' : '',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* 初始化合并自定义主题色
|
* @description
|
||||||
* 该方法会在初始化时执行一次,之后会在切换主题色时执行
|
* 初始化合并自定义主题色。
|
||||||
|
* 该方法会在初始化时执行一次,之后会在切换主题色时执行。
|
||||||
*/
|
*/
|
||||||
watch(
|
watchEffect(() => {
|
||||||
() => settingState.appTheme,
|
settingState.appTheme
|
||||||
(ndata) => {
|
? (settingState.primaryColorOverride = Object.assign(
|
||||||
ndata
|
{},
|
||||||
? (settingState.primaryColorOverride = Object.assign(
|
settingState.primaryColorOverride,
|
||||||
{},
|
APP_THEME.appNaiveUIThemeOverrides.dark,
|
||||||
settingState.primaryColorOverride,
|
APP_THEME.appNaiveUIThemeOverridesCommon.dark,
|
||||||
APP_THEME.appNaiveUIThemeOverrides.dark,
|
))
|
||||||
APP_THEME.appNaiveUIThemeOverridesCommon.dark,
|
: (settingState.primaryColorOverride = Object.assign(
|
||||||
))
|
{},
|
||||||
: (settingState.primaryColorOverride = Object.assign(
|
settingState.primaryColorOverride,
|
||||||
{},
|
APP_THEME.appNaiveUIThemeOverrides.light,
|
||||||
settingState.primaryColorOverride,
|
APP_THEME.appNaiveUIThemeOverridesCommon.light,
|
||||||
APP_THEME.appNaiveUIThemeOverrides.light,
|
))
|
||||||
APP_THEME.appNaiveUIThemeOverridesCommon.light,
|
|
||||||
))
|
toggleColorWeakness(settingState.colorWeakness)
|
||||||
},
|
|
||||||
{
|
if (!settingState.dynamicDocumentTitle) {
|
||||||
immediate: true,
|
document.title = settingState.sideBarLogo?.title || 'Ray Template'
|
||||||
once: true,
|
}
|
||||||
},
|
})
|
||||||
)
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...toRefs(settingState),
|
...toRefs(settingState),
|
||||||
updateLocale,
|
updateLocale,
|
||||||
changePrimaryColor,
|
changePrimaryColor,
|
||||||
updateSettingState,
|
updateSettingState,
|
||||||
|
toggleColorWeakness,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -14,7 +14,10 @@ export interface WatermarkConfig {
|
|||||||
height: number
|
height: number
|
||||||
xOffset: number
|
xOffset: number
|
||||||
yOffset: number
|
yOffset: number
|
||||||
|
xGap: number
|
||||||
|
yGap: number
|
||||||
rotate: number
|
rotate: number
|
||||||
|
cross: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface AppRootRoute {
|
export interface AppRootRoute {
|
||||||
@ -70,4 +73,12 @@ export interface SettingState {
|
|||||||
* accordion 手风琴模式
|
* accordion 手风琴模式
|
||||||
*/
|
*/
|
||||||
menuConfig: AppMenuConfig
|
menuConfig: AppMenuConfig
|
||||||
|
colorWeakness: boolean
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @description
|
||||||
|
* 动态浏览器标题。
|
||||||
|
* 如果设置为 true,会在更新菜单时,自动取用当前菜单的标题作为浏览器标题。
|
||||||
|
*/
|
||||||
|
dynamicDocumentTitle: boolean
|
||||||
}
|
}
|
||||||
|
@ -10,11 +10,14 @@ export interface AppMenuConfig {
|
|||||||
accordion: boolean
|
accordion: boolean
|
||||||
menuSiderBarLogo: boolean
|
menuSiderBarLogo: boolean
|
||||||
iconSize: number
|
iconSize: number
|
||||||
|
menuWidth: number
|
||||||
|
inverted: boolean
|
||||||
|
nativeScrollbar: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface AppKeepAlive {
|
export interface AppKeepAlive {
|
||||||
setupKeepAlive: boolean
|
setupKeepAlive: boolean
|
||||||
keepAliveExclude?: string[]
|
keepAliveExclude: string[]
|
||||||
maxKeepAliveLength: number
|
maxKeepAliveLength: number
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,7 +2,8 @@
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* 从目标类型中挑选出符合条件的属性名
|
* @description
|
||||||
|
* 从目标类型中挑选出符合条件的属性名。
|
||||||
*
|
*
|
||||||
* @example
|
* @example
|
||||||
* ConditionalKeys<{ a: string, b: number }, string> // 'a'
|
* ConditionalKeys<{ a: string, b: number }, string> // 'a'
|
||||||
@ -15,7 +16,8 @@ export type ConditionalKeys<Base, Condition> = NonNullable<
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* 从目标类型中排除符合条件的属性
|
* @description
|
||||||
|
* 从目标类型中排除符合条件的属性。
|
||||||
*
|
*
|
||||||
* @example
|
* @example
|
||||||
* ConditionalExclude<{ a: string, b: number }, string> // { b: number }
|
* ConditionalExclude<{ a: string, b: number }, string> // { b: number }
|
||||||
@ -27,7 +29,8 @@ export type ConditionalExclude<Base, Condition> = Omit<
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* 从目标类型中挑选出符合条件的属性
|
* @description
|
||||||
|
* 从目标类型中挑选出符合条件的属性。
|
||||||
*
|
*
|
||||||
* @example
|
* @example
|
||||||
* ConditionalPick<{ a: string, b: number }, string> // { a: string }
|
* ConditionalPick<{ a: string, b: number }, string> // { a: string }
|
||||||
@ -39,7 +42,8 @@ export type ConditionalPick<Base, Condition> = Pick<
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* 声明一个任意类型的对象
|
* @description
|
||||||
|
* 声明一个任意类型的对象。
|
||||||
*
|
*
|
||||||
* @example
|
* @example
|
||||||
* const A: Recordable = { a: 1, b: [] }
|
* const A: Recordable = { a: 1, b: [] }
|
||||||
@ -48,7 +52,8 @@ export type Recordable<T = any> = Record<string, T>
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* 获取目标类型的所有属性类型
|
* @description
|
||||||
|
* 获取目标类型的所有属性类型。
|
||||||
*
|
*
|
||||||
* @example
|
* @example
|
||||||
* ValueOf<{ a: string, b: number }> // string | number
|
* ValueOf<{ a: string, b: number }> // string | number
|
||||||
@ -57,7 +62,8 @@ export type ValueOf<T extends object> = T[keyof T]
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* 将目标所有属性变为可修改
|
* @description
|
||||||
|
* 将目标所有属性变为可修改。
|
||||||
*
|
*
|
||||||
* @example
|
* @example
|
||||||
* Mutable<{ readonly a: string }> // { a: string }
|
* Mutable<{ readonly a: string }> // { a: string }
|
||||||
@ -68,7 +74,8 @@ export type Mutable<T> = {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* 递归将目标所有属性变为可修改
|
* @description
|
||||||
|
* 递归将目标所有属性变为可修改。
|
||||||
*
|
*
|
||||||
* @example
|
* @example
|
||||||
* DeepMutable<{ readonly a: { readonly b: { readonly c: string } } }> // { a: { b: { c: string } } }
|
* DeepMutable<{ readonly a: { readonly b: { readonly c: string } } }> // { a: { b: { c: string } } }
|
||||||
@ -83,7 +90,8 @@ export type DeepMutable<T> = {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* 获取 Promise 返回值类型
|
* @description
|
||||||
|
* 获取 Promise 返回值类型。
|
||||||
*
|
*
|
||||||
* @example
|
* @example
|
||||||
* ReturnPromiseType<Promise<string>> // string
|
* ReturnPromiseType<Promise<string>> // string
|
||||||
@ -91,3 +99,17 @@ export type DeepMutable<T> = {
|
|||||||
*/
|
*/
|
||||||
export type ReturnPromiseType<T extends Promise<any>> =
|
export type ReturnPromiseType<T extends Promise<any>> =
|
||||||
T extends Promise<infer U> ? U : never
|
T extends Promise<infer U> ? U : never
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @description
|
||||||
|
* 深度只读。
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* DeepReadonly<{ a: { b: string } }> // { readonly a: { readonly b: string } }
|
||||||
|
*/
|
||||||
|
export type DeepReadonly<T> = T extends object
|
||||||
|
? {
|
||||||
|
readonly [P in keyof T]: DeepReadonly<T[P]>
|
||||||
|
}
|
||||||
|
: T
|
||||||
|
Loading…
x
Reference in New Issue
Block a user